Повысьте проблемы с событиями и повторным использованием состояний.
У меня проблемы с таблицей переходов и событиями. Позвольте мне объяснить фальшивый дизайн, который иллюстрирует проблему:
У меня есть конечный автомат (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& )
{ }
};
"