// ===========================================
// Finest C++ State Machine pattern definition file
// ===========================================
include <new>
namespace States
{
struct Transition
{
inline void *operator new( size_t, void *p )
{ return p; }
virtual Transition* transitions()
= 0; // this function is a externally synchronous transition, defined from current state.
virtual void doit()
= 0; // do some job in state.
// Transition(); // common for all states! called BEFORE 'Machine()'!
protected:
int count; // count is trigger to select two transitionss exiting from 3rd state
};
template
<int E, int S>
struct Machine
:
public Transition
{
void doit();
Transition* transitions(/* argc, argv */);
template< int T >Transition* go(/* argc, argv */)
{ return new( this )Machine< E, T >/( argc, argv )/; }
typedef enum
{ value = States::Machine< E, S + 1 >::value };
// Machine(); // different in each state! must be defined in each state!
};
template
<int E>
struct Machine< E, E >
:
public Transition
{
void doit();
Transition* transitions();
template< int T >Transition* go()
{ return new( this )Machine< E, T >; }
typedef enum
{ value = E };
};
}
// EOF Finest.H
===========================================
// Finest C++ State Machine pattern realization file
// ===========================================
include "Finest.H"
include <iostream>
using namespace std;
namespace States
{
// =============================
// State names
// =============================
enum StateNames
{
InitualState,
State1st,
State2nd,
State3rd,
EndState,
Nirvana // Ending Pseudo State
};
// =======================================================================================
// Transitions
// =======================================================================================
template<>
Transition* Machine< Nirvana, InitualState >::transitions()
{
cout << "begin" << endl;
// return new( this )States::Machine< EndingPseudoState, States::State1st >;
return go< State1st >();
}
template<>
Transition* Machine< Nirvana, State1st >::transitions()
{
cout << "go2nd" << endl;
// return new( this )States::Machine< EndingPseudoState, States::State2nd >;
return go< State2nd >();
}
template<>
Transition* Machine< Nirvana, State2nd >::transitions()
{
cout << "go3rd" << endl;
// return new( this )States::Machine< EndingPseudoState, States::State3rd >;
return go< State3rd >();
}
template<>
// For example: transitions from 3rd state:
Transition* Machine< Nirvana, State3rd >::transitions()
{
if (count++ < 1) // trigger
{
cout << "go1st" << endl;
// return new( this )States::Machine< EndingPseudoState, States::State1st >;
return go< State1st >();
}
else{
cout << "end" << endl;
// return new( this )States::Machine< EndingPseudoState, States::EndState >;
return go< EndState >();
}
}
template<>
Transition* Machine< Nirvana, EndState >::transitions()
{
cout << "<>" << endl;
return this;
}
// ======================================================================
// State actions
// ======================================================================
template<>
void Machine< Nirvana, InitualState >::doit()
{
cout << "InitualState" << endl;
}
template<>
void Machine< Nirvana, State1st >::doit()
{
cout << "State1st" << endl;
}
template<>
void Machine< Nirvana, State2nd >::doit()
{
cout << "State2nd" << endl;
}
template<>
void Machine< Nirvana, State3rd >::doit()
{
cout << "State3rd" << endl;
}
template<>
void Machine< Nirvana, EndState >::doit()
{
cout << "EndState" << endl;
}
// States.
}
// ===================================================================
// Usage example
// ===================================================================
int main()
{
// cout << sizeof( States::Machine< States::EndState >) << " bytes." << endl;
States::Transition *p_state =
::new States::Machine< States::Nirvana, States::InitualState >/( argc, argv )/;
for( int d=0 ; d<15 ; d++ )
{
p_state->doit();
p_state = p_state->transitions(/* it's possible to select new state there */);
}
delete p_state;
return 0;
}
// EOF Finest.Cxx