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