我的fsm中的状态具有不同的属性。我定义了一个事件,它将调用转换到目标状态。我想通过事件数据设置目标属性。我的选择是: 1.在动作或守卫中设置属性:但它仍处于源状态。如果我当时设置目标状态属性,我填写不好 2.在目标条目中设置属性:但是在收到事件时已经保护计算了属性的值,因此我应该重新计算:(
任何人都可以给我更多想法。谢谢 !
答案 0 :(得分:1)
我不确定你的情况,但我认为你有两个不同的问题。一个是设定目标州财产的最佳地点。另一个是如何避免重新计算。
让我们考虑前一个问题。如你所说,有两个候选人。它们是过渡动作和目标状态的进入动作。我认为两者都可以。如果您使用目标状态的输入操作,则需要关注事件类型。如果您按如下方式编写处理程序,则处理程序将捕获所有事件。
#define ID_TEXT 100
...
case WM_CREATE:
{
CreateWindow(L"STATIC", L"", WS_VISIBLE | WS_CHILD,
0, 0, 0, 0, hWnd, HMENU(ID_TEXT), 0, NULL);
...
resize_window(hWnd);
}
case WM_SIZE:
{
resize_window(hWnd);
return 0;
}
void resize_window(HWND hwnd)
{
RECT rc;
GetClientRect(hwnd, &rc);
//update ****
WINDOWSIZEW = rc.right;
WINDOWSIZEH = rc.bottom;
...
SetWindowPos(GetDlgItem(hWnd, ID_TEXT), 0, x, y, w, h, SWP_NOZORDER);
...
}
您可以按如下方式指定事件:
template <class Event, class Fsm>
void on_entry(Event const& e, Fsm&) {
std::cout << "State2::on_entry()" << std::endl;
std::cout << "You can also set the property here." << std::endl;
property = e.data;
}
要解决后一个问题,如何避免重新计算,需要将事件中的成员变量声明为可变,如下所示:
template <class Fsm>
void on_entry(Event1 const& e, Fsm&) {
std::cout << "State2::on_entry()" << std::endl;
std::cout << "You can also set the property here." << std::endl;
property = e.data;
}
因为Boost.MSM将Event参数作为const引用传递。
这是一段代码,描述了如何在不重新计算的情况下设置目标状态属性:
struct Event1 {
mutable int data; // mutable is required because Event is passed as const&.
};
您可以使用在线编译器Wandbox编译,运行和修改代码。 http://melpon.org/wandbox/permlink/L1HAjIiLU091906u