我正在尝试学习boost::statechart。
我想做一个加载文件的小应用程序。
// --------------------------------
// | |
// | O Project |
// | | |
// | v |
// | ---------------------------- |
// | | | |
// | | Unloaded | |
// | ---------------------------- |
// | | ^ |
// | | EvLoad | EvUnload |<-----O
// | v | |
// | ---------------------------- |
// | | | |
// | | Loaded | |
// | ---------------------------- |
// | | ^ |
// | | | EvLoad |
// | ----- |
// --------------------------------但是我如何将参数传递给状态,例如文件名?如果我将文件名存储在EvLoad中,我可以很容易地访问它,以便进行in state反应
struct Loaded : sc::simple_state< Loaded, Project>
{
typedef sc::custom_reaction< EvLoad > reactions;
sc::result react( const EvLoad & e )
{
//load file e.path()
...
return discard_event();
}
}但是,当我处于未加载状态时,我调用了已加载的构造函数,并且不能向它传递参数。我想出的唯一解决办法是在进行转换之前重新发布事件,但在我看来这有点脏。
struct Unloaded : sc::simple_state< Unloaded, Project >
{
typedef sc::custom_reaction< EvLoad > reactions;
sc::result react( const EvLoad & e )
{
post_event( e ); //workaround to pass the event to the loaded state
return transit<Loaded>();
}
};有没有更好的选择?
发布于 2011-08-07 05:54:24
这句话出自Boost statechart的作者之口,谁还会争辩呢?:)
我的另一个建议是,如果您的任何数据存在于“项目”级别,那么加载的文件名将是FSM状态信息的一部分,处于“项目”级别,而不是“已加载”状态。
您可以使文件名成为EvLoad事件/构造函数的参数,在转换上执行自定义操作,并存储在“项目”上下文中加载的文件名。我认为这更符合statechart的概念。
所以就像这样(尽管我还没有测试过它),显然你会清理它来更好地封装成员:
struct EvLoad: sc::event<EvLoad>
{
std::string filename;
EvLoad(const std::string& fn) : filename(fn) {}
};
struct EvUnload: sc::event<EvUnload>
struct Project : sc::state_machine<Project, Unloaded>
{
std::string filename;
void LoadFile(const EvLoad& e)
{
// Load file
filename = e.filename;
}
void UnloadFile(const EvUnload& e)
{
filename.clear();
// Unload file data
}
};
struct Unloaded : sc::simple_state<Unloaded, Project>
{
typedef sc::transition<EvLoad, Loaded, Project, &Project::LoadFile> reactions;
};
struct Loaded : sc::simple_state<Loaded, Project>
{
typdef mpl::list<
sc::transition<EvLoad, Loaded, Project, &Project::LoadFile>,
sc::transition<EvUnload, Unloaded>
> reactions;
};当你加载一个文件时,驱动状态机调用,比如project.process_event(EvLoad(filename));
或者,您可以只将文件名存储在“项目”状态,并从已加载状态使用context().filename访问它。
发布于 2012-03-30 21:00:24
我们使用triggering_event方法拉取触发事件,然后将数据作为成员变量附加到触发事件。它节省了大量的编码工作,并使我们不必生成自定义反应或将转换变量附加到状态图(我见过的两种常见方法)。
https://stackoverflow.com/questions/6968841
复制相似问题