statemachine icon indicating copy to clipboard operation
statemachine copied to clipboard

Call superstate executes for the same event as the child is in

Open muisje opened this issue 4 years ago • 5 comments

Currently the super states won't react to an event fired. Is there any elegant way to have all the super states of the current states be called on the same event if it is defined like that?

so for instance i have this function that is defined for every state. I want it to be called for every superstate including the current state: builder.In(state).On(Events.Do).Execute(state.Do); but it only executes for the current state and not the super states when firing the event Do,

muisje avatar Apr 22 '20 17:04 muisje

A transition on a superstate is only called when there is no transition lower in the hierarchy that matches the event and its guard returns true.

I suggest that you add the action to be executed in the transition actions lower in the hierarchy.

ursenzler avatar Apr 28 '20 15:04 ursenzler

Yeah, but how do you know what the super states are?

I've looked it doing it with extensions at the firing event but I'm unable to see what the super state is. Maybe i don't get it, but i like to access https://github.com/appccelerate/statemachine/blob/master/source/Appccelerate.StateMachine/Machine/States/IStateDefinition.cs because there i can see what the super state is. And the events and actions. Like that i could just do recursively for each super state call the action which has the same event.

I cannot do it in a pretty way either at definition since i can't access the hierarchy when building the state machine.

The least favorable way to do this is having an hierarchy defined as a copy, but I don't think that that is a great solution.

Do you've any other suggestions or am i understanding somethings not correctly?

muisje avatar May 19 '20 12:05 muisje

I see only the way to do this, but as I understood you, that is what you want to prevent:

(pseudo code) DefineHierarchyOn(Superstate).WithInitialSubState(A).AndChildren(B);

In(SuperState).On(E).Execute(Action); In(A).On(E).Execute(Action, AnotherAction) In(B).On(E).Execute(Action, YetAnotherAction)

or call Action from inside AnotherAction and YetAnotherAction.

I thought about adding a possibility to specify whether a transition should be passed from superstates to its children, but I don't really like that idea. I think that calling the action explicitly, makes the state machine easier to understand.

ursenzler avatar May 28 '20 06:05 ursenzler

So what I thought would work before you told me that the deepest event would get fired on duplicate event:

In(SuperState).On(E).Execute(Action); In(A).On(E).Execute(Action, AnotherAction); In(B).On(E).Execute(Action, YetAnotherAction);

I think that is pretty explicit. And you could maybe in the define hierarchy choose then what behaviour you want on duplicate event. So by default it would only call the lowest in hierarchy (to preserve backwards compatibility) and if you do define it would call all actions in the hierarchy on the event.

And the second option sounds less favorable to me when using it, because you do have to know which other actions you need to call in the sub state actions.

muisje avatar May 28 '20 10:05 muisje

As I understand your idea, it wouldn't work. I understand that you assume that transitions in super states for the same event would have the same target state. However, that is not true. A child state could point to Foo, a superstate to Bar. Please correct me if I didn't understand your idea.

ursenzler avatar Jun 05 '20 14:06 ursenzler