steelbreeze / state.js

DEPRECATED, please see @steelbreeze/state
https://github.com/steelbreeze/state
MIT License
324 stars 39 forks source link

Incorrect exit() executed when leaving composite state from choice pseudostate #27

Closed joeloyj closed 7 years ago

joeloyj commented 7 years ago

Example:

var state = require('state.js');

var model = new state.StateMachine('model');
var initial = new state.PseudoState('initial', model, state.PseudoStateKind.Initial);
var a = new state.State('a', model);
var b = new state.State('b', model);
var aa = new state.State('aa', a);
var aChoice = new state.PseudoState('aChoice', a, state.PseudoStateKind.Choice);

initial.to(aa);
aa.to(aChoice);
aChoice.to(b).when(function() { return true });

var instance = new state.StateMachineInstance('instance');
state.setConsole(console);
state.initialise(model, instance);

Running the above code produces:

initialise model
initialise instance
instance enter model
instance enter model.default
instance enter model.default.initial
instance leave model.default.initial
instance enter model.default.a
instance enter model.default.a.default
instance enter model.default.a.default.aa
instance leave model.default.a.default.aa
instance enter model.default.a.default.aChoice
instance leave model.default.a.default.aa
instance leave model.default.a.default
instance leave model.default.a
instance enter model.default.b

Note that instance leave model.default.a.default.aa is executed twice. The second occurrence should be instance leave model.default.a.default.aChoice.

mesmo commented 7 years ago

Thanks Joel,

Investigating...

mesmo commented 7 years ago

Hi Joel, you've uncovered a bug that will cause what you're seeing whenever you leave a composite state via a transition whose source is a pseudo state. The code uses the last known state in the active state configuration (which is always a state as its used for history purposes as well) as the basis for what child states to leave.

In your example, when bootstrapping the transition from aChoice to b it determines that it needs to exit a and then cascades the leave operation using the last know state.

I will investigate potential fixes, but this may take a little time - in the mean time, if you can restructure (or don't have any exit behaviour on aa), then you'll be fine.

mesmo commented 7 years ago

I have an approach to fixing the issues and am fairly well progressed on the development, but a little more work and testing required; should be in a stable state in a few days.

mesmo commented 7 years ago

Unfortunately, the approach I was looking at will not work; I have another angle of attach. This requires that I extend and expand the active state configuration to contain both the last known state and the current active vertex.

mesmo commented 7 years ago

Fixed by release v5.11.0