提升状态图:Return 到上一个状态
Boost Statechart: Return to Previous State
我有一个状态机,如果我进入一个特定的状态,有时我需要定期转换到另一个状态,而其他时候我需要 return 到之前的状态。
例如,有状态 A B C,假设转换 S 将状态 A 移动到 C,然后从 B 移动到 C。我需要转换 T 将 C 移动到 A,当 S 发生在状态 A 中时,C 移动到 B。在状态 B.
在下面的代码中,转换 S 发生在状态 B 中,因此我希望转换 T 到 return 到状态 B(而目前,它是 return 到状态 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;
}
以上代码returns:
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;
}
我有一个状态机,如果我进入一个特定的状态,有时我需要定期转换到另一个状态,而其他时候我需要 return 到之前的状态。
例如,有状态 A B C,假设转换 S 将状态 A 移动到 C,然后从 B 移动到 C。我需要转换 T 将 C 移动到 A,当 S 发生在状态 A 中时,C 移动到 B。在状态 B.
在下面的代码中,转换 S 发生在状态 B 中,因此我希望转换 T 到 return 到状态 B(而目前,它是 return 到状态 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;
}
以上代码returns:
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;
}