Imagine a part of your state machine looks like this:
How do you properly implement the choice part in Qt? I know there are guarded transitions, but that would mean that I need to:
Create a subclass of a QAbstractTransition which accepts e.g. an std::function<bool()> and a flag which determines if the transition happens when that boolean result is true, or when it is false
Create two instances of this class with the same boolean function, but opposite transition guards
Add two transitions from S1 using these two instances.
That approach seems kind of clumsy and error prone for something as simple as a choice.
Is there a more maintainable approach to implement this?
License Notice:
Alternatively to the default StackOverflow license you are hereby allowed to use this code through the MIT License.
I've created a BooleanChoiceTransition class with a constructor like this (might contain errors, the code is not on this machine, so I typed it by heart):
BooleanChoiceTransition::BooleanChoiceTransition(std::function<bool()> choiceFunc, QState* targetForTrueCase, QState* targetForFalseCase)
: QState{}
{
this->addTransition(this, &BooleanChoiceTransition::transitionToTrueTarget, targetForTrueCase);
this->addTransition(this, &BooleanChoiceTransition::transitionToFalseTarget, targetForFalseCase);
(void)QObject::connect(this, &QAbstractState::entered, [this]() {
if(choiceFunc())
{
emit transitionToTrueTarget();
}
else
{
emit transitionToFalseTarget();
}
});
}
with transitionToTrueTarget and transitionToFalseTarget being signals of course.
For the case of the example in the question, the class can be used like so:
auto choiceState = new BooleanChoiceTransition([this](){ return _someConditionFullfilled; }, s2, s3);
s1->addTransition(this, &MyClass::someTrigger, choiceState);
Since BooleanChoiceTransition is a QState, this can even be nested easily:
auto outerChoiceState = new BooleanChoiceTransition([this](){ return _someOtherConditionFullfilled; }, s4, choiceState);
Related
I maintain a data flow library that allows programmers to define new properties during instantiation, then does neat things at run-time with both property reads and writes, all transparently thanks to JS defineProperty. Sample usage, where TagSession is defined with the ES6 class keyword:
const sithApp = new TagSession( null, 'SithTrakSession',
{
obiTrakker: cF( c => new WebSocket('ws://localhost:4000')
.onmessage = msg => c.md.obiLoc = JSON.parse(msg.data)),
obiLoc: cI( null),
sithIds: cI([-1,-2,3616,-3,-4])
});
I can now write code where the map keywords are transparent accessors:
function SithTrak () {
return div({class: "app-container"},
h1({
class: "css-planet-monitor",
content: cF(c => "Obi-Wan currently on " +
(sithApp.obiLoc ?
sithApp.obiLoc.name : "...dunno"))
}))
}
This works great uncompiled and with Google Closure SIMPLE_OPTIMIZATION, but ADVANCED_COMPILATION warns (and the output fails) about, eg:
WARNING - Property obiLoc never defined on TagSession
withObi: cF( c=> c.md.info && sithApp.obiLoc
I have looked at all the annotations that might apply, but nothing seems suited to such a dynamic capability.
Am I missing something obvious, or is this combo of dynamism and optimization asking too much?
Dynamic properties added with this method would require using a bracket access for ADVANCED mode: sithApp['obiLoc']. In ADVANCED mode, the compiler must know about all properties accessed via the dot nation at compile time.
Since it isn't known that these properties are defined on the class you are going to get type warnings, bit it shouldn't break your code.
You can add declarations to silence the type warnings:
/** #type {?} */
TagSession.prototype.objLoc;
In other cases, you might be able to use #lends but I don't think this will work here as the types provided might not match the expected type of the property value. But there isn't enough context to be sure:
/** #lends {TagSession.prototype} */ ({
obiTrakker: ...,
obiLoc: ...,
sithIds: ...
})
I want some kind of mechanism to have more information about a caught exception. (Specifically exceptions I throw myself to abort transactions) I've looked around and pretty much the only thing I could find was "Use the info log". This to me does not seem like a good idea. For one it is cumbersome to access and find the last message. And it is limited in size so at some point the new messages won't even show up.
So my idea is the following: Create a class NuException and pass an instance of that through all methods store an instance in the class where the work methods are located. When I need to throw an exception I call a method on it similar to Global::error() but this one takes an identifier and a message.
Once I reach my catch block I can access those from my object the class that contains the work methods similarly to how CLRExceptions work.
class NuException
{
"public" str identifier;
"public" str message;
public Exception error(str _id, str _msg)
{
//set fields
return Exception::Error;
}
}
class Worker
{
"public" NuException exception;
void foo()
{
throw this.exception.error("Foo", "Record Foo already exists");
}
void bar()
{
this.foo();
}
}
void Job()
{
Worker w = new Worker();
try
{
w.bar(ex);
}
catch (Exception::Error)
{
info(w.exception().message());
}
}
It works but isn't there a better way? Surely someone must have come up with a solution to work around this shortcoming in AX?
Short answer: yes.
While your "brilliant" scheme "works", it gets boring pretty fast, as you now must transport your NuException object deep down 20 level from the listener (job) to the thrower (foo). Your bar method and other middle men has no interest or knowledge about your exception scheme but must pass it on anyway.
This is no longer the case after the update.
There are several ways to go.
Use an observer pattern like the Event broker or in AX 2012 and newer use delegates.
Stick to the infolog system and you use an InfoAction class to peggy bag your information to be used later. It can be used to display a stack trace or other interesting information.
Use a dedicated table for logging.
The third way may seem impractical, as any errors will undo the insert in the log. This is the default behavior but can be circumvented.
MyLogTable log;
Connection con = new UserConnection();
con.ttsBegin();
log.setConnection(con);
... // Set your fields
log.insert();
con.ttsCommit();
Your way to go depends on circumstances you do not mention.
I use a unit of work pattern a lot in my flex projects. I'll have a class that might call a web service, put the data in a sqlite db, refresh a model with the data then raise an event.
I usually call these inline and pass in some singleton classes:
protected function CareerSynced():void
{
var process:ProcessWorkouts = new ProcessWorkouts(_dataModel, _trainerModel, _databaseCache, _database.Conn);
process.addEventListener("AllWorkoutsProcessed", AllWorkoutsProcessed);
process.UpdateAllUnprocessed();
}
I'll then get the response like this:
private function AllWorkoutsProcessed(event:DataReceivedEvent):void
{
//do something here
}
My question is, am I adding that event listener correctly? I think I might be causing a memory leak, but I'm not sure. I've also thought about using a weak reference. I'm confused about when to use them. Would this be one of those cases?
Should it be like this?
process.addEventListener("AllWorkoutsProcessed", AllWorkoutsProcessed,false, 0, true);
I would either go with the weak reference or just remove the listener:
private function AllWorkoutsProcessed(event:DataReceivedEvent):void
{
event.target.removeEventListener("AllWorksoutsProcessed",AllWorkoutsProcessed);
}
I could list out my reasons but I'll just point you to this.
Let's say I have a class like so:
class Gerbil{
int id;
float x,y,z;
}
Let's further say this is part of a real-time simulation where I have a server/client setup and I change a property on the server-side:
//...
gerbil.x = 9.0;
//...
Now I want to send over this change to the client to synchronize the world state. However, the problem is I have potentially vast amounts of gerbils, and these gerbils also potentially have long lists of properties—not just x,y,z as depicted here.
My question is: Is there a way we can intercept these property assignments, transparently, and compile a diff from them?
From reading the D reference I got the impression opAssign might be the right thing, only there's actually no examples of how to use it? (D Ref. / opAssign) I suppose it would look something like this, but I'm just shooting from the hip:
void opAssign(string name)(float val){ //Just guessing here
if(name in floatProps){
if(isServer){
changedProps.push(this.id, name, val);
}
floatProps[name] = val;
}
}
And then opAssign would be called when we do:
gerbil.x = 9.0; //Same as gerbil.opAssign!("x")(9.0) ??
Apart from possibly wrong syntax, is this a step in the right direction? What is the right syntax? What about performance? It looks like it could be quite slow? Is there a faster, more "direct" way of this?
What I'd really like to avoid here are elaborate setups like:
gerbil.incProp(Prop.X, 9.0);
Thanks for your time.
Building on Jonathan's answer, I use code like this in a number of my libraries:
public template property(string name, T) {
mixin(`protected T _`~name~`;` ~
propertyGetter!(name, T) ~ propertySetter!(name, T));
}
public template property(string name, T, T def)
{
mixin(`protected T _`~name~` = `~def.stringof~`;` ~
propertyGetter!(name, T) ~ propertySetter!(name, T));
}
template propertyGetter(string name, T) {
enum propertyGetter = `public T `~name~`(){ return _`~name~`; }`;
}
template propertySetter(string name, T) {
enum propertySetter = `public typeof(this) `~name~`(T value){ _`~name~` = value;`~
`/* notify somebody that I've changed here */`~
`return this; }`;
}
The mixin strings are a bit ugly, but they preserve the proper line count.
I add properties to my classes like this:
class Gerbil {
mixin property!("id", int);
mixin property!("x", float);
mixin property!("y", float, 11.0); // give this one a default value
}
If you wanted, you could add some code to the propertySetter template that notified some sort of monitor that it had changed (passing id, property name, and new value). Then the monitor could transmit this info to a corresponding monitor on the server side who would find the object with proper id and set the specified property to the new value.
Overloading opAssign() is like overloading the assignment operator in C++. It's for assigning to the object itself, not one of its members. It's really not going to do what you want. I believe that the closest that you're going to get is properties:
class Gerbil
{
public:
#property int id()
{
return _id;
}
#property id(int newID)
{
//... Do whatever interception you want.
_id = newID;
}
#property float x()
{
return _x;
}
#property x(float newX)
{
//... Do whatever interception you want.
_x = newX;
}
#property float y()
{
return _y;
}
#property y(float newY)
{
//... Do whatever interception you want.
_y = newY;
}
#property float z()
{
return _z;
}
#property z(float newZ)
{
//... Do whatever interception zou want.
_z = newZ;
}
private:
int _id;
float _x, _y, _z;
}
#property enables property syntax so that you can use the function as if it were a variable. So,
//...
auto copyOfGerbilX = gerbil.x; //translates to gerbil.x()
gerbil.x = 9.0; //translates to gerbile.x(9.0)
//...
is now legal even though x is a function rather than a variable. You can insert whatever special handling code you want in the functions. And because the syntax used to access the variables is just as if they were public member variables, you can freely refactor your code to switch between having them be properties or public member variables in your class definition (assuming that you haven't tried to do something like take their address, since that doesn't mean the same thing for a variable as a function).
However, if what you're looking for is a generic way to not have to do all of those functions yourself, there is no direct construct for it. I believe that you could do it with compile-time reflection and string mixins or template mixins which would look at the list of your variables and then generate each of the property functions for you. However, then the extra handling code would have to be essentially the same for each function, and you'd have to be careful that the generated code was really what you wanted. I'm sure that it's feasible, but I'd have to work on the problem for a bit to produce a workable solution.
To generate such code, you'd need to look at __traits and std.traits for the compile-time reflection and at template mixins and string mixins for the code generation. I'd think twice about generating the code like that though rather than writing it by hand. It should be quite doable, but it won't necessarily be easy, debugging it could be entertaining, and if you're going to have to be fairly good with D templates and mixins to get it right.
But essentially, what you're looking for is to use #property functions so that you can add your handler code and then possibly use compile-time reflection along with mixins to generate the code for you, but generating code like that is a fairly advanced technique, so you may want to wait to try that until you're more experienced with D.
I'm using Python+PyAMF to talk back and forth with Flex clients, but I've run into a problem with the psudo-Enum-Singletons I'm using:
class Type {
public static const EMPTY:Type = new Type("empty");
public static const FULL:Type = new Type("full");
...
}
When I'm using locally created instances, everything is peachy:
if (someInstance.type == Type.EMPTY) { /* do things */ }
But, if 'someInstance' has come from the Python code, it's instance of 'type' obviously won't be either Type.EMPTY or Type.FULL.
So, what's the best way to make my code work?
Is there some way I can control AMF's deserialization, so when it loads a remote Type, the correct transformation will be called? Or should I just bite the bullet and compare Types using something other than ==? Or could I somehow trick the == type cohesion into doing what I want?
Edit: Alternately, does Flex's remoting suite provide any hooks which run after an instance has been deserialized, so I could perform a conversion then?
Random thought: Maybe you could create a member function on Type that will return the canonical version that matches it?
Something like:
class Type {
public static const EMPTY:Type = new Type("empty");
public static const FULL:Type = new Type("full");
...
// I'm assuming this is where that string passed
// in to the constructor goes, and that it's unique.
private var _typeName:String;
public function get canonical():Type {
switch(this._typeName) {
case "empty": return EMPTY;
case "full": return FULL;
/*...*/
}
}
}
As long as you know which values come from python you would just convert them initially:
var fromPython:Type = /*...*/
var t:Type = fromPython.canonical;
then use t after that.
If you can't tell when things come from python and when they're from AS3 then it would get pretty messy, but if you have an isolation layer between the AS and python code you could just make sure you do the conversion there.
It's not as clean as if you could control the deserialization, but as long as you've got a good isolation layer it should work.