Skip to content

Commit 180d558

Browse files
committed
Fixes project. Done.
1 parent 2c187b1 commit 180d558

20 files changed

+162
-206
lines changed

MonoGameStateMachine/Api/BuilderFluent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,6 @@ public interface BuilderFluent<TS, TT, TD>
6161
/// <summary>
6262
/// Builds this instance of an FSM (or SBFSM).
6363
/// </summary>
64-
Fsm<TS, TT, TD> Build();
64+
Fsm<TS, TT> Build();
6565
}
6666
}

MonoGameStateMachine/Api/FluentImplementation.cs

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,131 +27,126 @@
2727

2828
using System;
2929
using System.Collections.Generic;
30+
using Microsoft.Xna.Framework;
3031
using StateMachine.Events;
3132

3233
namespace MonoGameStateMachine.Api
3334
{
34-
public class FluentImplementation<TS, TT, TD> : StateMachine.Fluent.Api.FluentImplementation<TS, TT, TD>,
35-
TransitionStateFluent<TS, TT, TD>, GlobalTransitionBuilderFluent<TS, TT, TD>
35+
public class FluentImplementation<TS, TT> : StateMachine.Fluent.Api.FluentImplementation<TS, TT, GameTime>,
36+
TransitionStateFluent<TS, TT, GameTime>, GlobalTransitionBuilderFluent<TS, TT, GameTime>
3637
{
37-
public Dictionary<Tuple<TS, TS>, List<Timer>> AfterEntries { get; set; } = new Dictionary<Tuple<TS, TS>, List<Timer>>();
38-
public Dictionary<Tuple<TS>, List<Timer>> GlobalAfterEntries { get; set; } = new Dictionary<Tuple<TS>, List<Timer>>();
38+
public Dictionary<Tuple<TS, TS>, List<Timer<TS>>> AfterEntries { get; set; } = new Dictionary<Tuple<TS, TS>, List<Timer<TS>>>();
39+
public List<Timer<TS>> GlobalAfterEntries { get; set; } = new List<Timer<TS>>();
3940

4041
public FluentImplementation(TS startState) : base(startState)
4142
{
4243
}
4344

44-
public new Fsm<TS, TT, TD> Build()
45+
public new Fsm<TS, TT> Build()
4546
{
4647
base.Build();
47-
var m = new Fsm<TS, TT, TD>(FsmModel);
48+
var m = new Fsm<TS, TT>(FsmModel);
4849
m.AfterEntries = AfterEntries;
4950
m.GlobalAfterEntries = GlobalAfterEntries;
5051
return m;
5152
}
5253

53-
public TransitionStateFluent<TS, TT, TD> After(float amount, TimeUnit timeUnit)
54+
public TransitionStateFluent<TS, TT, GameTime> After(float amount, TimeUnit timeUnit)
5455
{
55-
List<Timer> l;
56+
List<Timer<TS>> l;
5657
var key = currentTransition;
5758
if (!AfterEntries.TryGetValue(key, out l))
5859
{
59-
l = new List<Timer>();
60+
l = new List<Timer<TS>>();
6061
AfterEntries.Add(key, l);
6162
}
62-
l.Add(new Timer(amount, timeUnit));
63+
l.Add(new Timer<TS>(key.Item2, amount, timeUnit));
6364
return this;
6465
}
6566

66-
public TransitionStateFluent<TS, TT, TD> AfterGlobal(float amount, TimeUnit timeUnit)
67+
public TransitionStateFluent<TS, TT, GameTime> AfterGlobal(float amount, TimeUnit timeUnit)
6768
{
68-
List<Timer> l;
6969
var key = currentGlobalTransition;
70-
if (!GlobalAfterEntries.TryGetValue(key, out l))
71-
{
72-
l = new List<Timer>();
73-
GlobalAfterEntries.Add(key, l);
74-
}
75-
l.Add(new Timer(amount, timeUnit));
70+
GlobalAfterEntries.Add(new Timer<TS>(key.Item1, amount, timeUnit));
7671
return this;
7772
}
7873

79-
public new StateFluent<TS, TT, TD> State(TS state)
74+
public new StateFluent<TS, TT, GameTime> State(TS state)
8075
{
8176
base.State(state);
8277
return this;
8378
}
8479

85-
public new TransitionFluent<TS, TT, TD> TransitionTo(TS state)
80+
public new TransitionFluent<TS, TT, GameTime> TransitionTo(TS state)
8681
{
8782
base.TransitionTo(state);
8883
return this;
8984
}
9085

91-
public new TransitionFluent<TS, TT, TD> PopTransition()
86+
public new TransitionFluent<TS, TT, GameTime> PopTransition()
9287
{
9388
base.PopTransition();
9489
return this;
9590
}
9691

97-
public new TransitionStateFluent<TS, TT, TD> On(TT trigger)
92+
public new TransitionStateFluent<TS, TT, GameTime> On(TT trigger)
9893
{
9994
base.On(trigger);
10095
return this;
10196
}
10297

103-
public new TransitionStateFluent<TS, TT, TD> If(Func<IfArgs<TS, TT>, bool> condition)
98+
public new TransitionStateFluent<TS, TT, GameTime> If(Func<IfArgs<TS>, bool> condition)
10499
{
105100
base.If(condition);
106101
return this;
107102
}
108103

109-
public new StateFluent<TS, TT, TD> OnEnter(
110-
Action<StateChangeArgs<TS, TT, TD>> stateChangeArgs)
104+
public new StateFluent<TS, TT, GameTime> OnEnter(
105+
Action<StateChangeArgs<TS, TT, GameTime>> stateChangeArgs)
111106
{
112107
base.OnEnter(stateChangeArgs);
113108
return this;
114109
}
115110

116-
public new StateFluent<TS, TT, TD> OnExit(
117-
Action<StateChangeArgs<TS, TT, TD>> stateChangeArgs)
111+
public new StateFluent<TS, TT, GameTime> OnExit(
112+
Action<StateChangeArgs<TS, TT, GameTime>> stateChangeArgs)
118113
{
119114
base.OnExit(stateChangeArgs);
120115
return this;
121116
}
122117

123-
public new StateFluent<TS, TT, TD> Update(Action<UpdateArgs<TS, TT, TD>> updateArgs)
118+
public new StateFluent<TS, TT, GameTime> Update(Action<UpdateArgs<TS, TT, GameTime>> updateArgs)
124119
{
125120
base.Update(updateArgs);
126121
return this;
127122
}
128123

129-
public new StateFluent<TS, TT, TD> ClearsStack()
124+
public new StateFluent<TS, TT, GameTime> ClearsStack()
130125
{
131126
base.ClearsStack();
132127
return this;
133128
}
134129

135-
public new BuilderFluent<TS, TT, TD> EnableStack()
130+
public new BuilderFluent<TS, TT, GameTime> EnableStack()
136131
{
137132
base.EnableStack();
138133
return this;
139134
}
140135

141-
public new GlobalTransitionFluent<TS, TT, TD> GlobalTransitionTo(TS state)
136+
public new GlobalTransitionFluent<TS, TT, GameTime> GlobalTransitionTo(TS state)
142137
{
143138
base.GlobalTransitionTo(state);
144139
return this;
145140
}
146141

147-
public new GlobalTransitionBuilderFluent<TS, TT, TD> OnGlobal(TT trigger)
142+
public new GlobalTransitionBuilderFluent<TS, TT, GameTime> OnGlobal(TT trigger)
148143
{
149144
base.OnGlobal(trigger);
150145
return this;
151146
}
152147

153-
public new GlobalTransitionBuilderFluent<TS, TT, TD> IfGlobal(
154-
Func<IfArgs<TS, TT>, bool> condition)
148+
public new GlobalTransitionBuilderFluent<TS, TT, GameTime> IfGlobal(
149+
Func<IfArgs<TS>, bool> condition)
155150
{
156151
base.IfGlobal(condition);
157152
return this;

MonoGameStateMachine/Api/GlobalTransitionFluent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public interface GlobalTransitionFluent<TS, TT, TD>
4646
/// currently describing.
4747
/// </summary>
4848
/// <param name="condition">The condition.</param>
49-
GlobalTransitionBuilderFluent<TS, TT, TD> IfGlobal(Func<IfArgs<TS, TT>, bool> condition);
49+
GlobalTransitionBuilderFluent<TS, TT, TD> IfGlobal(Func<IfArgs<TS>, bool> condition);
5050

5151
/// <summary>
5252
/// Automatically walks the transition you're currently describing, if the specified amount of time has passed.

MonoGameStateMachine/Api/TransitionFluent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@ public interface TransitionFluent<TS, TT, TD>
5353
/// describing.
5454
/// </summary>
5555
/// <param name="condition">The condition.</param>
56-
TransitionStateFluent<TS, TT, TD> If(Func<IfArgs<TS, TT>, bool> condition);
56+
TransitionStateFluent<TS, TT, TD> If(Func<IfArgs<TS>, bool> condition);
5757
}
5858
}

MonoGameStateMachine/Fsm.cs

Lines changed: 49 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ namespace MonoGameStateMachine
3838
[PublicAPI]
3939
public class Fsm<TS, TT> : Fsm<TS, TT, GameTime>
4040
{
41+
private GameTime gt = new GameTime();
42+
43+
public Dictionary<Tuple<TS, TS>, List<Timer<TS>>> AfterEntries { get; set; } = new Dictionary<Tuple<TS, TS>, List<Timer<TS>>>();
44+
public List<Timer<TS>> GlobalAfterEntries { get; set; } = new List<Timer<TS>>();
45+
4146
public Fsm(FsmModel<TS, TT, GameTime> model) : base(model)
4247
{
4348
}
@@ -53,60 +58,61 @@ public Fsm(State<TS, TT, GameTime> current, bool stackEnabled = false) : base(cu
5358
/// <returns></returns>
5459
public new static BuilderFluent<TS, TT, GameTime> Builder(TS startState)
5560
{
56-
return new FluentImplementation<TS, TT, GameTime>(startState);
57-
}
58-
}
59-
60-
[PublicAPI]
61-
public class Fsm<TS, TT, TD> : StateMachine.Fsm<TS, TT, TD>
62-
{
63-
public Dictionary<Tuple<TS, TS>, List<Timer>> AfterEntries { get; set; } = new Dictionary<Tuple<TS, TS>, List<Timer>>();
64-
public Dictionary<Tuple<TS>, List<Timer>> GlobalAfterEntries { get; set; } = new Dictionary<Tuple<TS>, List<Timer>>();
65-
66-
public Fsm(FsmModel<TS, TT, TD> model) : base(model)
67-
{
61+
return new FluentImplementation<TS, TT>(startState);
6862
}
6963

70-
public Fsm(State<TS, TT, TD> current, bool stackEnabled = false) : base(current, stackEnabled)
71-
{
72-
}
73-
74-
/// <summary>
75-
/// Gets you a builder for a Finite-State-Machine (FSM).
76-
/// </summary>
77-
/// <param name="startState">The start state's key.</param>
78-
/// <returns></returns>
79-
public new static BuilderFluent<TS, TT, DataObject<TD>> Builder(TS startState)
64+
public new void Update(GameTime gameTime)
8065
{
81-
return new FluentImplementation<TS, TT, DataObject<TD>>(startState);
82-
}
66+
// After-entries on transitions.
67+
foreach (var k in Current.Model.Transitions.Keys)
68+
{
69+
List<Timer<TS>> currentAfterEntries;
70+
if (AfterEntries.TryGetValue(new Tuple<TS, TS>(Current.Identifier, k), out currentAfterEntries))
71+
{
72+
if (CheckAfterEntries(currentAfterEntries, Current.Model.Transitions, gameTime))
73+
{
74+
return;
75+
}
76+
}
77+
}
8378

84-
public new void Update(TD data)
85-
{
86-
List<Timer> l;
87-
if (!AfterEntries.TryGetValue(Current, out l))
79+
// Global after-entries.
80+
if (CheckAfterEntries(GlobalAfterEntries, Model.GlobalTransitions, gameTime))
8881
{
89-
l = new List<Tuple<float, TimeUnit>>();
90-
AfterEntries.Add(key, l);
82+
return;
9183
}
92-
l.Add(new Tuple<float, TimeUnit>(amount, timeUnit));
84+
85+
Model.Current.RaiseUpdated(new UpdateArgs<TS, TT, GameTime>(this, Current, gameTime));
86+
}
9387

94-
foreach (var e in GlobalAfterEntries)
88+
private bool CheckAfterEntries(List<Timer<TS>> afterEntries,
89+
Dictionary<TS, Transition<TS, TT, GameTime>> transitions, GameTime g)
90+
{
91+
for (int i = 0; i < afterEntries.Count; i++)
9592
{
96-
var target = e.Key;
97-
var ts = e.Value;
98-
foreach (var t in ts)
93+
Timer<TS> e = afterEntries[i];
94+
Transition<TS, TT, GameTime> t;
95+
if (transitions.TryGetValue(e.Target, out t))
9996
{
100-
97+
if (t.ConditionsMet(Current.Identifier))
98+
{
99+
double? r = e.Tick(g.ElapsedGameTime.TotalMilliseconds);
100+
afterEntries[i] = e;
101+
if (r.HasValue)
102+
{
103+
// It triggered.
104+
DoTransition(e.Target, default(TT), t.Pop);
105+
gt.IsRunningSlowly = g.IsRunningSlowly;
106+
gt.TotalGameTime = g.TotalGameTime.Subtract(TimeSpan.FromMilliseconds(r.Value));
107+
gt.ElapsedGameTime =
108+
g.ElapsedGameTime.Subtract(TimeSpan.FromMilliseconds(r.Value));
109+
Update(gt);
110+
return true;
111+
}
112+
}
101113
}
102114
}
103-
if (!GlobalAfterEntries.TryGetValue(key, out l))
104-
{
105-
l = new List<Tuple<float, TimeUnit>>();
106-
GlobalAfterEntries.Add(key, l);
107-
}
108-
109-
Model.Current.RaiseUpdated(new UpdateArgs<TS, TT, TD>(this, Current, data));
115+
return false;
110116
}
111117
}
112118
}

MonoGameStateMachine/NUnitTests/FluentTests.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public void OnMethodTests()
8787
.GlobalTransitionTo(State.IDLE).AfterGlobal(10, TimeUnit.SECONDS)
8888
.Build();
8989

90-
m.Update(new GameTime(TimeSpan.Zero, TimeSpan.FromMilliseconds(16))); // Should do nothing.
90+
m.Update(new GameTime(TimeSpan.FromDays(1), TimeSpan.FromMilliseconds(16))); // Should do nothing.
9191
Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
9292
m.Trigger(Trigger.MOUSE_CLICKED);
9393
Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
@@ -96,8 +96,8 @@ public void OnMethodTests()
9696
m.Trigger(Trigger.MOUSE_RELEASED);
9797
Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
9898
m.Trigger(Trigger.MOUSE_OVER);
99-
m.Update(new GameTime(TimeSpan.Zero, TimeSpan.FromMilliseconds(16)));
100-
m.Update(new GameTime(TimeSpan.Zero, TimeSpan.FromMilliseconds(16)));
99+
m.Update(new GameTime(TimeSpan.FromDays(1), TimeSpan.FromMilliseconds(16)));
100+
m.Update(new GameTime(TimeSpan.FromDays(1), TimeSpan.FromMilliseconds(16)));
101101
Assert.That(m.Current.Identifier, Is.EqualTo(State.OVER));
102102
Assert.That(button.BtnState, Is.EqualTo(State.OVER));
103103
Assert.That(button.OldState, Is.EqualTo(State.IDLE));
@@ -114,21 +114,21 @@ public void OnMethodTests()
114114
Assert.That(m.Current.Identifier, Is.EqualTo(State.REFRESHING));
115115
Assert.That(button.BtnState, Is.EqualTo(State.REFRESHING));
116116
Assert.That(button.OldState, Is.EqualTo(State.PRESSED));
117-
m.Update(new GameTime(TimeSpan.Zero, TimeSpan.FromMilliseconds(500))); // No transition yet...
117+
m.Update(new GameTime(TimeSpan.FromDays(1), TimeSpan.FromMilliseconds(500))); // No transition yet...
118118
Assert.That(m.Current.Identifier, Is.EqualTo(State.REFRESHING));
119119
Assert.That(button.BtnState, Is.EqualTo(State.REFRESHING));
120120
Assert.That(button.OldState, Is.EqualTo(State.PRESSED));
121-
m.Update(new GameTime(TimeSpan.Zero, TimeSpan.FromMilliseconds(500))); // But now.
121+
m.Update(new GameTime(TimeSpan.FromDays(1), TimeSpan.FromMilliseconds(600))); // But now.
122122
Assert.That(m.Current.Identifier, Is.EqualTo(State.OVER));
123123
Assert.That(button.BtnState, Is.EqualTo(State.OVER));
124124
Assert.That(button.OldState, Is.EqualTo(State.REFRESHING));
125-
m.Update(new GameTime(TimeSpan.Zero, TimeSpan.FromMilliseconds(10000)));
125+
m.Update(new GameTime(TimeSpan.FromDays(1), TimeSpan.FromMilliseconds(10000)));
126126
Assert.That(m.Current.Identifier, Is.EqualTo(State.IDLE));
127127
Assert.That(button.BtnState, Is.EqualTo(State.IDLE));
128128
Assert.That(button.OldState, Is.EqualTo(State.OVER));
129129

130130
// Update was triggered twice over all states.
131-
Assert.That(button.UpdateCounter, Is.EqualTo(2F));
131+
Assert.That(button.UpdateCounter, Is.EqualTo(3F));
132132
}
133133
}
134134
}

MonoGameStateMachine/TimeUnit.cs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,13 @@
3030
namespace MonoGameStateMachine
3131
{
3232
[PublicAPI]
33-
public enum TimeUnit
33+
public enum TimeUnit : long
3434
{
35-
MILLISECONDS,
36-
SECONDS,
37-
MINUTES,
38-
HOURS,
39-
DAYS,
40-
WEEKS,
41-
MONTHS,
42-
YEARS
35+
MILLISECONDS = 1,
36+
SECONDS = 1000,
37+
MINUTES = SECONDS * 60,
38+
HOURS = MINUTES * 60,
39+
DAYS = HOURS * 24,
40+
WEEKS = DAYS * 7
4341
}
4442
}

0 commit comments

Comments
 (0)