我希望能够将事件中的数据传递给由于转换而构建的状态。
从2009年的this帖子和2010年的this个帖子中建议使用triggering_event()
。但是,我无法在任何地方找到演示如何使用它的示例。
有人可以帮忙吗?
答案 0 :(得分:0)
以下示例是基于所描述的电机状态机here的Boost状态图实现。我没有使用custom_reaction来提高EvSetSpeed事件的速度(如此处的其他状态),而是修改它以在Start状态的构造函数中调用triggering_event()。
注意事项:
最后,值得一提的是,尝试在状态机的初始状态的构造函数中调用triggering_event将导致返回null值。这是因为初始状态是在启动调用期间构建的,其中没有触发事件。
#include <boost/statechart/state_machine.hpp>
#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/state.hpp>
#include <boost/statechart/event.hpp>
#include <boost/statechart/in_state_reaction.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/mpl/list.hpp>
#include <boost/statechart/custom_reaction.hpp>
#include <iostream>
namespace mpl = boost::mpl;
namespace sc = boost::statechart;
class EvHalt : public sc::event< EvHalt > {};
class EvSetSpeed : public sc::event< EvSetSpeed >
{
public:
EvSetSpeed(int speed) : _speed(speed) {}
int getSpeed() const { return _speed; };
private:
int _speed;
};
class Idle;
class Start;
class Stop;
class Running;
class Motor : public sc::state_machine<Motor, Idle> {};
class Idle : public sc::simple_state<Idle, Motor>
{
public:
typedef mpl::list<
sc::transition< EvSetSpeed, Start >,
sc::transition< EvHalt, Idle > > reactions;
Idle() { std::cout << "Entering Idle State" << std::endl; };
~Idle() { std::cout << "Exiting Idle State" << std::endl; };
};
class Start : public sc::state<Start, Motor>
{
public:
typedef mpl::list<
sc::transition< EvSetSpeed, Running >,
sc::transition< EvHalt, Stop > > reactions;
Start(my_context ctx) : _speed(0), my_base(ctx)
{
auto trigEvt = dynamic_cast<const EvSetSpeed*>(triggering_event());
if (trigEvt) // returns true if trigEvt is indeed an EvSetSpeed event
{
_speed = trigEvt->getSpeed();
post_event(*trigEvt);
std::cout << "Entering Start State at speed " << _speed << std::endl;
}
else
std::cout << "Entering Start State. Triggering Event is NOT EvSetSpeed." << std::endl;
};
~Start() { std::cout << "Exiting Start State" << std::endl; };
private:
int _speed; // Unused in this example.
};
class Running : public sc::simple_state<Running, Motor>
{
public:
typedef mpl::list<
sc::custom_reaction< EvSetSpeed >,
sc::custom_reaction< EvHalt > > reactions;
sc::result react(const EvSetSpeed& ev)
{
std::cout << "In Running Mode: Set Speed to " << ev.getSpeed() << std::endl;
return discard_event();
}
sc::result react(const EvHalt& ev)
{
std::cout << "In Running Mode: Halting Motor" << std::endl;
post_event(ev);
return transit<Stop>();
}
Running() { std::cout << "Entering Running State" << std::endl; };
~Running() { std::cout << "Exiting Running State" << std::endl; };
};
class Stop : public sc::simple_state<Stop, Motor>
{
public:
typedef sc::transition< EvHalt, Idle > reactions;
Stop() { std::cout << "Entering Stop State" << std::endl; };
~Stop() { std::cout << "Exiting Stop State" << std::endl; };
};
int main()
{
Motor myMotor;
myMotor.initiate();
myMotor.process_event(EvSetSpeed(100));
myMotor.process_event(EvSetSpeed(200));
myMotor.process_event(EvHalt());
myMotor.process_event(EvSetSpeed(300));
myMotor.process_event(EvHalt());
myMotor.process_event(EvHalt());
return 0;
}