stateMachine.h
Engine/source/T3D/components/game/stateMachine.h
Classes:
class
class
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#ifndef STATE_MACHINE_H 25#define STATE_MACHINE_H 26 27#ifndef _SIMBASE_H_ 28#include "console/simBase.h" 29#endif 30#ifndef _OBJECTTYPES_H_ 31#include "T3D/objectTypes.h" 32#endif 33#ifndef _MMATH_H_ 34#include "math/mMath.h" 35#endif 36#ifndef _XMLDOC_H_ 37#include "console/SimXMLDocument.h" 38#endif 39 40class StateMachine 41{ 42public: 43 struct StateField 44 { 45 StringTableEntry name; 46 47 bool triggerBoolVal; 48 float triggerNumVal; 49 Point3F triggerVectorVal; 50 String triggerStringVal; 51 52 enum Type 53 { 54 BooleanType = 0, 55 NumberType, 56 VectorType, 57 StringType 58 }fieldType; 59 }; 60 61 struct UniqueReference 62 { 63 SimObject* referenceObj; 64 const char* referenceVar; 65 const char* uniqueName; 66 }; 67 68 struct StateTransition 69 { 70 struct Condition 71 { 72 enum TriggerValueTarget 73 { 74 Equals = 0, 75 GeaterThan, 76 LessThan, 77 GreaterOrEqual, 78 LessOrEqual, 79 True, 80 False, 81 Positive, 82 Negative, 83 DoesNotEqual 84 }; 85 86 StateField field; 87 88 TriggerValueTarget triggerComparitor; 89 90 UniqueReference *valUniqueRef; 91 }; 92 93 StringTableEntry mName; 94 StringTableEntry mStateTarget; 95 Vector<Condition> mTransitionRules; 96 }; 97 98 struct State 99 { 100 Vector<StateTransition> mTransitions; 101 102 StringTableEntry stateName; 103 104 StringTableEntry callbackName; 105 }; 106 107 StringTableEntry mStateMachineFile; 108 109protected: 110 Vector<State> mStates; 111 112 Vector<StateField> mFields; 113 114 Vector<UniqueReference> mUniqueReferences; 115 116 State mCurrentState; 117 118 F32 mStateStartTime; 119 F32 mStateTime; 120 121 StringTableEntry mStartingState; 122 123 State *mCurCreateSuperState; 124 State *mCurCreateState; 125 126 SimObjectPtr<SimXMLDocument> mXMLReader; 127 128public: 129 StateMachine(); 130 virtual ~StateMachine(); 131 132 void update(); 133 134 void loadStateMachineFile(); 135 void readStates(); 136 void readTransitions(State ¤tState); 137 void readConditions(StateTransition &newTransition); 138 139 void setState(const char* stateName, bool clearFields = true); 140 141 const char* getCurrentStateName() { return mCurrentState.stateName; } 142 State& getCurrentState() { 143 return mCurrentState; 144 } 145 146 S32 getStateCount() { return mStates.size(); } 147 const char* getStateByIndex(S32 index); 148 State& getStateByName(const char* name); 149 150 void checkTransitions(const char* slotName, const char* newValue); 151 152 bool passComparitorCheck(const char* var, StateTransition::Condition transitionRule); 153 154 S32 findFieldByName(const char* name); 155 156 S32 getFieldsCount() { return mFields.size(); } 157 158 StateField getField(U32 index) 159 { 160 if (index <= mFields.size()) 161 return mFields[index]; 162 } 163 164 Signal< void(StateMachine*, S32 stateIdx) > onStateChanged; 165 166 // 167 inline bool readStateName(State* state, SimXMLDocument* reader) 168 { 169 if (reader->pushFirstChildElement("Name")) 170 { 171 state->stateName = reader->getData(); 172 reader->popElement(); 173 174 return true; 175 } 176 177 return false; 178 } 179 inline bool readStateScriptFunction(State* state, SimXMLDocument* reader) 180 { 181 if (reader->pushFirstChildElement("ScriptFunction")) 182 { 183 state->callbackName = reader->getData(); 184 reader->popElement(); 185 186 return true; 187 } 188 189 return false; 190 } 191 inline bool readTransitonTarget(StateTransition* transition, SimXMLDocument* reader) 192 { 193 if (reader->pushFirstChildElement("StateTarget")) 194 { 195 transition->mStateTarget = reader->getData(); 196 reader->popElement(); 197 198 return true; 199 } 200 201 return false; 202 } 203 // 204 inline bool readFieldName(StateField* newField, SimXMLDocument* reader) 205 { 206 if (reader->pushFirstChildElement("FieldName")) 207 { 208 newField->name = reader->getData(); 209 reader->popElement(); 210 211 return true; 212 } 213 214 return false; 215 } 216 inline bool readFieldComparitor(StateTransition::Condition* condition, SimXMLDocument* reader) 217 { 218 if (reader->pushFirstChildElement("Comparitor")) 219 { 220 S32 compIdx = parseComparitor(reader->getData()); 221 condition->triggerComparitor = static_cast<StateTransition::Condition::TriggerValueTarget>(compIdx); 222 reader->popElement(); 223 224 return true; 225 } 226 227 return false; 228 } 229 inline bool readFieldValue(StateField* field, SimXMLDocument* reader) 230 { 231 if (reader->pushFirstChildElement("NumValue")) 232 { 233 field->fieldType = StateField::NumberType; 234 field->triggerNumVal = dAtof(reader->getData()); 235 reader->popElement(); 236 return true; 237 } 238 else if (reader->pushFirstChildElement("StringValue")) 239 { 240 field->fieldType = StateField::StringType; 241 field->triggerStringVal = reader->getData(); 242 reader->popElement(); 243 return true; 244 } 245 else if (reader->pushFirstChildElement("BoolValue")) 246 { 247 field->fieldType = StateField::BooleanType; 248 field->triggerBoolVal = dAtob(reader->getData()); 249 reader->popElement(); 250 return true; 251 } 252 253 return false; 254 } 255 256private: 257 S32 parseComparitor(const char* comparitorName); 258}; 259 260#endif 261
