Boost logo

Boost Users :

Subject: [Boost-users] Boost.MSM: Exit a composite state after an event has been fired from that composite state?
From: RaRi (degoah_at_[hidden])
Date: 2012-12-19 10:22:07


Hi list,

I'm using boost.msm from the boost 1.52 library and trying to fire an event
from a composite state to enter a state of a top level state machine.
Unfortunatly this doesn't work.

Please consider here for the following code:

namespace {
    namespace msm = boost::msm;
    namespace msmf = boost::msm::front;
    namespace mpl = boost::mpl;

    // ----- Events
    struct Event1 {};
    struct Event2 {};
    struct EventSub1 {};
    struct EventSub2 {};

    // ----- State machine
    struct OuterSm_:msmf::state_machine_def<OuterSm_>
    {
        struct State1_:msmf::state_machine_def<State1_>
        {
            template <class Event,class Fsm>
            void on_entry(Event const&, Fsm&) const {
                std::cout << "State1::on_entry()" << std::endl;
            }

            template <class Event,class Fsm>
            void on_exit(Event const&, Fsm&) const {
                std::cout << "State1::on_exit()" << std::endl;
            }

            struct SubState1:msmf::state<> {
                template <class Event,class Fsm>
                void on_entry(Event const&, Fsm& fsm) const {
                    std::cout << "SubState1::on_entry()" << std::endl;
                    std::cout << "SubState1::fire event2()" << std::endl;
                    fsm.process_event(Event2()); // Produces an assertion ->
It is not possible to leave the submachine although the "Event2()" is
defined as transition in the transition table of the outermachine.

                }

                template <class Event,class Fsm>
                void on_exit(Event const&, Fsm&) const {
                    std::cout << "SubState1::on_exit()" << std::endl;
                }
            };

            struct SubState2:msmf::state<> {
                template <class Event,class Fsm>
                void on_entry(Event const&, Fsm& a) const {
                    std::cout << "SubState2::on_entry()" << std::endl;
                }

                template <class Event,class Fsm>
                void on_exit(Event const&, Fsm&) const {
                    std::cout << "SubState2::on_exit()" << std::endl;
                }
            };

            struct Exit1:msmf::exit_pseudo_state<msmf::none> {};

            // Set initial state
            typedef mpl::vector<SubState1> initial_state;
            // Transition table
            struct transition_table:mpl::vector<
                // Start Event Next Action Guard
                msmf::Row < SubState1, EventSub1, SubState2, msmf::none,
msmf::none >
               // Is there a possibility in MSM to exit a composite state if
an event is fired from that
              // msmf::Row < SubState1, Event2, Exit1, msmf::none,
msmf::none > I don't want this!

> {};
        };

        struct State2:msmf::state<>
        {
            template <class Event,class Fsm>
            void on_entry(Event const&, Fsm&) const {
                std::cout << "State2::on_entry()" << std::endl;
            }
            template <class Event,class Fsm>
            void on_exit(Event const&, Fsm&) const {
                std::cout << "State2::on_exit()" << std::endl;
            }

            template <class Event, class Fsm, class SourceState, class
TargetState>
            void operator()(Event const&, Fsm& f, SourceState&,
TargetState&) const
            {
                std::cout << "Do function" << std::endl;
            }
        };

        typedef msm::back::state_machine<State1_> State1;

        // Set initial state
        typedef State1 initial_state;
        // Transition table
        struct transition_table:mpl::vector<
            // Start Event Next Action Guard
            msmf::Row < State1, Event2, State2, State2, msmf::none
>
> {};
    };

    // Pick a back-end
    typedef msm::back::state_machine<OuterSm_> Osm;

    void test()
    {
        Osm osm;
        osm.start();
        // osm.process_event(Event2()); // This works fine -> Leaving state
"Substate1" of the submachine
    }
}

int main()
{
    test();
    return 0;
}

You see that the code calls f*sm.process_event(Event2())* within the state
*SubState1* of the submachine to make a transition from the top-level state
*State1* to *State2* of the outer statemachine. Unfortunately this doesn't
work although the *Event2* is defined in the transition table of the
outer-statemachine.

On the other hand it a transition from *State1* to state *State2* works in
case the event *Event2* is fired outside the submachine ( please refer to
the void test() function in the code above).

I actually don't want to define a transition in the transition table of
submachine to enter an pseudo exit point like:

msmf::Row < SubState1, Event2, Exit1, msmf::none, msmf::none >

Is there a possibility in MSM to exit a composite state if an event is fired
from that composite state?

Thank you in advance for your time and help!

Grüße ;),

RaRi

--
View this message in context: http://boost.2283326.n4.nabble.com/Boost-MSM-Exit-a-composite-state-after-an-event-has-been-fired-from-that-composite-state-tp4640341.html
Sent from the Boost - Users mailing list archive at Nabble.com.

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