2010-10-14 31 views
5

Tôi đang sử dụng thư viện MSM Boost 1.44.0 mới để sản xuất máy trạng thái. Trong máy trạng thái này có hai loại sự kiện class1class2. Các sự kiện class1 có thể được xử lý theo trạng thái S1 hoặc S2 trong khi class2 chỉ có thể được xử lý theo trạng thái S2.Tăng MSM chỉ xử lý các chuyển đổi nội bộ

Sự kiện class1 đặc biệt upgrade_req yêu cầu nâng cấp từ tiểu bang S1 thành tiểu bang S2.

Tôi đã thực hiện điều đó trong Boost :: MSM như sau:

// State S1 and S2 allow any class1 events 
struct class1 {}; 
// Only state S2 allows class2 events 
struct class2 {}; 

// an upgrade request is a class1 event that requests an upgrade to state 2 
struct upgrade_req : public class1 {}; 

struct MyFSM : public msm::front::state_machine_def<MyFSM> 
{ 
    /// State 1. Allows any class1 event 
    struct S1 : public msm::front::state<> 
    { 
     /// functor says "processing event in State 1" 
     struct ProcessEvent { /* ... */ }; 

     struct internal_transition_table : mpl::vector< 
      //  Event Action  Guard 
      //  +-------+-------------+------------+ 
      Internal< class1, ProcessEvent, none > 
     > {}; 
    }; // S1 

    /// State 2. Allows any class1 or class2 events 
    struct S2 : public msm::front::state<> 
    { 
     /// functor says "processing event in State 2" 
     struct ProcessEvent { /* ... */ }; 

     struct internal_transition_table : mpl::vector< 
      //  Event Action  Guard 
      //  +-------+-------------+------------+ 
      Internal< class1, ProcessEvent, none >, 
      Internal< class2, ProcessEvent, none > 
     > {}; 
    }; // S2 

    /// everybody starts in state 1 
    typedef S1 initial_state; 

    /// send an error if a class2 event was received for state1 
    struct SendError { /* ... */ }; 

    /// Send a response to the upgrade request 
    struct SendUpgradeRsp { /* ... */ }; 

    /// functor returns true if the request to upgrade to state 2 is OK. 
    struct VerifyUpgradeReq { /* ... */ }; 

    struct transition_table : mpl::vector< 
     // Start Event   Next Action   Guard 
     // +------+-------------+------+----------------+------------------+ 
     Row< S1, class1,  none, none,   none, 
     Row< S1, class2,  S1, SendError,  none >, 
     Row< S1, upgrade_req, S2, SendUpgradRsp, VerifyUpgradeReq >, 

     Row< S2, class1,  none, none,   none, 
     Row< S2, class2,  none, none,   none > 
    > {}; 
}; // MyFSM 

Vấn đề của tôi là khi tôi sử dụng này vì nó là, sự kiện upgrade_req không bao giờ được xử lý bởi các chính MyFSM::transition_table. Nó chỉ được xử lý bởi S1::internal_transition_table.

Ví dụ:

int main(int argc, char* argv[]) 
{ 
    msm::back::state_machine<MyFSM> sm; 
    sm.start(); 
    sm.process_event(class1()); 
    sm.process_event(upgrade_req()); 
    sm.process_event(class2()); 
    return 0; 
} 

tôi sẽ mong muốn đầu ra của điều này là: sự kiện

chế biến trong nước 1.
Nâng cấp Yêu cầu OK.
kiện chế biến trong nước 2.

Nhưng, những gì tôi nhận được là: sự kiện

chế biến trong nước 1.
kiện chế biến trong nước 1.
Lỗi. Đã nhận được sự kiện loại 2 ở Tiểu bang 1.

Có ai có đề xuất về cách khắc phục sự cố này không?

Cảm ơn, PaulH

Trả lời

5

Vấn đề của bạn là ưu tiên hàng đầu của quá trình chuyển đổi nội bộ là cao hơn so với đối tượng quy định trong bảng chuyển tiếp. Và update_req là một class1, transiton nội bộ cháy. Điều này thực sự tuân theo tiêu chuẩn UML. MSM cung cấp cho bạn giải pháp thứ hai, bạn có thể xác định chuyển đổi nội bộ của S1 bằng Hàng không có mục tiêu bên trong transition_table thay vì sử dụng internal_transition_table. Nếu bạn định nghĩa nó TRƯỚC KHI quá trình chuyển đổi S1 + upgrade_reg -> S2, nó sẽ có một prio ít hơn và sẽ chỉ được thử nếu không thể xem xét đến cái kia.

Nếu bạn hoàn toàn cần một internal_transition_table thì bạn chỉ có thể cung cấp một bảo vệ để từ chối class1 nếu nó không phải là update_req.

HTH, Christophe Henry

PS: Tôi chỉ tìm thấy bài này bằng cách may mắn. Đăng lên danh sách người dùng tăng sẽ đảm bảo cho bạn câu trả lời nhanh hơn nhiều.

Các vấn đề liên quan