00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef FSMTEMPLATE_H
00025 #define FSMTEMPLATE_H
00026
00027 #include <vector>
00028 #include <algorithm>
00029 #include <stdexcept>
00030 #include <deque>
00031 #include <string>
00032 #include <functional>
00033 #include <iterator>
00034 #include <iostream>
00035 #include <boost/function.hpp>
00036
00037
00038
00039
00045 #define FSM_BEGIN( StartFSMState ) (StartFSMState), \
00046 FSM::SStateMachineProxy<FSMStateType, \
00047 FSMEventType> \
00048 () << ( \
00049 FSM::SStatesListProxy<FSMStateType>() <<
00050
00051
00056 #define FSM_STATES
00057
00058
00064 #define FSM_EVENT( Arg ) ) \
00065 << (FSM::STransitionsProxy<FSMStateType, \
00066 FSMEventType> \
00067 ( Arg ) <<
00068
00069
00074 #define FSM_END )
00075
00076
00081 #define FSM_RESET FSM::ResetMachine
00082
00083
00084
00085
00091 #define FUNCFSM_BEGIN( StartFSMState ) (StartFSMState), \
00092 FSM::SFuncStateMachineProxy<FSMStateType, \
00093 FSMEventType> \
00094 () << ( \
00095 FSM::SStatesListProxy<FSMStateType>() <<
00096
00097
00102 #define FUNCFSM_STATES
00103
00104
00110 #define FUNCFSM_EVENT( Arg ) ) \
00111 << (FSM::SFuncTransitionsProxy<FSMStateType, \
00112 FSMEventType> \
00113 ( Arg ) <<
00114
00115
00120 #define FUNCFSM_END )
00121
00122
00126 #define FUNCFSM_RESET FSM::ResetMachine
00127
00128
00129
00130
00134 namespace FSM
00135 {
00136
00138 enum SMachineManipulator
00139 {
00140 ResetMachine = 0
00141 };
00142
00143
00145 enum STransitionManipulator
00146 {
00147 NONE = 0,
00148 EXCEPTION = 1
00149 };
00150
00151
00153 class SStateMachineException : public std::exception
00154 {
00155 private:
00156 const std::string Message;
00157
00158 public:
00161 SStateMachineException( const std::string & Msg ) : Message( Msg )
00162 {}
00163
00166 SStateMachineException( const char * Msg ) : Message( Msg )
00167 {}
00168
00171 virtual const char * what( void ) const throw()
00172 { return Message.c_str(); }
00173
00175 virtual ~SStateMachineException() throw () {}
00176
00177 private:
00178 SStateMachineException();
00179 };
00180
00181
00187 template < typename SState, typename SEvent >
00188 class SEmptyFunctor
00189 {
00190 public:
00192 void operator() ( const SState &,
00193 const SEvent &,
00194 const SState & )
00195 { return; }
00196 };
00197
00198
00204 template < typename SState, typename SEvent >
00205 class SOnEnterFunctor
00206 {
00207 public:
00213 void operator() ( SState & From,
00214 const SEvent & Event,
00215 SState & To )
00216 { To.OnEnter( From, Event ); }
00217 };
00218
00219
00225 template < typename SState, typename SEvent >
00226 class SOnExitFunctor
00227 {
00228 public:
00234 void operator() ( SState & From,
00235 const SEvent & Event,
00236 SState & To )
00237 { From.OnExit( Event, To ); }
00238 };
00239
00240
00246 template < typename SState, typename SEvent >
00247 class SOnMoveFunctor
00248 {
00249 public:
00256 void operator() ( SState & From,
00257 const SEvent & Event,
00258 SState & To )
00259 {
00260 const SState & FromConst( From );
00261 const SState & ToConst( To );
00262
00263 From.OnExit( Event, ToConst );
00264 To.OnEnter( FromConst, Event );
00265 }
00266 };
00267
00268
00273 template < typename SEvent >
00274 class SThrowStrategy
00275 {
00276 public:
00281 void operator() ( const SEvent & ) const
00282 { throw SStateMachineException( "Unknown event." ); }
00283 };
00284
00285
00290 template < typename SEvent >
00291 class SIgnoreStrategy
00292 {
00293 public:
00295 void operator() ( const SEvent & ) const
00296 { return; }
00297 };
00298
00299
00300
00302
00303
00304
00305
00306 template < typename SState >
00307 class SStatesListProxy
00308 {
00309 private:
00310 std::vector<SState> StatesProxy;
00311
00312 public:
00313 SStatesListProxy() { return; }
00314
00315 SStatesListProxy & operator << ( const SState & TheState )
00316 {
00317
00318 if ( std::find( StatesProxy.begin(),
00319 StatesProxy.end(),
00320 TheState ) != StatesProxy.end() )
00321 {
00322 throw SStateMachineException( "States must be unique." );
00323 }
00324 StatesProxy.push_back( TheState );
00325 return *this;
00326 }
00327
00328 const std::vector<SState> & GetStates( void ) const
00329 { return StatesProxy; }
00330 };
00331
00332
00334
00335
00337
00338
00339
00340
00341 template < typename SState, typename SEvent >
00342 class STransitionsProxy
00343 {
00344 private:
00345 SEvent Event;
00346 std::vector<SState> NewStates;
00347 std::vector< int > Manipulators;
00348
00349 public:
00350 explicit STransitionsProxy( const SEvent & TheEvent ) :
00351 Event( TheEvent )
00352 { return; }
00353
00354 STransitionsProxy & operator << ( const SState & TheState )
00355 {
00356 NewStates.push_back( TheState );
00357 Manipulators.push_back( -1 );
00358 return *this;
00359 }
00360
00361 STransitionsProxy & operator << ( const STransitionManipulator & Manipulator )
00362 {
00363 NewStates.push_back( SState() );
00364 Manipulators.push_back( Manipulator );
00365 return *this;
00366 }
00367
00368 const std::vector<SState> & GetStates( void ) const
00369 { return NewStates; }
00370
00371 const std::vector<int> & GetManipulators( void ) const
00372 { return Manipulators; }
00373
00374 const SEvent & GetEvent( void ) const
00375 { return Event; }
00376
00377 private:
00378 STransitionsProxy();
00379 };
00380
00382
00383
00384
00386
00387
00388
00389
00390 template < typename SState, typename SEvent >
00391 class SStateMachineProxy
00392 {
00393 typedef SState StateType;
00394 typedef SEvent EventType;
00395 typedef std::vector<StateType> SStatesList;
00396 typedef std::vector<EventType> SEventsList;
00397
00398 typedef std::vector< int > SManipulatorsList;
00399
00400 private:
00401 SStatesList MachineStatesProxy;
00402 bool HaveStates;
00403 SEventsList MachineEventsProxy;
00404 std::vector<SStatesList> Transitions;
00405 std::vector<SManipulatorsList> TransitionsManipulators;
00406
00407 public:
00408 SStateMachineProxy() : HaveStates( false )
00409 { return; }
00410
00411 SStateMachineProxy & operator <<
00412 ( const SStatesListProxy<SState> & TheStates )
00413 {
00414 if ( HaveStates )
00415 {
00416 throw SStateMachineException( "Too much state lists." );
00417 }
00418 HaveStates = true;
00419 MachineStatesProxy = TheStates.GetStates();
00420 return *this;
00421 }
00422
00423 SStateMachineProxy & operator <<
00424 ( const STransitionsProxy<SState,SEvent> & TheTransitions )
00425 {
00426 if ( !HaveStates )
00427 {
00428 throw SStateMachineException( "States must be defined "
00429 "before the transitions." );
00430 }
00431
00432 if ( MachineStatesProxy.size() !=
00433 TheTransitions.GetStates().size() )
00434 {
00435 throw SStateMachineException( "Transition states do not "
00436 "coincide to the states list." );
00437 }
00438
00439
00440 if ( std::find( MachineEventsProxy.begin(),
00441 MachineEventsProxy.end(),
00442 TheTransitions.GetEvent() )
00443 != MachineEventsProxy.end() )
00444 {
00445 throw SStateMachineException( "Events must be unique." );
00446 }
00447
00448
00449 CheckTransitionValidity( TheTransitions.GetStates().begin(),
00450 TheTransitions.GetStates().end(),
00451 TheTransitions.GetManipulators().begin(),
00452 TheTransitions.GetManipulators().begin() );
00453
00454 MachineEventsProxy.push_back( TheTransitions.GetEvent() );
00455 Transitions.push_back( TheTransitions.GetStates() );
00456 TransitionsManipulators.push_back( TheTransitions.GetManipulators() );
00457 return *this;
00458 }
00459
00460
00461
00462
00463
00464 void CheckTransitionValidity(
00465 typename SStatesList::const_iterator First,
00466 typename SStatesList::const_iterator Last,
00467 std::vector<int>::const_iterator ManipulatorFirst,
00468 std::vector<int>::const_iterator ManipulatorLast )
00469 {
00470 for ( ; First != Last; ++First, ++ManipulatorFirst )
00471 {
00472 if ( *ManipulatorFirst == -1 )
00473 {
00474 if ( std::find( MachineStatesProxy.begin(),
00475 MachineStatesProxy.end(), *First )
00476 == MachineStatesProxy.end() )
00477 {
00478 throw SStateMachineException( "Transition state "
00479 "is not valid." );
00480 }
00481 }
00482 }
00483 }
00484
00485 const SStatesList & GetStates( void ) const
00486 { return MachineStatesProxy; }
00487
00488 const std::vector<SStatesList> & GetTransitions( void ) const
00489 { return Transitions; }
00490
00491 const std::vector<SManipulatorsList> & GetManipulators( void ) const
00492 { return TransitionsManipulators; }
00493
00494 const SEventsList & GetEvents( void ) const
00495 { return MachineEventsProxy; }
00496 };
00497
00499
00500
00501
00511 template < typename SState,
00512 typename SEvent,
00513 typename SFunctor = SEmptyFunctor<SState,SEvent>,
00514 typename SUnknownEventStrategy = SThrowStrategy<SEvent> >
00515 class SStateMachine
00516 {
00517 public:
00519 typedef SState StateType;
00520 typedef SEvent EventType;
00521 typedef std::vector<StateType> SStatesList;
00522 typedef std::vector<EventType> SEventsList;
00523 typedef std::vector<SStatesList> TransitionsType;
00524 typedef std::deque<EventType> EventsQueueType;
00525 typedef std::vector<int> ManipulatorsList;
00526 typedef std::vector<ManipulatorsList> ManipulatorsType;
00528
00529 private:
00530 StateType CurrentState;
00531 SStatesList States;
00532 SEventsList Events;
00533 TransitionsType Transitions;
00534 ManipulatorsType Manipulators;
00535 SFunctor Functor;
00536 SUnknownEventStrategy UnknownEventStrategy;
00537 EventsQueueType EventsQueue;
00538
00539
00540 bool InProcess;
00541 int CurrentStateIndex;
00542
00543 StateType InitialState;
00544
00545 public:
00553 SStateMachine( const StateType & StartState,
00554 const SStateMachineProxy<StateType,
00555 EventType> & ProxyMachine ) :
00556 CurrentState( StartState ),
00557 States( ProxyMachine.GetStates() ),
00558 Events( ProxyMachine.GetEvents() ),
00559 Transitions( ProxyMachine.GetTransitions() ),
00560 Manipulators( ProxyMachine.GetManipulators() ),
00561 InProcess( false ),
00562 CurrentStateIndex( -1 ),
00563 InitialState( StartState )
00564 {
00565
00566 typename SStatesList::iterator k( std::find( States.begin(),
00567 States.end(),
00568 StartState ) );
00569 if ( k == States.end() )
00570 {
00571 throw SStateMachineException( "Start state is invalid." );
00572 }
00573 CurrentStateIndex = std::distance( States.begin(), k );
00574 }
00575
00576
00581 SStateMachine & Reset( void )
00582 {
00583 CurrentState = InitialState;
00584 CurrentStateIndex = GetStateIndex( CurrentState );
00585 InProcess = false;
00586 EventsQueue.clear();
00587 return *this;
00588 }
00589
00590
00594 StateType GetCurrentState( void ) const
00595 { return CurrentState; }
00596
00597
00598
00606 SStateMachine & AcceptEvent( const EventType & Event )
00607 {
00608 EventsQueue.push_back( Event );
00609 if ( InProcess ) return *this;
00610 InProcess = true;
00611 while ( !EventsQueue.empty() )
00612 {
00613 ProcessEvent( EventsQueue.front() );
00614 EventsQueue.pop_front();
00615 }
00616 InProcess = false;
00617 return *this;
00618 }
00619
00620
00628 SStateMachine & operator << ( const EventType & Event )
00629 { return AcceptEvent( Event ); }
00630
00631
00636 SStateMachine & operator << ( SMachineManipulator Manipulator )
00637 {
00638 if ( Manipulator != ResetMachine )
00639 {
00640 Reset();
00641 throw SStateMachineException( "Unknown manipulator. Machine is reset." );
00642 }
00643 return Reset();
00644 }
00645
00646 private:
00647 void ProcessEvent( const EventType & Event )
00648 {
00649 try
00650 {
00651 int EventIndex( GetEventIndex( Event ) );
00652 if ( EventIndex == -1 ) return;
00653
00654 StateType OldState( CurrentState );
00655
00656 if ( (Manipulators[EventIndex])[CurrentStateIndex] == EXCEPTION )
00657 {
00658 throw SStateMachineException( "Transition is forbidden. Machine is reset." );
00659 }
00660
00661 if ( (Manipulators[EventIndex])[CurrentStateIndex] == NONE )
00662 {
00663 return;
00664 }
00665
00666 CurrentState = (Transitions[EventIndex])[CurrentStateIndex];
00667 CurrentStateIndex = GetStateIndex( CurrentState );
00668
00669 Functor( OldState, Event, CurrentState );
00670 }
00671 catch ( ... )
00672 {
00673 Reset();
00674 throw;
00675 }
00676 }
00677
00678 int GetEventIndex( const EventType & Event ) const
00679 {
00680 typename SEventsList::const_iterator k( std::find( Events.begin(),
00681 Events.end(),
00682 Event ) );
00683 if ( k == Events.end() )
00684 {
00685 UnknownEventStrategy( Event );
00686 return -1;
00687 }
00688 return std::distance( Events.begin(), k );
00689 }
00690
00691 int GetStateIndex( const StateType & State ) const
00692 {
00693 return std::distance( States.begin(),
00694 std::find( States.begin(),
00695 States.end(),
00696 State ) );
00697 }
00698
00699 private:
00700
00701
00702
00703 SStateMachine();
00704 SStateMachine & operator= ( const SStateMachine & );
00705 SStateMachine( const SStateMachine & );
00706 };
00707
00708
00709
00715 template < typename SState,
00716 typename SEvent,
00717 typename SFunctor,
00718 typename SUnknownEventStrategy >
00719 std::ostream & operator << (std::ostream & Stream,
00720 const SStateMachine<SState,
00721 SEvent,
00722 SFunctor,
00723 SUnknownEventStrategy> & Machine )
00724 { return Stream << Machine.GetCurrentState(); }
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00739 template < typename Child,
00740 typename Event >
00741 class StateBase
00742 {
00743
00744
00745 typedef boost::function< void ( Child &,
00746 Event &,
00747 Child & ) > CallbackType;
00748
00749 private:
00750 CallbackType Callback;
00751
00752 protected:
00753 StateBase() : Callback( 0 ) {}
00754
00755 public:
00760 Child & operator [] ( const CallbackType & NewCallback )
00761 {
00762 Callback = NewCallback;
00763 return static_cast< Child & >( *this );
00764 }
00765
00770 CallbackType GetCallback( void )
00771 {
00772 CallbackType Temporary( Callback );
00773
00774 Callback = 0;
00775 return Temporary;
00776 }
00777 };
00778
00779
00781
00782
00783 template < typename SState, typename SEvent >
00784 struct SFuncBundle
00785 {
00786 SState NewState;
00787 int Manipulator;
00788 boost::function< void ( SState &,
00789 SEvent &,
00790 SState & ) > Callback;
00791
00792 SFuncBundle() {}
00793 };
00794
00796
00797
00798
00799
00800
00801
00802
00803
00804
00806
00807
00808
00809
00810 template < typename SState, typename SEvent >
00811 class SFuncTransitionsProxy
00812 {
00813 typedef SFuncBundle< SState, SEvent > Bundle;
00814
00815 private:
00816 SEvent Event;
00817 std::vector<Bundle> NewStates;
00818
00819 public:
00820 explicit SFuncTransitionsProxy( const SEvent & TheEvent ) :
00821 Event( TheEvent )
00822 { return; }
00823
00824 SFuncTransitionsProxy & operator << ( SState & TheState )
00825 {
00826 Bundle NewBundle;
00827
00828 NewBundle.NewState = TheState;
00829 NewBundle.Manipulator = -1;
00830 NewBundle.Callback = TheState.GetCallback();
00831
00832 NewStates.push_back( NewBundle );
00833 return *this;
00834 }
00835
00836 SFuncTransitionsProxy & operator << ( const STransitionManipulator & Manipulator )
00837 {
00838 Bundle NewBundle;
00839
00840 NewBundle.NewState = SState();
00841 NewBundle.Manipulator = Manipulator;
00842 NewBundle.Callback = 0;
00843
00844 NewStates.push_back( NewBundle );
00845 return *this;
00846 }
00847
00848 const std::vector<Bundle> & GetStates( void ) const
00849 { return NewStates; }
00850
00851 const SEvent & GetEvent( void ) const
00852 { return Event; }
00853
00854 private:
00855 SFuncTransitionsProxy();
00856 };
00857
00859
00860
00861
00863
00864
00865
00866
00867 template < typename SState, typename SEvent >
00868 class SFuncStateMachineProxy
00869 {
00870 typedef SFuncBundle< SState, SEvent > Bundle;
00871
00872 typedef SState StateType;
00873 typedef SEvent EventType;
00874 typedef std::vector<StateType> SStatesList;
00875 typedef std::vector<EventType> SEventsList;
00876 typedef std::vector< Bundle > SBundlesList;
00877
00878 private:
00879 SStatesList MachineStatesProxy;
00880 bool HaveStates;
00881 SEventsList MachineEventsProxy;
00882 std::vector<SBundlesList> Transitions;
00883
00884 public:
00885 SFuncStateMachineProxy() : HaveStates( false )
00886 { return; }
00887
00888 SFuncStateMachineProxy & operator <<
00889 ( const SStatesListProxy<SState> & TheStates )
00890 {
00891 if ( HaveStates )
00892 {
00893 throw SStateMachineException( "Too much state lists." );
00894 }
00895 HaveStates = true;
00896 MachineStatesProxy = TheStates.GetStates();
00897 return *this;
00898 }
00899
00900 SFuncStateMachineProxy & operator <<
00901 ( const SFuncTransitionsProxy<SState,SEvent> & TheTransitions )
00902 {
00903 if ( !HaveStates )
00904 {
00905 throw SStateMachineException( "States must be defined "
00906 "before the transitions." );
00907 }
00908
00909 if ( MachineStatesProxy.size() !=
00910 TheTransitions.GetStates().size() )
00911 {
00912 throw SStateMachineException( "Transition states do not "
00913 "coincide to the states list." );
00914 }
00915
00916
00917 if ( std::find( MachineEventsProxy.begin(),
00918 MachineEventsProxy.end(),
00919 TheTransitions.GetEvent() )
00920 != MachineEventsProxy.end() )
00921 {
00922 throw SStateMachineException( "Events must be unique." );
00923 }
00924
00925
00926 CheckTransitionValidity( TheTransitions.GetStates().begin(),
00927 TheTransitions.GetStates().end() );
00928
00929 MachineEventsProxy.push_back( TheTransitions.GetEvent() );
00930 Transitions.push_back( TheTransitions.GetStates() );
00931 return *this;
00932 }
00933
00934
00935
00936
00937
00938 void CheckTransitionValidity(
00939 typename std::vector<Bundle>::const_iterator First,
00940 typename std::vector<Bundle>::const_iterator Last )
00941 {
00942 for ( ; First != Last; ++First )
00943 {
00944 if ( First->Manipulator == -1 )
00945 {
00946 if ( std::find( MachineStatesProxy.begin(),
00947 MachineStatesProxy.end(), First->NewState )
00948 == MachineStatesProxy.end() )
00949 {
00950 throw SStateMachineException( "Transition state "
00951 "is not valid." );
00952 }
00953 }
00954 }
00955 }
00956
00957 const SStatesList & GetStates( void ) const
00958 { return MachineStatesProxy; }
00959
00960 const std::vector<SBundlesList> & GetTransitions( void ) const
00961 { return Transitions; }
00962
00963 const SEventsList & GetEvents( void ) const
00964 { return MachineEventsProxy; }
00965 };
00966
00968
00969
00970
00978 template < typename SState,
00979 typename SEvent,
00980 typename SUnknownEventStrategy = SThrowStrategy<SEvent> >
00981 class SFuncStateMachine
00982 {
00983 public:
00985 typedef SFuncBundle< SState, SEvent > Bundle;
00986
00987 typedef SState StateType;
00988 typedef SEvent EventType;
00989 typedef std::vector<StateType> SStatesList;
00990 typedef std::vector<EventType> SEventsList;
00991 typedef std::vector<SStatesList> TransitionsType;
00992 typedef std::deque<EventType> EventsQueueType;
00993 typedef std::vector< Bundle > SBundlesList;
00995
00996 private:
00997 StateType CurrentState;
00998 SStatesList States;
00999 SEventsList Events;
01000 std::vector<SBundlesList> Transitions;
01001 SUnknownEventStrategy UnknownEventStrategy;
01002 EventsQueueType EventsQueue;
01003
01004
01005 bool InProcess;
01006
01007 int CurrentStateIndex;
01008
01009 StateType InitialState;
01010
01011 public:
01018 SFuncStateMachine( const StateType & StartState,
01019 const SFuncStateMachineProxy<StateType,
01020 EventType> & ProxyMachine ) :
01021 CurrentState( StartState ),
01022 States( ProxyMachine.GetStates() ),
01023 Events( ProxyMachine.GetEvents() ),
01024 Transitions( ProxyMachine.GetTransitions() ),
01025 InProcess( false ),
01026 CurrentStateIndex( -1 ),
01027 InitialState( StartState )
01028 {
01029
01030 typename SStatesList::iterator k( std::find( States.begin(),
01031 States.end(),
01032 StartState ) );
01033 if ( k == States.end() )
01034 {
01035 throw SStateMachineException( "Start state is invalid." );
01036 }
01037 CurrentStateIndex = std::distance( States.begin(), k );
01038 }
01039
01040
01045 SFuncStateMachine & Reset( void )
01046 {
01047 CurrentState = InitialState;
01048 CurrentStateIndex = GetStateIndex( CurrentState );
01049 InProcess = false;
01050 EventsQueue.clear();
01051 return *this;
01052 }
01053
01054
01058 StateType GetCurrentState( void ) const
01059 { return CurrentState; }
01060
01061
01069 SFuncStateMachine & AcceptEvent( EventType & Event )
01070 {
01071 EventsQueue.push_back( Event );
01072 if ( InProcess ) return *this;
01073 InProcess = true;
01074 while ( !EventsQueue.empty() )
01075 {
01076 ProcessEvent( EventsQueue.front() );
01077 EventsQueue.pop_front();
01078 }
01079 InProcess = false;
01080 return *this;
01081 }
01082
01090 SFuncStateMachine & operator << ( EventType & Event )
01091 { return AcceptEvent( Event ); }
01092
01093
01098 SFuncStateMachine & operator << ( SMachineManipulator Manipulator )
01099 {
01100 if ( Manipulator != ResetMachine )
01101 {
01102 Reset();
01103 throw SStateMachineException( "Unknown manipulator. Machine is reset." );
01104 }
01105 return Reset();
01106 }
01107
01108 private:
01109 void ProcessEvent( EventType & Event )
01110 {
01111 try
01112 {
01113 int EventIndex( GetEventIndex( Event ) );
01114 if ( EventIndex == -1 ) return;
01115
01116 StateType OldState( CurrentState );
01117
01118 if ( Transitions[EventIndex][CurrentStateIndex].Manipulator == EXCEPTION )
01119 {
01120 throw SStateMachineException( "Transition is forbidden. Machine is reset." );
01121 }
01122
01123 if ( Transitions[EventIndex][CurrentStateIndex].Manipulator == NONE )
01124 {
01125 return;
01126 }
01127
01128 boost::function< void ( SState &, SEvent &, SState & ) >
01129 Functor( Transitions[EventIndex][CurrentStateIndex].Callback );
01130
01131 CurrentState = Transitions[EventIndex][CurrentStateIndex].NewState;
01132 CurrentStateIndex = GetStateIndex( CurrentState );
01133
01134 if ( Functor != 0 ) Functor( OldState, Event, CurrentState );
01135 }
01136 catch ( ... )
01137 {
01138 Reset();
01139 throw;
01140 }
01141 }
01142
01143
01144 int GetEventIndex( const EventType & Event ) const
01145 {
01146 typename SEventsList::const_iterator k( std::find( Events.begin(),
01147 Events.end(),
01148 Event ) );
01149 if ( k == Events.end() )
01150 {
01151 UnknownEventStrategy( Event );
01152 return -1;
01153 }
01154 return std::distance( Events.begin(), k );
01155 }
01156
01157 int GetStateIndex( const StateType & State ) const
01158 {
01159 return std::distance( States.begin(),
01160 std::find( States.begin(),
01161 States.end(),
01162 State ) );
01163 }
01164
01165 private:
01166
01167
01168
01169 SFuncStateMachine();
01170 SFuncStateMachine & operator= ( const SFuncStateMachine & );
01171 SFuncStateMachine( const SFuncStateMachine & );
01172 };
01173
01174
01179 template < typename SState,
01180 typename SEvent,
01181 typename SUnknownEventStrategy >
01182 std::ostream & operator << (std::ostream & Stream,
01183 const SFuncStateMachine<SState,
01184 SEvent,
01185 SUnknownEventStrategy> & Machine )
01186 { return Stream << Machine.GetCurrentState(); }
01187
01188
01189
01190 }
01191
01192 #endif
01193