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

How to let the on() callback be called for the startState? #25

Open
bbjay opened this issue Oct 15, 2018 · 3 comments
Open

How to let the on() callback be called for the startState? #25

bbjay opened this issue Oct 15, 2018 · 3 comments

Comments

@bbjay
Copy link
Contributor

bbjay commented Oct 15, 2018

On startup of my program, I need to be able to sync my state machine to an external/remote machine with the same states. Looking at the code, creating a new instance with the same startState seems to be the obvious way to do this.
The problem now is that I also need the on() callback be called for that startState, which of course is not possible at the construction time of the FSM as the transitions are defined only after instantiation.

The reset() method unfortunately does not call the callbacks. Calling .go(startState) is only possible with allowImplicitSelfTransition=true, which is not an option for my case.

Am I missing something, or is this not possible at the moment?

@bbjay
Copy link
Contributor Author

bbjay commented Oct 15, 2018

I've thought of the following ways to achieve this functionality, but they all have some drawbacks or are not possible at all:

  • maintaining my own mapping of on()-callbacks-functions and states outside the FSM, and then call the corresponding function for startState after initialization.
  • introducing a special initial-start-state for every state in my FSM, with only a transition to the desired state, so that .go(desiredStartState) would be possible.
  • subclassing the FSM and adding a method start(), which would look like
public start() {
   const originalAllowImplicitSelfTransition = this._allowImplicitSelfTransition;
   this._allowImplicitSelfTransition = true;
   this.go(this._startState);
   this._allowImplicitSelfTransition = originalAllowImplicitSelfTransition;
}

which would only work if both fields were protected, not private.

I think my favorite solution would be to have an extra parameter on reset(), like
public reset(execCallbacks = false).
I could try to make a PR for this, if it is a desirable solution.
What do you think?

@eonarheim
Copy link
Owner

Hi @bbjay please do make a PR

Just to be clear is the goal just to re-run the start state on() handlers on reset()? If so I think your proposed solution works. I agree we'll want it to be off by default to avoid a breaking change for other folks.

I might suggest a slightly different signature using an option bag just to give us room to grow any more flags in the future without having to grow a parameter list.

export interface ResetOptions {
   runCallbacks?: boolean;
};

export const DefaultResetOptions: ResetOptions = {
   runCallbacks: false
};
public reset(options?: ResetOptions) {
   // if option is set override defaults, otherwise defaults
   options = options ? { ...DefaultResetOptions, ...options } : { ...DefaultResetOptions };
} ;

@bbjay
Copy link
Contributor Author

bbjay commented Oct 19, 2018

Hi @eonarheim , yes exactly.
Ok, will try that out on Sunday.

eonarheim pushed a commit that referenced this issue Oct 22, 2018
This implements the features discussed in #25
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

2 participants