Повысьте проблемы с событиями и повторным использованием состояний.

У меня проблемы с таблицей переходов и событиями. Позвольте мне объяснить фальшивый дизайн, который иллюстрирует проблему:

У меня есть конечный автомат (myStateMachine), содержащий 2 состояния (s0 и s1) и 1 подсостояние машины (subm1).

подсистема subm1 содержит начальное состояние sub0, а также s1 (то же состояние, что и в myStateMachine).

это основная таблица переходов:

s0-> s1 для события 'ES1'

s0-> s2 для события 'ES2'

s0-> subm1 для события 'ESUB'

это таблица переходов для автоматов:

sub0-> s1 для события 'ES1'

теперь предположим, что состояние s1 использует событие, которое вызвало его, для извлечения некоторой информации, т.е.

struct s1 : public msm::front::state<>
{
   template <class Event,class FSM>
   void on_entry(Event const& evt,FSM& fsm)
   { 
      evt.getEventData();
   }
}

поэтому каждое событие, которое может перейти к s1, должно реализовывать метод getEventData().

-> это нормально!

Теперь моя проблема в том, что ESUB НЕ реализует getEventData(), но, очевидно, так и должно (компилятор выдает ошибки). И я не понимаю почему.

Я не использую ESUB для перехода на s1, но я использую ESUB для перехода на subm1, а subm1 содержит s1, но я не получаю к нему доступ в этот момент.

Я надеюсь, что это понятно.

1 ответ

Решение

Я ПОЛУЧИЛ ОТВЕТ ОТ ДИЗАЙНЕРА BOOST MSM Кристофа Генри:

"Привет,

это досадное ограничение msm (для композитов), которое я имею в своем списке вещей, чтобы решить как можно скорее. Проблема в том, что хотя esub не используется для перехода к s1, для компилятора это возможно. Как бы то ни было, это моя вина, плюс я забыл это в доке:(

Решение состоит в том, чтобы немного помочь компилятору, включив on_entry с evt.getEventData() только для событий, имеющих специальное свойство, такое как ваш es1. Например:

BOOST_MPL_HAS_XXX_TRAIT_DEF(get_event_data) 

// this event supports getEventData 
struct es1 
{ 
   typedef int get_event_data; 
   void getEventData(){...} 
 }; 

Затем используйте это в вашем штате:

 struct s1 : public msm::front::state<> 
 { 
   template <class Event,class FSM> 
   typename boost::enable_if<typename 
   has_get_event_data<Event>::type,void>::type 
   on_entry(Event const& evt,FSM& fsm) 
   { 
      evt.getEventData(); 
   } 
   // for events not supporting getEventData like esub 
   template <class Event,class FSM> 
   typename boost::disable_if<typename 
   has_get_event_data<Event>::type,void>::type 
   on_entry(Event const& ,FSM& ) 
   {    } 
   }; 

"

Другие вопросы по тегам