////////////////////////////////////////////////////////////////////////////// // Copyright 2005-2006 Andreas Huber Doenni // Distributed under the Boost Software License, Version 1.0. (See accompany- // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include namespace sc = boost::statechart; namespace mpl = boost::mpl; struct EvToA : sc::event< EvToA > {}; struct EvToB : sc::event< EvToB > {}; struct EvToD : sc::event< EvToD > {}; struct EvToE : sc::event< EvToE > {}; struct A; struct StateIterationTest : sc::state_machine< StateIterationTest, A > { public: ////////////////////////////////////////////////////////////////////////// StateIterationTest(); void AssertInState( const std::string & stateNames ) const { stateNamesCache_.clear(); for ( state_iterator currentState = state_begin(); currentState != state_end(); ++currentState ) { const StateNamesMap::const_iterator found = stateNamesMap_.find( currentState->dynamic_type() ); BOOST_REQUIRE( found != stateNamesMap_.end() ); stateNamesCache_.insert( found->second ); } std::string::const_iterator expectedName = stateNames.begin(); BOOST_REQUIRE( stateNames.size() == stateNamesCache_.size() ); for ( StateNamesCache::const_iterator actualName = stateNamesCache_.begin(); actualName != stateNamesCache_.end(); ++actualName, ++expectedName ) { BOOST_REQUIRE( ( *actualName )[ 0 ] == *expectedName ); } } private: ////////////////////////////////////////////////////////////////////////// typedef std::map< state_base_type::id_type, std::string > StateNamesMap; typedef std::set< std::string > StateNamesCache; StateNamesMap stateNamesMap_; mutable StateNamesCache stateNamesCache_; }; struct C; struct D; struct B : sc::simple_state< B, StateIterationTest, mpl::list< C, D > > { typedef sc::transition< EvToA, A > reactions; }; struct A : sc::simple_state< A, StateIterationTest > { typedef sc::transition< EvToB, B > reactions; }; struct F; struct G; struct E : sc::simple_state< E, B::orthogonal< 1 >, mpl::list< F, G > > { typedef sc::transition< EvToD, D > reactions; }; struct F : sc::simple_state< F, E::orthogonal< 0 > > {}; struct G : sc::simple_state< G, E::orthogonal< 1 > > {}; struct C : sc::simple_state< C, B::orthogonal< 0 > > {}; struct D : sc::simple_state< D, B::orthogonal< 1 > > { typedef sc::transition< EvToE, E > reactions; }; StateIterationTest::StateIterationTest() { // We're not using custom type information to make this test work even when // BOOST_STATECHART_USE_NATIVE_RTTI is defined stateNamesMap_[ A::static_type() ] = "A"; stateNamesMap_[ B::static_type() ] = "B"; stateNamesMap_[ C::static_type() ] = "C"; stateNamesMap_[ D::static_type() ] = "D"; stateNamesMap_[ E::static_type() ] = "E"; stateNamesMap_[ F::static_type() ] = "F"; stateNamesMap_[ G::static_type() ] = "G"; } int test_main( int, char* [] ) { StateIterationTest machine; machine.AssertInState( "" ); machine.initiate(); machine.AssertInState( "A" ); machine.process_event( EvToB() ); machine.AssertInState( "CD" ); machine.process_event( EvToA() ); machine.AssertInState( "A" ); machine.process_event( EvToB() ); machine.AssertInState( "CD" ); machine.process_event( EvToE() ); machine.AssertInState( "CFG" ); machine.process_event( EvToD() ); machine.AssertInState( "CD" ); machine.process_event( EvToE() ); machine.AssertInState( "CFG" ); machine.process_event( EvToA() ); machine.AssertInState( "A" ); machine.terminate(); machine.AssertInState( "" ); return 0; }