boost :: msm用法:如何设置目标状态的属性

时间:2016-02-18 05:51:13

标签: c++ boost

我的fsm中的状态具有不同的属性。我定义了一个事件,它将调用转换到目标状态。我想通过事件数据设置目标属性。我的选择是: 1.在动作或守卫中设置属性:但它仍处于源状态。如果我当时设置目标状态属性,我填写不好 2.在目标条目中设置属性:但是在收到事件时已经保护计算了属性的值,因此我应该重新计算:(

任何人都可以给我更多想法。谢谢 !

1 个答案:

答案 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