我希望将GUI实现为状态机。我认为这样做有好处也有缺点,但这不是这个问题的主题。
在阅读了这方面的文章之后,我发现了几种在C++中对状态机建模的方法,我坚持使用了2,但是我不知道哪种方法更适合于GUI建模。
- `OnEvent(...);`
- `OnEnterState(...);`
- `OnExitState(...);`从StateMachine::OnEvent(...)开始,我将事件转发给CurrentState::OnEvent(...),并在这里做出了是否进行转换的决定。在过渡阶段,我称之为CurrentState::OnExitState(...),NewState::OnEnterState()和CurrentState = NewState;
使用这种方法,状态将与动作紧密耦合,但当从一种状态进入多个状态时,State可能会变得复杂,而对于不同的转换,我必须采取不同的操作。
- `InitialState`
- `FinalState`
- `OnEvent(...)`
- `DoTransition(...)`从StateMachine::OnEvent(...)中,我将事件转发到状态机中InitialState与CurrentState具有相同值的所有转换。如果满足转换条件,则停止循环,调用DoTransition方法,并将CurrentState设置为Transition::FinalState。
使用这种方法,Transition将非常简单,但是转换计数的数量可能会非常高。此外,当一个州接收到一个事件时,跟踪将执行什么操作也会变得更加困难。
您认为什么方法更适合GUI建模。你知道其他可能对我的问题更好的表述吗?
发布于 2012-12-07 13:59:33
以下是第三种选择:
symbol (见下文)OnEvent方法,它返回一个symbol
从StateMachine::OnEvent(...)中,事件被转发给State::OnEvent,后者返回一个symbol --执行的结果。然后,基于当前状态和返回符号的StateMachine决定是否
OnExitState和OnEnterState作为对应的状态。3个状态和3个符号的示例矩阵
0 1 2
1 2 0
2 0 1在本例中,如果机器处于任何一个od状态,则(0,1,2)和State::OnEvent返回符号0 (矩阵中的第一行)--它处于相同的状态。
第二行说,如果当前状态是0,而返回的符号是1,则转换为状态1。用于state 1 -> state 2和state 2 -> state 0。
类似的第三行表示,对于符号2,state 0-> state 2,state 1 -> state 0,state 2 -> state 1。
这样做的要点是:
symbols的数量很可能会远低于州的数量。DB_ERROR与NETWORK_ERROR不同的时候,您只需更改转换表,而不碰状态实现。发布于 2012-12-07 13:38:33
我不知道这是否是你所期望的答案,但我用一种简单的方式来处理这样的状态机。
使用枚举类型的状态变量(可能的状态)。在GUI的每个事件处理程序中,测试状态值,例如使用switch语句。执行相应的处理,并设置状态的下一个值。
轻巧灵活。保持代码的正常运行使其具有可读性和“正式性”。
发布于 2012-12-07 13:46:08
我个人更喜欢你说的第一种方法。我发现第二个是非常违反直觉和过于复杂的。为每个状态设置一个类是简单和容易的,如果您在OnEnterState中设置正确的事件处理程序,并在OnExitState中删除它们,那么您的代码将是干净的,所有东西都将自动包含在相应的状态中,允许轻松读取。
您还将避免使用巨大的switch语句来选择要调用的正确事件处理程序或过程,因为状态所做的一切在状态本身内都是完全可见的,从而使状态机代码变得简短和简单。
最后但并非最不重要的一点是,这种编码方式是从状态机绘制到您将要使用的任何语言的精确转换。
https://stackoverflow.com/questions/13763627
复制相似问题