zoukankan      html  css  js  c++  java
  • boost statechart 模板化的state类

    备忘:

        项目中大量使用了boost的statecahrt状态机.这玩意麻烦,但有时确实挺好用的.排查时让人头痛.尤其是项目整个状态机庞大且混乱,穿插了大量不规则的不属于statechart框架的全局状态变量(bool变量啥的).但工作需要,我需要实现除去人物逻辑动作等状态之外,各个状态都能有一个子状态,这样状态切换时都能进行全屏特效或别的工作.目前的办法是给state加上模板参数.事实上,项目中的确实缺乏通用子状态概念,导致实现不同职业的状态机时,类似一些特效开关,加载配置等,全部都需要在每个职业实现一个状态机,状态机里全部重写这些步骤一遍.一旦这些通用的设置有修改,就要全部去找到各个职业的状态机,然后再找到各个状态,一个一个改之.

    #ifndef __fsm_h__
    #define __fsm_h__
    
    #include <boost/statechart/event.hpp>
    #include <boost/statechart/state_machine.hpp>
    #include <boost/statechart/simple_state.hpp>
    #include <boost/statechart/state.hpp>
    #include <boost/statechart/custom_reaction.hpp>
    #include <boost/statechart/transition.hpp>
    #include <boost/statechart/result.hpp>
    
    #include <boost/config.hpp>
    
    #ifdef BOOST_INTEL
    #  pragma warning( disable: 304 ) // access control not specified
    #endif
    
    namespace Alpha
    {
        namespace fsm
        {
            namespace sc = boost::statechart;
            namespace mpl = boost::mpl;
    
            template< class MostDerived,
            class InitialState,
            class Allocator = std::allocator< void >,
            class ExceptionTranslator = sc::null_exception_translator >
            struct fsm_machine : public sc::state_machine<MostDerived, InitialState, Allocator, ExceptionTranslator>
            {
    
            };
    
            struct nulltype {};
    
            template<class Host> 
            struct fsm_state_init_converter
            {
                typedef mpl::list<Host>     type;
                typedef Host                origin_type;
            };
    
            template<> 
            struct fsm_state_init_converter< mpl::list<> >
            {
                typedef mpl::list<>  type;
                typedef nulltype     origin_type;
            };
    
            template<
                class MostDerived, 
                class Context, 
                class InnerInitial = boost::mpl::list<>, 
                    sc::history_mode historyMode = sc::has_no_history
            >
            struct fsm_state : public sc::state<MostDerived, Context, typename fsm_state_init_converter<InnerInitial>::type, historyMode>
            {
                typedef sc::state<MostDerived, Context, typename fsm_state_init_converter<InnerInitial>::type, historyMode> my_state_base;
                typedef typename fsm_state_init_converter<InnerInitial>::origin_type initial_type;
    
                fsm_state(my_state_base::my_context ctx):my_state_base(ctx) {}
            };
    
            template<class Context> 
            struct fsm_common_init_state : public fsm::fsm_state<fsm_common_init_state<Context>, Context>
            {
                typedef fsm::fsm_state<fsm_common_init_state<Context>, Context> my_state_base;
    
                fsm_common_init_state(my_state_base::my_context ctx):my_state_base(ctx) 
                { std::cout << "enter fsm_common_init_state\n"; }
                ~fsm_common_init_state() { std::cout << "exit fsm_common_init_state\n"; }
            };
    
            template<class Context, 
                template<class _Context> class common_init_state_type = fsm_common_init_state>
            struct fsm_common_state : public fsm::fsm_state<fsm_common_state<Context, common_init_state_type>, 
                Context, 
                common_init_state_type<fsm_common_state<Context, common_init_state_type>> >
            {
                typedef fsm_common_state<Context, common_init_state_type> this_type;
                typedef fsm::fsm_state<this_type, Context, common_init_state_type<this_type> > my_state_base;
    
                fsm_common_state(my_state_base::my_context ctx):my_state_base(ctx) 
                { std::cout << "enter fsm_common_state\n"; }
                ~fsm_common_state() { std::cout << "exit fsm_common_state\n"; }
            };
    
        }
    }
    
    #endif

     下一步搭配正交区域.目前遇到的问题是当前状态跳转时,实现fading时需要进入一个中间状态,而不能直接跳转(例如下一个场景),将需要某种回调机制.当然这些实际上可以通过statechart的event和reaction模拟,但之前都是通过全局变量来控制,而且场景建立删除牢牢的变为当前状态的一部分了.如果level能够做成继承多态的,而不是绑定到状态上,靠状态区分level,应是更合适的方法.目前已经定死了,解决办法就是再添加2个全局的事件,通知通用子状态,因为退出时需要进行一个延迟几秒左右的处理,来进行类似淡出的效果.当然,如果渲染和逻辑能够支持多线程,就容易处理多了.也就不纠结这几秒的延迟事件了.暂告一段落.

     可能需要搭配的event带模板的.如下:

        template<class Host> struct EffectEvent_Fading : public sc::event<EffectEvent_Fading<Host>> {};
        template<class Host> struct EffectEvent_Blooming : public sc::event<EffectEvent_Blooming<Host>> {};
  • 相关阅读:
    vue table 中 列 加上 下划线和click 方法
    vue 比较好的学习文章
    Hive 以及mysql 中如何做except 数据操作
    oracle 日期维表 原始版本 带注解
    RMI 实现的rpc 远程过程调用 Java
    剑指offer20:定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
    剑指offer19:按照从外向里以顺时针的顺序依次打印出每一个数字,4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
    模拟通讯录
    剑指offer17:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
    剑指offer16:输入两个单调递增的链表,合成后的链表满足单调不减规则。
  • 原文地址:https://www.cnblogs.com/flytrace/p/2888375.html
Copyright © 2011-2022 走看看