我是C++的新手。
如何在C++中实现状态机?
我只能得到消息,但需要知道下一个状态。
我需要使用什么样的结构?
谢谢,Igal
我是C++的新手。
如何在C++中实现状态机?
我只能得到消息,但需要知道下一个状态。
我需要使用什么样的结构?
谢谢,Igal
对于简单状态机,您可以在循环中使用switch语句,例如:
for (;;)
{
switch (state)
{
case STATE_1:
// do stuff
// maybe change state
break;
case STATE_2:
// do stuff
// maybe change state
break;
case STATE_3:
// do stuff
// maybe change state
break;
// ...
}
}
typedef std::pair<State,Message> StateMessagePair;
typedef std::map<StateMessagePair,State> StateDiagram;
StateDiagram sd;
// add logic to diagram
...
State currentState = getInitialState();
...
// process message
Message m = getMessage();
StateDiagram::iterator it=sd.find(std::make_pair(currentState,m)));
if (it==sd.end()) exit("incorrect message");
currentState = it->second;
编辑: 构建状态图的方法如下(以可乐售货机为例):
StateDiagram.insert(std::make_pair(State::Idle ,Message::MakeChoice ),State::WaitingForMoney);
StateDiagram.insert(std::make_pair(State::WaitingForMoney,Message::Cancel ),State::Idle);
StateDiagram.insert(std::make_pair(State::WaitingForMoney,Message::MoneyEntered ),State::FindCan);
StateDiagram.insert(std::make_pair(State::FindCan ,Message::CanSentToUser),State::Idle);
默认操作可以使用第二个映射来实现,其中键仅为State,如下所示:
typedef std::map<State,State> StateDiagramForDefaults;
逻辑可以在StateDiagramForDefaults中进行查找,而不是打印“错误消息”。
如果需要将操作添加到状态图中,则映射的值应该是一个由动作和新状态组成的对,如下所示:
typedef std::pair<State,Message> StateMessagePair;
typedef std::pair<State,IAction *> StateActionPair;
typedef std::map<StateMessagePair,StateActionPair> StateDiagram;
std::make_pair(currentState,m)
。 - Amr Saber
class State
{
//pass a new Message into the current State
//current State does (state-specific) processing of
//the message, and returns a pointer to the new State
//if there's a state change
virtual State* getNewState(const Message&) = 0;
};
class ExampleState
{
virtual State* getNewState(const Message& message)
{
switch (message.type)
{
case MessageType.Stop:
//change state to stopped
return new StoppedState();
}
//no state change
return 0;
}
};
其中一个复杂之处在于状态应该是静态的轻量级模式,还是它们应该携带实例数据,因此应该被新建和删除。
State* getNewState(const State& oldState)
方法,这样消息就知道状态而不是状态知道消息。第三种可能性是拥有一个二维数组,其中每个可能的消息/状态组合都有一个单独的元素,每个元素都是一个函数指针,用于处理特定的消息/状态组合。 - ChrisWcStateMachine::HandleMessage( msg_t msg )
{
switch( myState ) {
case A:
switch( msg ) {
case M:
// here is the code to handle message M when in state A
...
一旦您成功运行此功能,添加更多的状态和消息就变得非常有趣和容易。
请查看在程序中实现有限状态自动机,了解几种不同的构建有限状态机的方法。
我正在使用的是基于这个的:机器对象。
它似乎被很好地优化了,而且使用起来比Boost Statechart简单得多。