-
Notifications
You must be signed in to change notification settings - Fork 147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: Add arguments to transition method #78
Comments
@murillo128 Apologies for taking four days to respond! This is actually a question that's come up before, and is something I don't currently plan to add support for. However, I believe machina may already support what you need to do. First, here's my reasoning behind why I'd prefer to not add support for transition args: If a conditional action is necessary inside the // pretending, for a moment, that _onEnter supports arguments
states: {
online: {
_onEnter: function( transitionArgs ) {
this.someProviderApi.connect().then( function() {
this.someProviderApi.sendMessage( transitionArgs );
}.bind( this ) );
}
},
"offline-idle": {
sendMessage: function( msg ) {
this.transition( "online", msg );
}
}
// other states, etc.
} Note that what the I have yet to run into a use-case where the need for transition args didn't involve either the need to trigger an input handler in the new state or read some state from the FSM. If your scenario involves the need to trigger input, you can use the states: {
online: {
sendMessage: function( msg ) {
this.someProviderApi.sendMessage( msg );
}
},
"offline-idle": {
sendMessage: function( msg ) {
/* this is the same as calling
this.transition( "online" );
this.handle( "sendMessage", msg );
*/
this.deferAndTransition( "online" );
}
}
// other states, etc.
} (See the wiki for API documentation on the differences between The above approach maintains an explicit/intentional nature about the input your FSM handles. If your scenario doesn't involve the need to trigger input, but instead you need to store some data while in one state, and read it in another, then you can simply store it on the FSM instance itself if you're using a I hope this helps! If I've completely misunderstood the need, feel free to reply and better educate me as to what your use-case is. Thanks! |
thanxs for your answer. Very much appreciated. Yes, I was thinking in doing a transition && handle and move the functionality to the input handler, and also agree with you that passing an argument to the _onEnter is not an elegant FSM design. However, I still fill that I feel missing (or I have failed to find in the docs and source code) to be able to keep an internal attributes of the state. Currently if I have to store a counter or set an attibute for calling my API I need to set it at FSM level and it get's quite polluted after a while. In that sense, I would rename my feature request, instead of been able to pass an argument to the _onEnter, I think it would be able to have an "internal state" or attributes within each state, and be able to set the from the FSM while transitioning. For example, it would be something like:
So the id would be and state attribute I could access from all input handlers and _onEnter/_onExit without having to store it globally on the FSM. |
@murillo128 I definitely understand what you're asking - unfortunately it's not something that I would want to add to machina's core lib. Here's why: at the foundation, every machina FSM is a var plainFsm = new machina.Fsm({
initialize: function() {
this.history = [];
},
initialState: "on",
states: {
"on": {
_onEnter: function() {
this.history.push("turning on");
},
"turn.on": function() {
this.history.push("already on!");
},
"turn.off": "off"
},
"off": {
_onEnter: function() {
this.history.push("turning off");
},
"turn.on": "on",
"turn.off": function() {
this.history.push("already off!");
}
}
},
turnOn: function() {
this.handle("turn.on");
},
turnOff: function() {
this.handle("turn.off");
}
});
var behavioralFsm = new machina.BehavioralFsm({
initialState: "on",
states: {
"on": {
_onEnter: function(client) {
client.history.push("turning on");
},
"turn.on": function(client) {
client.history.push("already on!");
},
"turn.off": "off"
},
"off": {
_onEnter: function(client) {
client.history.push("turning off");
},
"turn.on": "on",
"turn.off": function(client) {
client.history.push("already off!");
}
}
},
turnOn: function(client) {
this.handle(client, "turn.on");
},
turnOff: function(client) {
this.handle(client, "turn.off");
}
});
var client = {
history: []
};
plainFsm.turnOn();
plainFsm.turnOff();
plainFsm.turnOff();
plainFsm.turnOn();
plainFsm.turnOn();
behavioralFsm.turnOn(client);
behavioralFsm.turnOff(client);
behavioralFsm.turnOff(client);
behavioralFsm.turnOn(client);
behavioralFsm.turnOn(client);
console.log(plainFsm.history);
console.log(client.history);
}); It sounds like using a behavioral FSM may work well for what you want to do. |
thanxs @ifandelse for the detailed answer. I appreciate your time and why you don't want to implement the change. Anyway, here are the changes I am working on, just in case you find it interesting (untested yet): |
Hi,
Could it be possible to add arguments to the transition method so they are passed to the state _onEnter method call?
Best regards
Sergio
The text was updated successfully, but these errors were encountered: