|
Boost Users : |
Subject: [Boost-users] [MSM] event type change while using a direct entry
From: Steckmann, Sven (sven.steckmann_at_[hidden])
Date: 2011-05-11 09:04:12
Dear list,
while writing a state machine, I added an explicit_entry to my machine. My problem now is, if I want to write different function for different event types for the entry action like this:
template < class FSM>
void on_entry(event2 const& ev,FSM&fsm ){ ⦠}
not all events were catched by it. After some compiling and generating an example, I know when the problem occurs. I am not sure if this is a bug or a feature âº. The event for the explicit entry is wrapped with a direct_entry_event. If the transition is from outside the statemachine this is quite ok (I got the original event, not the direct_entry_event), but if transition is inside the machine, the direct_entry_event is not removed and I got this to my on_entry.
The example and the console output from the listing below show this effect. Is this a compiler problem or a problem/bug/feature coming from the msm?
I am using a gcc 4.3.4 and boost 1.46.1 (trunk also shows this)
Kind regards,
Sven Steckmann
// Copyright 2010 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <vector>
#include <iostream>
// back-end
#include <boost/msm/back/state_machine.hpp>
//front-end
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>
namespace msm = boost::msm;
namespace mpl = boost::mpl;
namespace
{
// events
struct event1 {};
struct event2 {};
struct SubFsm2_ : public msm::front::state_machine_def<SubFsm2_>
{
template <class Event,class FSM>
void on_entry(Event const&,FSM& ) {std::cout << "entering: SubFsm2" << std::endl;}
template <class Event,class FSM>
void on_exit(Event const&,FSM& ) {std::cout << "leaving: SubFsm2" << std::endl;}
struct SubState2 : public msm::front::state<> , public msm::front::explicit_entry<0>
{
template <class Event,class FSM>
void on_entry(Event const&ev,FSM&fsm )
{
std::cout << "entering: SubFsm2::SubState2 with event type: " << typeid(Event).name() << std::endl;
}
template <class Event,class FSM>
void on_exit(Event const&,FSM& ) {std::cout << "leaving: SubFsm2::SubState2" << std::endl;}
};
// the initial state. Must be defined
typedef SubState2 initial_state;
// Transition table for SubFsm2
struct transition_table : mpl::vector<
// Start Event Next Action Guard
// +--------------+-------------+------------+------------------------+----------------------+
_row < SubState2 , event2 , SubState2 >
// +--------------+-------------+------------+------------------------+----------------------+
> {};
// Replaces the default no-transition response.
template <class FSM,class Event>
void no_transition(Event const& e, FSM&,int state)
{
std::cout << "no transition from state " << state
<< " on event " << typeid(e).name() << std::endl;
}
};
typedef msm::back::state_machine<SubFsm2_> SubFsm2;
// front-end: define the FSM structure
struct Fsm_ : public msm::front::state_machine_def<Fsm_>
{
// The list of FSM states
struct State1 : public msm::front::state<>
{
// every (optional) entry/exit methods get the event passed.
template <class Event,class FSM>
void on_entry(Event const&ev,FSM&fsm )
{
std::cout << "entering: State1" << std::endl;
}
template <class Event,class FSM>
void on_exit(Event const&,FSM& ) {std::cout << "leaving: State1" << std::endl;}
};
struct State2 : public msm::front::state<>
{
// every (optional) entry/exit methods get the event passed.
template <class Event,class FSM>
void on_entry(Event const&,FSM& ) {std::cout << "entering: State2" << std::endl;}
template <class Event,class FSM>
void on_exit(Event const&,FSM& ) {std::cout << "leaving: State2" << std::endl;}
};
// the initial state of the player SM. Must be defined
typedef SubFsm2 initial_state;
// Transition table for Fsm
struct transition_table : mpl::vector<
// Start Event Next Action Guard
// +---------------------+--------+------------------------------------+-------+--------+
_row < State1 , event1 , SubFsm2 >,
_row < SubFsm2 , event1 , State1 >
// +---------------------+--------+------------------------------------+-------+--------+
> {};
// Replaces the default no-transition response.
template <class FSM,class Event>
void no_transition(Event const& e, FSM&,int state)
{
std::cout << "no transition from state " << state
<< " on event " << typeid(e).name() << std::endl;
}
};
typedef msm::back::state_machine<Fsm_> Fsm;
void test()
{
Fsm p;
p.start();
p.process_event(event2());
p.process_event(event1());
p.process_event(event1());
}
}
--------------------------------------------- OUTPUT to console ------------------------------------------------------
entering: SubFsm2
entering: SubFsm2::SubState2 with event type: N5boost3msm4back13state_machineIN12_GLOBAL__N_14Fsm_ENS_9parameter5void_ES6_S6_S6_E9InitEventE
leaving: SubFsm2::SubState2
////// Comment: Now the transition is inside the submachine, the direct_entry_event is not removed
entering: SubFsm2::SubState2 with event type: N5boost3msm4back18direct_entry_eventIN12_GLOBAL__N_18SubFsm2_9SubState2ENS3_6event2EEE
leaving: SubFsm2::SubState2
leaving: SubFsm2
entering: State1
leaving: State1
entering: SubFsm2
////// Comment: Her the right event will be passed to
entering: SubFsm2::SubState2 with event type: N12_GLOBAL__N_16event1E
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net