00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef TJSTATE_H
00019 #define TJSTATE_H
00020
00021 #include <tjutils/tjutils.h>
00022 #include <tjutils/tjlabel.h>
00023 #include <tjutils/tjlog.h>
00024
00030
00031
00032 class StateComponent {
00033 public:
00034 static const char* get_compName();
00035 };
00036
00038
00039
00040 template <class T> class State : public Labeled {
00041
00042 public:
00043 typedef bool (T::* transition) ();
00044
00045 State(T* statemachine, const char* statelabel, State* prerequired_state, transition tr)
00046 : Labeled(statelabel), machine(statemachine), pre_state(prerequired_state), trans(tr) {
00047 Log<StateComponent> odinlog(this,"State()");
00048 }
00049
00050 bool obtain_state() {
00051 Log<StateComponent> odinlog(this,"obtain_state");
00052
00053
00054
00055 if(machine->current_state==this) return true;
00056
00057
00058 if(machine->direct_transition(this)) return true;
00059
00060
00061 if(pre_state) {
00062 if(!pre_state->obtain_state()) return false;
00063 }
00064
00065 bool result=(machine->*trans)();
00066 if(result) machine->current_state=this;
00067 return result;
00068 }
00069
00070 private:
00071 T* machine;
00072 State* pre_state;
00073 transition trans;
00074 };
00075
00077
00078 template <class T>
00079 struct DirectTransition {
00080
00081 DirectTransition(State<T>* init, State<T>* dest, typename State<T>::transition tr) : init_state(init), dest_state(dest), trans(tr) {
00082 Log<StateComponent> odinlog("DirectTransition","DirectTransition()");
00083 }
00084
00085 bool operator == (const DirectTransition<T>& dt) const {return init_state==dt.init_state && dest_state==dt.dest_state && trans==dt.trans;}
00086 bool operator != (const DirectTransition<T>& dt) const {return !(*this==dt);}
00087 bool operator < (const DirectTransition<T>& dt) const {return init_state<dt.init_state && dest_state<dt.dest_state;}
00088
00089 State<T>* init_state;
00090 State<T>* dest_state;
00091
00092 typename State<T>::transition trans;
00093
00094
00095 };
00096
00097
00099
00100
00101 template <class T>
00102 class StateMachine {
00103
00104 protected:
00105 StateMachine(State<T>* first_state) : current_state(first_state) {
00106 Log<StateComponent> odinlog("StateMachine","StateMachine()");
00107 }
00108
00109 const STD_string& get_current_state_label() const {return current_state->get_label();}
00110
00111 void register_direct_trans(State<T>* init, State<T>* dest, typename State<T>::transition tr) {
00112 direct_trans.push_back( DirectTransition<T>(init,dest,tr) );
00113 }
00114
00115 bool direct_transition(State<T>* dest) {
00116 typename STD_list<DirectTransition<T> >::iterator it;
00117 for(it=direct_trans.begin(); it!=direct_trans.end(); ++it) {
00118 if( (it->init_state==current_state) && (it->dest_state==dest) ) {
00119 typename State<T>::transition tt=it->trans;
00120 bool result=((T*)(this)->*tt)();
00121 if(result) current_state=dest;
00122 return result;
00123 }
00124 }
00125 return false;
00126 }
00127
00128 private:
00129 friend class State<T>;
00130
00131 STD_list<DirectTransition<T> > direct_trans;
00132
00133 State<T>* current_state;
00134 };
00135
00136
00139 #endif