Boost logo

Boost Users :

Subject: [Boost-users] [msm] How to cause no_transition for cases of guard returning false?
From: 谢任中 (joshchia_at_[hidden])
Date: 2012-11-13 03:40:59


Hi,

I want no_transition() to be called whenever no row matches, even if there
is a row that does not match only because the guard returns false. How can
I achieve this? I want to be strict about the input events. I can probably
workaround this by putting guardless rows at the top whose action is to
call no_transition(), but I'm hoping to find a cleaner solution.

If I get this behavior in msm, then the following code should output "no
transition..." as its last line. Right now, with boost 1.51, it doesn't. It
just prints "entering State1".

Josh

#include <iostream>

#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/functor_row.hpp>
#include <boost/msm/front/state_machine_def.hpp>

using namespace std;

namespace mpl = boost::mpl;
namespace msm = boost::msm;
using namespace msm::front;

struct Event {
    Event(bool data) : data(data) { }
    bool data;
};

struct state_ : public msm::front::state_machine_def<state_> {
    struct MyGuard {
        template <class EVT, class FSM, class SourceState, class
TargetState>
        bool operator()(EVT const& e, FSM&, SourceState&, TargetState&) {
            return e.data;
        }
    };

    struct State1 : public msm::front::state<> {
        // optional entry/exit methods
        template <class Event,class FSM>
        void on_entry(Event const&, FSM& f) { 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<> {
        // optional entry/exit methods
        template <class Event,class FSM>
        void on_entry(Event const&, FSM& f) { std::cout << "entering:
State2" << std::endl; }
        template <class Event,class FSM>
        void on_exit(Event const&,FSM& ) { std::cout << "leaving: State2"
<< std::endl; }
    };

    typedef State1 initial_state;
    struct transition_table : mpl::vector<
        Row< State1, Event , State2, none, MyGuard >
> {};

    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<state_> State;

int main() {
    State state;
    state.start();
    state.process_event(Event(false));
    return 0;
}



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