所以我试图理解 Qt 的 QStateMachine 的一个问题,我希望有人能帮助解释为什么会发生这种情况。我对 QStateMachine 的基本理解非常感兴趣,而不仅仅是修复。
首先考虑具有状态 A、B 和事件 1 的状态机。事件 1 将您从 A 带到 B。A 是初始状态。
具体来说,这是为了维护邻居。在设备 XI 中收到邻居 Y 打招呼的消息。这会导致邻居 X 为这个新邻居 Y 分配一个邻居状态机。这会创建邻居状态机,然后调用 QStateMachine::start( ) ;
现在在这个状态机启动之后,我需要继续处理这个 hello 消息。所以起初我在做:
QStateMachine::start( ) ;
emit event 1 ;
我的理解是这行不通,因为 start 是一个异步调用,因此状态机在启动完成后才处于初始启动状态。这引出了我的第一个问题。
1)所以状态机启动被放置在 qapp 事件队列中,但也没有发出异步调用?事件 1 不会在开始后被放入事件队列中,那么这不意味着我们将处于初始状态吗?还是发出不是异步调用?
认为这是问题,我通过将函数连接到状态机启动信号来稍微更改我的代码。然后,如果状态机未启动,我将代码更改为将事件排队,并在调用启动信号后处理此待处理事件队列(并将它们发送到状态机)。
事实证明,当我开始信号时,初始状态仍未设置。例如 QStateMachine::configuration( ).contains( initialstate ) == false。这引出了我的第二个也是更大的问题。
2)为什么发出started信号时我不在初始状态。
这里的事件顺序是:
- 创建状态机
- 设置初始状态
- 启动状态机
- 接收事件 1
- 由于未启动队列事件 1
- 已接收开始信号
- 处理事件 1
- 由于是未知状态什么都不做
- 接收事件 1
- 处理事件 1
- 现在处于状态 A。转换到状态 B。
顺序应该是:
- 创建状态机
- 设置初始状态
- 启动状态机
- 接收事件 1
- 由于未启动队列事件 1
- 已接收开始信号
- 处理事件 1
- 现在是状态 A。转换到状态 B。
- 接收事件 1
- 处理事件 1
- 现在是状态 B。什么也不做。
或者更好的活动我希望我不必排队参加活动。我希望我能做到这一点:
- 创建状态机
- 设置初始状态
- 启动状态机
- 接收事件 1
- 处理事件 1
- 现在是状态 A。转换到状态 B。
- 接收事件 1
- 处理事件 1
- 现在是状态 B。什么也不做。