0

我正在寻找一些将军

  1. 优化
  2. 正确性
  3. 可扩展性

关于我当前的 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,

  1. 从堆栈中弹出“录音”(并调用其退出函数……此处未定义)。
  2. 将“播放”压入堆栈(并调用 enter 函数)。
  3. 将“alsoStreamToRemoteIp”推入堆栈(并调用 enter 函数)。
4

2 回答 2

1

我不确定我是否遵循这里的所有细节。但是,您似乎在描述具有多个状态机的 FSM(有限状态机)实现。有时,当FSM F1的特定状态(S1)发生特定事件(E1)时,需要进入一个新的FSM(称之为F2)以简化整体处理)。

如果是这种情况,那么当 E1 在 S1 中发生时,您需要调用一个动作例程来接管事件读取并实现 F2 FSM。调用时,在F2的启动状态下开始处理,并处理相关的子事件。当它到达其结束状态时,F2 的解释器完成。它可能会向 F2 运行时暂停的 F1 动作例程返回一些信息,并且 F1 中的下一个状态可能会受此影响。

您的其余描述 - 诸如“覆盖块”之类的内容 - 对于无法访问您的实现的人来说没有多大意义。

于 2009-09-11T05:32:18.687 回答
1

两件事情:

1:在大多数情况下,只需将程序的状态表示为模型,并直接或通过 MVC 模式与之交互。

2:如果你真的需要一个FSM,即你想对你的模型随机做一堆动作,在某些时候只允许其中一些动作。然后....

仍然将程序的状态保留在一个模型(或多个模型,具体取决于分解和复杂性)中,并表示状态和转换之类的。

class State:
   def __init__(self):
      self.neighbors = {}

其中邻居包含的字典{Action: State},以便您可以执行类似的操作

someAction.execute() # Actions manipulate the model (use classes or lambdas)
currentState = currentState.neighbors[someAction]

或者更酷的是,有一个无限循环从邻居中随机选择一个动作,执行它,并无限期地移动状态。这是测试程序的好方法。

于 2009-09-11T23:29:12.700 回答