cpp实现的一个状态机

用cpp实现一个简单的状态机

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
#pragma once
#include <unordered_map>

using StateType = int;
static StateType NullState = -1;

class StateMachine;
class State;

class State {
public:
virtual ~State(){};

virtual void OnStateEnter(StateMachine *stateMachine) = 0;
virtual void OnTick(StateMachine *stateMachine, int64_t TimeNow) = 0;
virtual void OnStateExit(StateMachine *stateMachine) = 0;
};

class StateMachine {
private:
// 该状态机下的所有状态
std::unordered_map<StateType, State *> allStates;
// 该状态机当前状态
StateType curState = NullState;

public:
StateMachine() = default;
~StateMachine() {
for (auto &stateIter : allStates) {
if (stateIter.second != nullptr) {
stateIter.second = nullptr;
delete stateIter.second;
}
}
}

// 注册新的状态到状态机
bool RegisterState(StateType type, State *statePtr);

// 状态转移
bool Trans(StateType newState);

// TICK函数
void Tick(int64_t TimeNow);

StateType GetState() { return curState; }
};

#define CREATE_STATE(name) \
class name##State; \
using name##StatePtr = std::unique_ptr<name##State>; \
class name##State : public State { \
public: \
virtual void OnStateEnter(StateMachine *stateMachine) override; \
virtual void OnTick(StateMachine *stateMachine, int64_t TimeNow) override; \
virtual void OnStateExit(StateMachine *stateMachine) override; \
};

StateMachine.cc

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
#include "StateMachine.h"

// 注册新的状态到状态机
bool StateMachine::RegisterState(StateType type, State *statePtr) {
std::unordered_map<StateType, State *>::iterator iter = allStates.find(type);
if (iter != allStates.end()) {
return false;
}

allStates.insert({type, std::forward<State *>(statePtr)});
return true;
}

// 状态转移
bool StateMachine::Trans(StateType newState) {
// 当前状态退出
if (curState != NullState) {
std::unordered_map<StateType, State *>::iterator iter =
allStates.find(curState);
if (iter != allStates.end() && iter->second != nullptr) {
iter->second->OnStateExit(this);
}
}

// 下一状态进入
auto iter = allStates.find(newState);
if (iter == allStates.end()) {
curState = NullState;
return false;
}
if (iter->second != nullptr) {
curState = newState;
iter->second->OnStateEnter(this);
}

return true;
}

// TICK函数
void StateMachine::Tick(int64_t TimeNow) {
if (curState == NullState) {
return;
}

std::unordered_map<StateType, State *>::iterator curStateIter =
allStates.find(curState);
if (curStateIter != allStates.end() && curStateIter->second != nullptr) {
curStateIter->second->OnTick(this, TimeNow);
}
}