返回顶部

收藏

状态机模板类

更多

我写了很多描述,由于操作不熟而丢失了。大家有对状态机不了解了,建议到百度与google去搜一下“状态机”关键字。我相信你会找到很多资料。

很多设备的工作模式不是:“遇到某事做什么”,而是:“在某个状态下,遇到某事,做什么,并变成另一种状态”。

StateMachine就是一个状态机的状模板。你只要关注statemachine.hpp部分的代码,这才是你用得着的。将其包含到你的工程中。

为了方便大家了解StateMachine的使用方法,我写了一个播放机的例子。特别是要看videostatemachine.cpp中是怎么添加状态表与如果实际 状态切换的。

有Qt开发环境了朋友可以下载到同一目录下,并在该目录下执行:

$ qmake -project

$ qmake *.pro

$ make

并执行生成生可执行文件。

本人亲自下载操作一下,是可以的。

由于statemachine.hpp文件中使用了std::vector与Boost::function, Boost::bind。如果你想使用它,你的开发环境需要具备两样东西。

对了,我的boost文件放在 /usr/include/boost/ 中,仅供参考。

#ifndef STATEMACHINE_H
#define STATEMACHINE_H

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <vector>

template <typename StateType, typename EventType>
class StateMachine
{
public:
    typedef boost::function<bool()> GuardFun;
    typedef boost::function<void()> ActionFun;

    struct Item {
        StateType currState, nextState;
        EventType triger;
        GuardFun  guard;
        ActionFun action;

        Item(StateType cs, StateType ns, EventType t, GuardFun gf, ActionFun af)
            : currState(cs), nextState(ns), triger(t), guard(gf), action(af) {}
    };

    StateMachine(StateType startState) : m_currState(startState) {}

    void append(StateType cs, StateType ns, EventType t, GuardFun gf, ActionFun af) {
        m_stateTable.push_back(Item(cs, ns, t, gf, af));
    }
    void append(StateType cs, StateType ns, EventType t, GuardFun gf) {
        m_stateTable.push_back(Item(cs, ns, t, gf, boost::bind(&StateMachine::default_action, this)));
    }
    void append(StateType cs, StateType ns, EventType t, int, ActionFun af) {
        m_stateTable.push_back(Item(cs, ns, t, boost::bind(&StateMachine::default_guard, this), af));
    }
    void append(StateType cs, StateType ns, EventType t) {
        m_stateTable.push_back(Item(cs, ns, t, boost::bind(&StateMachine::default_guard, this),
                                    boost::bind(&StateMachine::default_action, this)));
    }

    StateType currentState() { return m_currState; }

    bool eventTriger(EventType triger)
    {
        bool isStateChanged = false;

        typename std::vector<Item>::iterator iter = m_stateTable.begin();
        for ( ; iter != m_stateTable.end(); ++iter) {
            if (iter->currState == m_currState && iter->triger == triger) {
                if (iter->guard()) {
                    m_currState = iter->nextState;
                    iter->action();
                    isStateChanged = true;
                }
                break;
            }
        }

        return isStateChanged;
    }

protected:
    bool default_guard() { return true; }
    void default_action() {}

private:
    std::vector<Item> m_stateTable;
    StateType m_currState;
};

#endif // STATEMACHINE_H
//该片段来自于http://outofmemory.cn

标签:c++,基础

收藏

0人收藏

支持

0

反对

0

相关聚客文章
  1. pansunyou 发表 2014-11-30 02:51:00 C++通用跨数据库访问方案之一: 基础组件cdbc
  2. linux@linux.cn (linu 发表 2016-11-04 02:37:00 C++ 程序员 Protocol Buffers 基础指南
  3. tanglei 发表 2014-05-28 15:08:01 struct与class区别联系
  4. 博主 发表 2016-06-28 05:17:59 Bazel C++ 基础[翻译]
  5. 博主 发表 2011-11-03 16:00:00 C++ 语言基础
  6. thinkpc 发表 2016-03-04 13:55:30 c++&nbsp;11 map基础value排序
  7. 王朝阳 发表 2013-03-01 00:00:00 旅游规划编制的基础思路
  8. mortoray 发表 2013-03-14 18:20:04 Parsing an exact decimal value using GMP
  9. Herb Sutter 发表 2012-06-05 19:03:20 GotW #104: Solution
  10. Herb Sutter 发表 2012-11-03 22:06:31 Talk now online: The Future of C++ (VC++, ISO C++)
  11. Boris Kolpackov 发表 2012-10-16 15:51:35 Custom C++ to Database Type Mapping in ODB
  12. dutor 发表 2011-10-16 14:19:12 调试基础:内存转储

发表评论