Skip to content

Commit 149d272

Browse files
committed
Resets local timers when entering a state.
1 parent 88ad97c commit 149d272

File tree

4 files changed

+66
-5
lines changed

4 files changed

+66
-5
lines changed

MonoGameStateMachine/Fsm.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,29 @@ public Fsm(State<TS, TT, GameTime> current, bool stackEnabled = false) : base(cu
6161
return new FluentImplementation<TS, TT>(startState);
6262
}
6363

64+
private void ResetCurrentAfterEntries()
65+
{
66+
foreach (var k in Current.Model.Transitions.Keys)
67+
{
68+
List<Timer<TS>> currentAfterEntries;
69+
if (AfterEntries.TryGetValue(new Tuple<TS, TS>(Current.Identifier, k), out currentAfterEntries))
70+
{
71+
for (int i = 0; i < currentAfterEntries.Count; i++)
72+
{
73+
Timer<TS> e = currentAfterEntries[i];
74+
e.Reset();
75+
currentAfterEntries[i] = e;
76+
}
77+
}
78+
}
79+
}
80+
81+
protected override void Entered(StateChangeArgs<TS, TT, GameTime> args)
82+
{
83+
ResetCurrentAfterEntries();
84+
base.Entered(args);
85+
}
86+
6487
public new void Update(GameTime gameTime)
6588
{
6689
// After-entries on transitions.
@@ -84,7 +107,7 @@ public Fsm(State<TS, TT, GameTime> current, bool stackEnabled = false) : base(cu
84107

85108
Model.Current.RaiseUpdated(new UpdateArgs<TS, TT, GameTime>(this, Current, gameTime));
86109
}
87-
110+
88111
private bool CheckAfterEntries(List<Timer<TS>> afterEntries,
89112
Dictionary<TS, Transition<TS, TT, GameTime>> transitions, GameTime g)
90113
{

MonoGameStateMachine/NUnitTests/FluentTests.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,5 +181,28 @@ public void WhenMultipleAfterConditionsFireOnASingleUpdateOnEnterAndOnExitShoudF
181181
Assert.That(enterCount, Is.EqualTo(4));
182182
Assert.That(exitCount, Is.EqualTo(4));
183183
}
184+
185+
[Test]
186+
[Category("MonoGameStateMachine.FluentTests")]
187+
public void WhenAnAfterConditionDoesNotFiresAndATransitionHappensTheTimerIsResetOnReentry()
188+
{
189+
var m = Fsm<State, Trigger>.Builder(State.IDLE)
190+
.State(State.IDLE)
191+
.TransitionTo(State.OVER).After(10, TimeUnit.MILLISECONDS)
192+
.TransitionTo(State.OVER).On(Trigger.MOUSE_CLICKED)
193+
.State(State.OVER)
194+
.TransitionTo(State.IDLE).On(Trigger.MOUSE_CLICKED)
195+
.Build();
196+
197+
Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
198+
m.Update(new GameTime(TimeSpan.FromDays(1), TimeSpan.FromMilliseconds(5)));
199+
Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
200+
m.Trigger(Trigger.MOUSE_CLICKED);
201+
Assert.That(m.Current.Identifier, Is.EqualTo(State.OVER));
202+
m.Trigger(Trigger.MOUSE_CLICKED);
203+
Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
204+
m.Update(new GameTime(TimeSpan.FromDays(1), TimeSpan.FromMilliseconds(5)));
205+
Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
206+
}
184207
}
185208
}

MonoGameStateMachine/Timer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public Timer(TS target, double value, TimeUnit unit)
4646
Reset();
4747
}
4848

49-
private void Reset()
49+
public void Reset()
5050
{
5151
Time = Value * (long) Unit;
5252
}

StateMachine/Fsm.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,27 @@ protected void DoTransition(TS state, TT input, bool isPop)
153153
{
154154
StateChangeArgs<TS, TT, TD> args =
155155
new StateChangeArgs<TS, TT, TD>(this, old, Model.Current, input);
156-
old.RaiseExited(args);
157-
Model.Current.RaiseEntered(args);
158-
Model.RaiseStateChanged(args);
156+
Exited(old, args);
157+
Entered(args);
158+
StateChanged(args);
159159
}
160160
}
161161

162+
protected virtual void Entered(StateChangeArgs<TS, TT, TD> args)
163+
{
164+
Model.Current.RaiseEntered(args);
165+
}
166+
167+
protected virtual void Exited(State<TS, TT, TD> old, StateChangeArgs<TS, TT, TD> args)
168+
{
169+
old.RaiseExited(args);
170+
}
171+
172+
protected virtual void StateChanged(StateChangeArgs<TS, TT, TD> args)
173+
{
174+
Model.RaiseStateChanged(args);
175+
}
176+
162177
public void Trigger(TT input)
163178
{
164179
if (input == null) return;

0 commit comments

Comments
 (0)