首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >状态机表示

状态机表示
EN

Stack Overflow用户
提问于 2012-12-07 13:01:03
回答 5查看 1.5K关注 0票数 3

我希望将GUI实现为状态机。我认为这样做有好处也有缺点,但这不是这个问题的主题。

在阅读了这方面的文章之后,我发现了几种在C++中对状态机建模的方法,我坚持使用了2,但是我不知道哪种方法更适合于GUI建模。

  1. 用以下方法将状态机表示为状态列表:
代码语言:javascript
复制
- `OnEvent(...);`
- `OnEnterState(...);`
- `OnExitState(...);`

StateMachine::OnEvent(...)开始,我将事件转发给CurrentState::OnEvent(...),并在这里做出了是否进行转换的决定。在过渡阶段,我称之为CurrentState::OnExitState(...)NewState::OnEnterState()CurrentState = NewState;

使用这种方法,状态将与动作紧密耦合,但当从一种状态进入多个状态时,State可能会变得复杂,而对于不同的转换,我必须采取不同的操作。

  1. 将状态机表示为具有以下属性的转换列表:
代码语言:javascript
复制
- `InitialState`
- `FinalState`
- `OnEvent(...)`
- `DoTransition(...)`

StateMachine::OnEvent(...)中,我将事件转发到状态机中InitialStateCurrentState具有相同值的所有转换。如果满足转换条件,则停止循环,调用DoTransition方法,并将CurrentState设置为Transition::FinalState

使用这种方法,Transition将非常简单,但是转换计数的数量可能会非常高。此外,当一个州接收到一个事件时,跟踪将执行什么操作也会变得更加困难。

您认为什么方法更适合GUI建模。你知道其他可能对我的问题更好的表述吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-12-07 13:59:33

以下是第三种选择:

  • 将状态机表示为转换矩阵
    • 矩阵列索引表示状态
    • 矩阵行索引表示一个symbol (见下文)
    • 矩阵单元表示应该过渡到的状态。这既可以是新状态,也可以是同一状态。
    • 每个状态都有OnEvent方法,它返回一个symbol

StateMachine::OnEvent(...)中,事件被转发给State::OnEvent,后者返回一个symbol --执行的结果。然后,基于当前状态和返回符号的StateMachine决定是否

  • 必须向不同的状态过渡,或
  • 当前状态保持不变
  • 或者,如果进行了转换,则调用OnExitStateOnEnterState作为对应的状态。

3个状态和3个符号的示例矩阵

代码语言:javascript
复制
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

这样做的要点是:

  1. symbols的数量很可能会远低于州的数量。
  2. 国与国之间并不了解
  3. 所有的转换都是从一个点控制的,所以当您想要处理符号DB_ERRORNETWORK_ERROR不同的时候,您只需更改转换表,而不碰状态实现。
票数 3
EN

Stack Overflow用户

发布于 2012-12-07 13:38:33

我不知道这是否是你所期望的答案,但我用一种简单的方式来处理这样的状态机。

使用枚举类型的状态变量(可能的状态)。在GUI的每个事件处理程序中,测试状态值,例如使用switch语句。执行相应的处理,并设置状态的下一个值。

轻巧灵活。保持代码的正常运行使其具有可读性和“正式性”。

票数 1
EN

Stack Overflow用户

发布于 2012-12-07 13:46:08

我个人更喜欢你说的第一种方法。我发现第二个是非常违反直觉和过于复杂的。为每个状态设置一个类是简单和容易的,如果您在OnEnterState中设置正确的事件处理程序,并在OnExitState中删除它们,那么您的代码将是干净的,所有东西都将自动包含在相应的状态中,允许轻松读取。

您还将避免使用巨大的switch语句来选择要调用的正确事件处理程序或过程,因为状态所做的一切在状态本身内都是完全可见的,从而使状态机代码变得简短和简单。

最后但并非最不重要的一点是,这种编码方式是从状态机绘制到您将要使用的任何语言的精确转换。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13763627

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档