00001
00032 #ifndef LL_LLSTATEMACHINE_H
00033 #define LL_LLSTATEMACHINE_H
00034
00035 #include <string>
00036
00037 #include "llassoclist.h"
00038 #include "llerror.h"
00039 #include <map>
00040
00041 class LLUniqueID
00042 {
00043 friend bool operator==(const LLUniqueID &a, const LLUniqueID &b);
00044 friend bool operator!=(const LLUniqueID &a, const LLUniqueID &b);
00045 protected:
00046 static U32 sNextID;
00047 U32 mId;
00048 public:
00049 LLUniqueID(){mId = sNextID++;}
00050 virtual ~LLUniqueID(){}
00051 U32 getID() {return mId;}
00052 };
00053
00054 class LLFSMTransition : public LLUniqueID
00055 {
00056 public:
00057 LLFSMTransition() : LLUniqueID(){};
00058 virtual std::string getName(){ return "unnamed"; }
00059 };
00060
00061 class LLFSMState : public LLUniqueID
00062 {
00063 public:
00064 LLFSMState() : LLUniqueID(){};
00065 virtual void onEntry(void *){};
00066 virtual void onExit(void *){};
00067 virtual void execute(void *){};
00068 virtual std::string getName(){ return "unnamed"; }
00069 };
00070
00071 class LLStateDiagram
00072 {
00073 typedef std::map<LLFSMTransition*, LLFSMState*> Transitions;
00074
00075 friend std::ostream& operator<<(std::ostream &s, LLStateDiagram &FSM);
00076 friend class LLStateMachine;
00077
00078 protected:
00079 typedef std::map<LLFSMState*, Transitions> StateMap;
00080 StateMap mStates;
00081 Transitions mDefaultTransitions;
00082 LLFSMState* mDefaultState;
00083 BOOL mUseDefaultState;
00084
00085 public:
00086 LLStateDiagram();
00087 virtual ~LLStateDiagram();
00088
00089 protected:
00090
00091 BOOL addState(LLFSMState *state);
00092
00093
00094 BOOL addTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition);
00095
00096
00097 BOOL addUndirectedTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition);
00098
00099
00100 void addDefaultTransition(LLFSMState& end_state, LLFSMTransition& transition);
00101
00102
00103 LLFSMState* processTransition(LLFSMState& start_state, LLFSMTransition& transition);
00104
00105
00106 void setDefaultState(LLFSMState& default_state);
00107
00108
00109 S32 numDeadendStates();
00110
00111
00112 BOOL stateIsValid(LLFSMState& state);
00113
00114
00115 LLFSMState* getState(U32 state_id);
00116
00117 public:
00118
00119 BOOL saveDotFile(const char* filename);
00120 };
00121
00122 class LLStateMachine
00123 {
00124 protected:
00125 LLFSMState* mCurrentState;
00126 LLFSMState* mLastState;
00127 LLFSMTransition* mLastTransition;
00128 LLStateDiagram* mStateDiagram;
00129
00130 public:
00131 LLStateMachine();
00132 virtual ~LLStateMachine();
00133
00134
00135 void setStateDiagram(LLStateDiagram* diagram);
00136
00137
00138 void processTransition(LLFSMTransition &transition, void* user_data);
00139
00140
00141 LLFSMState* getCurrentState() const;
00142
00143
00144 void runCurrentState(void *data);
00145
00146
00147 BOOL setCurrentState(LLFSMState *initial_state, void* user_data, BOOL skip_entry = TRUE);
00148
00149
00150 BOOL setCurrentState(U32 state_id, void* user_data, BOOL skip_entry = TRUE);
00151 };
00152
00153 #endif //_LL_LLSTATEMACHINE_H