Boost Statechart:返回以前的状态

Boost Statechart: Return to Previous State

本文关键字:状态 返回 Statechart Boost      更新时间:2023-10-16

我有一台状态计算机,如果我输入特定状态,有时我需要定期过渡到另一个状态,而其他时间我需要返回以前的状态。<<<<<<<<<<<<

例如,使a b c表示过渡s将状态a移至c,从b到C。我需要一个过渡t将c移动到s时,当s发生在状态中时a和c在状态中发生在状态中时B.

在下面的代码中,过渡s发生在状态B中,因此我希望过渡t返回状态B(而目前,它返回状态A(。

#include <boost/mpl/list.hpp>
#include <boost/statechart/state_machine.hpp>
#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/event.hpp>
#include <boost/statechart/transition.hpp>
// states
struct A;
struct B;
struct C;
struct D;
// events
struct S : boost::statechart::event<S> {};
struct T : boost::statechart::event<T> {};
struct U : boost::statechart::event<U> {};
// fsm
struct FSM : boost::statechart::state_machine<FSM, B> {};
// fully defined states/transitions
struct A : boost::statechart::simple_state<A, FSM> {
    typedef boost::statechart::transition<S, C> reactions;
    A() { std::cout << "entered A" << std::endl; }
};
struct B : boost::statechart::simple_state<B, FSM> {
    typedef boost::statechart::transition<S, C> reactions;
    B() { std::cout << "entered B" << std::endl; }
};
struct C : boost::statechart::simple_state<C, FSM> {
    typedef boost::mpl::list<
                boost::statechart::transition<T, A>,
                boost::statechart::transition<T, B>,
                boost::statechart::transition<U, D> > reactions;
    C() { std::cout << "entered C" << std::endl; }
};
struct D : boost::statechart::simple_state<D, FSM> {
    D() { std::cout << "entered D" << std::endl; } 
};
int main() {
    FSM fsm;
    fsm.initiate();
    fsm.process_event(S());
    fsm.process_event(T());
    fsm.process_event(S());
    fsm.process_event(U());
    return 0;
}

上述代码返回:

entered B
entered C
entered A
entered C
entered D

我想看:

entered B
entered C
entered B
entered C
entered D

使用boost :: statechart有什么干净的方法?

我找到了一个〜好〜通过为状态创建枚举映射,将先前状态存储在最外面的上下文(顶级FSM(,然后使用一个,然后使用一个,然后使用一个,然后使用一个T事件的自定义反应:

#include <boost/mpl/list.hpp>
#include <boost/statechart/state_machine.hpp>
#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/event.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/statechart/custom_reaction.hpp>
// states
struct A;
struct B;
struct C;
struct D;
// state enum mapping
enum class state_mapping {
    A = 0,
    B,
    C,
    D
};
// events
struct S : boost::statechart::event<S> {};
struct T : boost::statechart::event<T> {};
struct U : boost::statechart::event<U> {};
// fsm
struct FSM : boost::statechart::state_machine<FSM, B> {
    state_mapping previous_state = state_mapping::B;
};
// fully defined states/transitions
struct A : boost::statechart::simple_state<A, FSM> {
    typedef boost::statechart::transition<S, C> reactions;
    
    A() { std::cout << "entered A" << std::endl; }
    virtual ~A() { outermost_context().previous_state = state_mapping::A; }
};
struct B : boost::statechart::simple_state<B, FSM> {
    typedef boost::statechart::transition<S, C> reactions;
    
    B() { std::cout << "entered B" << std::endl; }
    virtual ~B() { outermost_context().previous_state = state_mapping::B; }
};
struct C : boost::statechart::simple_state<C, FSM> {
    typedef boost::mpl::list<
                boost::statechart::custom_reaction<T>,
                boost::statechart::transition<U, D> > reactions;
                
    C() { std::cout << "entered C" << std::endl; }
    
    boost::statechart::result react(const T&) {
        
        switch(outermost_context().previous_state) {
            
        case state_mapping::A:
            return transit<A>();
        case state_mapping::B:
            return  transit<B>();
        default:
            return discard_event();
            
        }
        
    }
};
struct D : boost::statechart::simple_state<D, FSM> {
    D() { std::cout << "entered D" << std::endl; }
};
int main() {
    FSM fsm;
    
    fsm.initiate();
    
    fsm.process_event(S());
    fsm.process_event(T());
    fsm.process_event(S());
    fsm.process_event(U());
    return 0;
}