我正在寻找一些将军
- 优化
- 正确性
- 可扩展性
关于我当前的 C++ 分层状态机实现的建议。
样本
variable isMicOn = false
variable areSpeakersOn = false
variable stream = false
state recording
{
//override block for state recording
isMicOn = true //here, only isMicOn is true
//end override block for state recording
}
state playback
{
//override block for state playback
areSpeakersOn = true //here, only areSpeakersOn = true
//end override block for state playback
state alsoStreamToRemoteIp
{
//override block for state alsoStreamToRemoteIp
stream = true //here, both areSpeakersOn = true and stream = true
//end override block for state alsoStreamToRemoteIp
}
}
goToState(recording)
goToState(playback)
goToState(playback.alsoStreamToRemoteIp)
执行
目前,HSM 被实现为树结构,其中每个状态可以有可变数量的状态作为子状态。
每个状态包含可变数量的覆盖基值的“覆盖”块(在 std::map 中)。在根状态,状态机有一组变量(函数、属性...)初始化为一些默认值。每次我们进入子状态时,“覆盖”列表都会定义变量和值,这些变量和值应该替换父状态中同名的变量和值。为清楚起见,更新了原文。
引用变量
在运行时,当前状态存储在堆栈中。
每次引用变量时,都会执行向下堆栈遍历,以寻找最高覆盖,或者在没有覆盖的情况下,寻找默认值。
切换状态
每次切换到单个状态帧时,该状态都会被压入堆栈。
每次切换到一个状态时,我都会跟踪一个树的下降,它将我从当前状态带到根状态。然后我从目标状态到根状态进行树下降,直到我看到当前跟踪与前一个跟踪匹配。我在这两条迹线相遇的地方声明了一个交叉点。然后,为了切换到目标状态,我从源下降,从堆栈中弹出状态帧,直到到达交点。然后我上升到目标节点并将状态帧推入堆栈。
所以对于上面的代码示例
状态切换的执行跟踪
- 源状态 = 记录
目标状态 = 也StreamToRemoteIp
从源下降 = 记录->根(跟踪 = [根])
从目标的下降=也StreamToRemoteIp->播放->根(跟踪= [播放,根])
相交于根。
要从录制切换到还StreamToRemoteIp,
- 从堆栈中弹出“录音”(并调用其退出函数……此处未定义)。
- 将“播放”压入堆栈(并调用 enter 函数)。
- 将“alsoStreamToRemoteIp”推入堆栈(并调用 enter 函数)。