zoukankan      html  css  js  c++  java
  • Qt状态机框架——如何避免状态爆炸


    前几节讲述了如何在Qt状态机框架下如何建立一个状态机,如何迁移状态,如何中断状态机,如何分组状态。本节要先看一个“异常”情况,假设我们有一个状态机,状态机有两种属性,这两种属性互不相关,比如汽车有两种属性,干净和脏,移动和静止是两组不同的属相且不相关,如果按照前几节的内容进行建模,这个状态机中有四种状态和八个状态迁移才能保证在进入所有状态,状态图如下:


    如果此时状态机发生了变化,需要增加一个属性,比如颜色,那状态数量就要翻倍(2*2*2)达到8种,如果再增加属性比如是否有天窗,那状态数量再增加一本(2*2*2*2)达到16种……如此下去,这个状态机就会发生状态爆炸了——状态数量太多了,状态迁移也太多了。
    如何避免状态爆炸呢?很幸运,Qt状态机框架提供的并行模型可以解决状态爆炸的问题。我们上每个独立的属性单独作为一个状态分组,状态分组维护自己的子状态迁移,这样即使属性增加,状态和状态迁移增加数量也是线性的,不会产生爆炸的结果,状态如类似于下面这样:



    我们如何使用Qt状态机框架如何建立并行模型呢?很简单,只需要创建状态QState时传入一个参数QState::ParallelStates即可
    QState *s1 = new QState(QState::ParallelStates);
    // s11 and s12 will be entered in parallel
    QState *s11 = new QState(s1);
    QState *s12 = new QState(s1);
    machine.addState(s1);
    Qt状态机并行模型的特殊要注意的地方:当进入并行状态S1时,S11和S12同时进入,然后每个子状态(S11和S12)中的状态迁移则是正常操作;然后如果其中一个子状态退出并行状态,那么所有子状态都会退出。
    Qt状态机框架遵循交错语义,所有并行操作以事件处理的原子步骤被执行,没有事件能够中断并行操作。然而,事件处理本身是顺序执行的,因为状态机本身在一个单独的线程里。考虑这样一个例子:有两个状态迁移能够退出并行状态,当这两个条件同时为真是,这个状态迁移中的第二个将不会起作用,因为第一个条件已经触发退出了并行状态,第二个迁移不会被处理。
    void MainWindow::CreateParallelStateMachine(void)
    {
    QState *s1 = new QState(QState::ParallelStates);
    // s11 and s12 will be entered in parallel
    QState *s11 = new QState(s1);
    QState *s12 = new QState(s1);
    connect(s11, SIGNAL(entered()), this, SLOT(OnEnterS11()));
    connect(s11, SIGNAL(exited()), this, SLOT(OnExitS11()));
    connect(s12, SIGNAL(entered()), this, SLOT(OnEnterS12()));
    connect(s12, SIGNAL(exited()), this, SLOT(OnExitS12()));
    machine.addState(s1);
    machine.setInitialState(s1);
    machine.start();
    }
    void MainWindow::OnEnterS11(void)
    {
    qDebug() << "Enter S11";
    }
    void MainWindow::OnEnterS12(void)
    {
    qDebug() << "Enter S12";
    }
    void MainWindow::OnExitS11(void)
    {
    qDebug() << "Exit S11";
    }
    void MainWindow::OnExitS12(void)
    {
    qDebug() << "Exit S12";

    }

  • 相关阅读:
    黄金点游戏
    wc
    自动生成简单四则运算
    第三章 软件工程师的成长 案例分析
    Y2K问题
    我们自己写代码的时候,是否考虑到如何让代码容易于阅读和维护呢?
    关于软件工程师的思维误区问题
    JAVAEE 第七周
    JAVAEE 第六周
    JAVAEE 第五周
  • 原文地址:https://www.cnblogs.com/lvdongjie/p/13897084.html
Copyright © 2011-2022 走看看