-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathStateMachine.h
71 lines (62 loc) · 2.33 KB
/
StateMachine.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#ifndef STATE_MACHINE_H
#define STATE_MACHINE_H
namespace StateMachineUtils
{
template <class TStateId> class State
{
public:
/**
* @param deltaMicros The time (in microseconds) since the last tick of the state machine
* @return The new state of the state machine
*/
virtual TStateId const Tick(unsigned long const deltaMicros) = 0;
/**
* Called when the state machine enters this state.
* Should reset any internal state inside the State object.
* Should apply any associated external state (e.g. turning on an output pin),
* making no assumptions (e.g. do not assume that output pins are already LOW)
*/
virtual void OnEnterState() = 0;
};
unsigned long const Duration(unsigned long const startMicros, unsigned long const endMicros)
{
if(startMicros > endMicros) return startMicros - endMicros;
else return endMicros - startMicros;
}
template <class TStateId> class StateMachine
{
private:
State<TStateId> * currentState;
unsigned long lastTickMicros = 0;
TStateId currentStateId;
protected:
void SetState(TStateId const newStateId)
{
if (newStateId != currentStateId)
{
currentState = GetStateInstance(newStateId);
currentState->OnEnterState();
currentStateId = newStateId;
}
}
/**
* @param stateId An identifier representing a state
* @return Pointer to a state object corresponding with the given id
*/
virtual State<TStateId> * GetStateInstance(TStateId const stateIdentifier) const = 0;
public:
StateMachine(
TStateId const initialStateId,
State<TStateId> * currentState)
: currentStateId(initialStateId)
, currentState(currentState)
{ }
void Tick()
{
auto const currentMicros = micros();
SetState(currentState->Tick(Duration(lastTickMicros, currentMicros)));
lastTickMicros = currentMicros;
}
};
}
#endif //STATE_MACHINE_H