State machine throws std exception in an action

Forwarded private email: --- Ankorus wrote:
Subject: State machine throws std exception in an action Date: Mon, 10 Dec 2007 15:08:01 -0800
Andreas,
The state machine I am using for boost statechart playground is as simple as it gets. Stopped -> Started where Started state has 2 sub states: Passive (default) -> Active. I started with simple_state, found that it does not have sm context in constructor, moved to state, added some actions. Everything was looking good so far. Now the action called transitioning from Passive to Active throws std exception. I am expecting Started state to transit to Exception but it is not happenning... Any comments appreciated...
Thanks, Ankorus
// StateDefines.h #pragma once #include <boost/statechart/event.hpp> #include <boost/statechart/state_machine.hpp> namespace sc = boost::statechart; // Events struct EvStart : sc::event<EvStart> {}; struct EvStop : sc::event<EvStop> {}; struct EvActivate : sc::event<EvActivate> {}; struct EvDeactivate : sc::event<EvDeactivate> {}; // States struct Started; struct Stopped; struct Active; struct Passive; struct Exception;
// States.h #pragma once #include <boost/statechart/state.hpp> #include <boost/statechart/simple_state.hpp> #include <boost/statechart/transition.hpp> #include <boost/statechart/exception_translator.hpp> #include <boost/mpl/list.hpp> #include "SomeClass.h" namespace mpl = boost::mpl; struct Started : sc::simple_state<Started, SomeClass, Passive> { typedef mpl::list < sc::transition<EvStop, Stopped, SomeClass, &SomeClass::Shutdown>, sc::transition<sc::exception_thrown, Exception>
reactions; Started(); ~Started(); }; struct Stopped : sc::state<Stopped, SomeClass> { typedef sc::transition<EvStart, Started, SomeClass, &SomeClass::Startup> reactions; Stopped(my_context ctx); ~Stopped(); }; struct Active : sc::simple_state<Active, Started> { typedef sc::transition<EvDeactivate, Passive, SomeClass, &SomeClass::Deactivate> reactions; Active(); ~Active(); }; struct Passive : sc::simple_state<Passive, Started> { typedef sc::transition<EvActivate, Active, SomeClass, &SomeClass::Activate> reactions; Passive(); ~Passive(); }; struct Exception : sc::simple_state<Exception, Started> { //typedef sc::transition<EvStart, Started, SomeClass, &SomeClass::Startup> reactions; Exception(); ~Exception(); };
// States.cpp #include "StdAfx.h" #include "States.h" Stopped::Stopped(my_context ctx) : sc::state<Stopped, SomeClass>(ctx) { std::cout << __FUNCTION__ << std::endl; context<SomeClass>().SomeFun(); }; Stopped::~Stopped() { std::cout << __FUNCTION__ << std::endl; }; Started::Started() { std::cout << __FUNCTION__ << std::endl; }; Started::~Started() { std::cout << __FUNCTION__ << std::endl; }; Active::Active() { std::cout << __FUNCTION__ << std::endl; }; Active::~Active() { std::cout << __FUNCTION__ << std::endl; }; Passive::Passive() { std::cout << __FUNCTION__ << std::endl; }; Passive::~Passive() { std::cout << __FUNCTION__ << std::endl; }; Exception::Exception() { std::cout << __FUNCTION__ << std::endl; }; Exception::~Exception() { std::cout << __FUNCTION__ << std::endl; };
// SomeClass.h #pragma once #include "StatesDefines.h" class SomeClass : public sc::state_machine<SomeClass, Stopped> { public: SomeClass(); ~SomeClass(); void SomeFun() { std::cout << __FUNCTION__ << std::endl; } public: void Activate(const EvActivate& e) { std::cout << "Action: "__FUNCTION__ << std::endl; throw std::exception("Activation exception"); } void Deactivate(const EvDeactivate& e) { std::cout << __FUNCTION__ << std::endl; } void Startup(const EvStart& e) { std::cout << __FUNCTION__ << std::endl; } void Shutdown(const EvStop& e) { std::cout << __FUNCTION__ << std::endl; } };
// SomeClass.cpp #include "StdAfx.h" #include "States.h" SomeClass::SomeClass() { initiate(); } SomeClass::~SomeClass() { }
// main.cpp #include "stdafx.h" #include "SomeClass.h" int main(int argc, char* argv[]) { //try //{ SomeClass sc; sc.process_event(EvStart()); sc.process_event(EvActivate()); sc.process_event(EvStop()); //} //catch(std::exception& e) //{ // std::cout << e.what() << std::endl; //} return 0; }

Hi
Now the action called transitioning from Passive to Active throws std exception. I am expecting Started state to transit to Exception but it is not happenning... Any comments appreciated...
and
class SomeClass : public sc::state_machine<SomeClass, Stopped>
By default, a state_machine does not translate exceptions but just propagates them to the state machine client, please see <http://www.boost.org/libs/statechart/doc/tutorial.html#ExceptionHandling> You need to pass an instantiation of exception_translator<> as additional parameter to state_machine<>, as follows: class SomeClass : public sc::state_machine< SomeClass, Stopped, std::allocator<void>, sc::exception_translator<> > { ... }; Please see <http://www.boost.org/libs/statechart/doc/reference.html#ClassTemplateexception_translator> for more information. HTH, -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.
participants (1)
-
Andreas Huber