Skip to content
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

Question: treat two events the same way #30

Open
Haukinger opened this issue Jan 8, 2018 · 5 comments
Open

Question: treat two events the same way #30

Haukinger opened this issue Jan 8, 2018 · 5 comments

Comments

@Haukinger
Copy link

Is it possible to react to two different events in the same way?

Example:

_stateMachine.In(States.A)
     .On(Events.B).Or(Events.C)
     .If(Something).Goto(States.C).Execute(ComplicatedStuff)
     .If(SomethingElse).Goto(States.D).Execute(MoreStuff)
     .Otherwise().Goto(States.E).Execute(Cleanup);

I want to not copy the whole if-otherwise-lines for the second event

@ursenzler
Copy link
Member

No, this is not possible in such an easy way.

If you don't want to duplicate the code, I suggest putting the part from .If into another method/nested method/lambda and pass the result of the .On(...) call to it (once for B, once for C).

However, I struggle to find a scenario in which I would react the same to two different events. Can you merge these two events into a single event? Maybe you have to split externally visible events from internally used events?

I do not want to add this syntax unless we have a good scenario for it. I hope you understand, sorry.

@Haukinger
Copy link
Author

I'm implementing a communication protocol, and in one state of the client, two control bytes should generate the same reaction when received.
Extracting a method will work, I suppose.

@ursenzler
Copy link
Member

I see no easy way to accomplish that with the way the fluent syntax is currently built, sorry.

@djack42
Copy link

djack42 commented Jan 10, 2018

It could be done easily by an extension at Firing time with ExtensionBase.FiringEvent(IStateMachineInformation<TState, TEvent> stateMachine, ref TEvent eventId, ref object eventArgument) because eventId is ref ! That way you could redirect with some logic the event C to B depending on the State.

And at queue time with a few changes :
EventQueued and EventQueuedWithPriority could be called with TEvent eventId as a ref parameter, allowing the implementation to modify the eventId (like some other calls).

In the Passive Implementation, by swapping the following lines in Fire(TEvent eventId, object eventArgument), that would do it I suppose (same for FirePriority ) :

this.events.AddLast(new EventInformation<TEvent>(eventId, eventArgument));
this.stateMachine.ForEach(extension => extension.EventQueued(this.stateMachine, eventId, eventArgument));

@ursenzler
Copy link
Member

That would work, but the understandability of the code would suffer a lot because the knowledge that C is handled as B is hidden and not visible in the definition.
I'm currently working on splitting the different aspects of the state machine (definition, execution, state). Once that is done, introducing an Or in the syntax should be much easier than with the current implementation. But that will take time.....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants