Skip to content

Commit

Permalink
Merge pull request #544 from hooligan495/bugfix/543_prevent_reentry
Browse files Browse the repository at this point in the history
In the case of a superstate having a trigger that moves the state to …
  • Loading branch information
mclift authored Nov 8, 2023
2 parents e88e6eb + f9b291b commit 99e49a8
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/Stateless/StateMachine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,10 @@ void InternalFireOne(TTrigger trigger, params object[] args)
case DynamicTriggerBehaviour _ when result.Handler.ResultsInTransitionFrom(source, args, out var destination):
case TransitioningTriggerBehaviour _ when result.Handler.ResultsInTransitionFrom(source, args, out destination):
{
//If a trigger was found on a superstate that would cause unintended reentry, don't trigger.
if (source.Equals(destination))
break;

// Handle transition, and set new state
var transition = new Transition(source, destination, trigger, args);
HandleTransitioningTrigger(args, representativeState, transition);
Expand Down
23 changes: 23 additions & 0 deletions test/Stateless.Tests/StateMachineFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,29 @@ public void WhenInSubstate_TriggerIgnoredInSuperstate_RemainsInSubstate()
Assert.Equal(State.B, sm.State);
}

[Fact]
public void WhenInSubstate_TriggerSuperStateTwiceToSameSubstate_DoesNotReenterSubstate()
{
var sm = new StateMachine<State, Trigger>(State.A);
var eCount = 0;

sm.Configure(State.B)
.OnEntry(() => { eCount++;})
.SubstateOf(State.C);

sm.Configure(State.A)
.SubstateOf(State.C);


sm.Configure(State.C)
.Permit(Trigger.X, State.B);

sm.Fire(Trigger.X);
sm.Fire(Trigger.X);

Assert.Equal(1, eCount);
}

[Fact]
public void PermittedTriggersIncludeSuperstatePermittedTriggers()
{
Expand Down

0 comments on commit 99e49a8

Please sign in to comment.