123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #ifndef STATE_MACHINE_H
- #define STATE_MACHINE_H
- #ifndef _SIMBASE_H_
- #include "console/simBase.h"
- #endif
- #ifndef _OBJECTTYPES_H_
- #include "T3D/objectTypes.h"
- #endif
- #ifndef _MMATH_H_
- #include "math/mMath.h"
- #endif
- #ifndef _XMLDOC_H_
- #include "console/SimXMLDocument.h"
- #endif
- class StateMachine
- {
- public:
- struct StateField
- {
- StringTableEntry name;
-
- bool triggerBoolVal;
- float triggerNumVal;
- Point3F triggerVectorVal;
- String triggerStringVal;
- enum Type
- {
- BooleanType = 0,
- NumberType,
- VectorType,
- StringType
- }fieldType;
- };
- struct UniqueReference
- {
- SimObject* referenceObj;
- const char* referenceVar;
- const char* uniqueName;
- };
- struct StateTransition
- {
- struct Condition
- {
- enum TriggerValueTarget
- {
- Equals = 0,
- GeaterThan,
- LessThan,
- GreaterOrEqual,
- LessOrEqual,
- True,
- False,
- Positive,
- Negative,
- DoesNotEqual
- };
- StateField field;
- TriggerValueTarget triggerComparitor;
- UniqueReference *valUniqueRef;
- };
- StringTableEntry mName;
- StringTableEntry mStateTarget;
- Vector<Condition> mTransitionRules;
- };
- struct State
- {
- Vector<StateTransition> mTransitions;
- StringTableEntry stateName;
- StringTableEntry callbackName;
- };
- StringTableEntry mStateMachineFile;
- protected:
- Vector<State> mStates;
- Vector<StateField> mFields;
- Vector<UniqueReference> mUniqueReferences;
- State mCurrentState;
- F32 mStateStartTime;
- F32 mStateTime;
- StringTableEntry mStartingState;
- State *mCurCreateSuperState;
- State *mCurCreateState;
- SimObjectPtr<SimXMLDocument> mXMLReader;
- public:
- StateMachine();
- virtual ~StateMachine();
- void update();
- void loadStateMachineFile();
- void readStates();
- void readTransitions(State ¤tState);
- void readConditions(StateTransition &newTransition);
- void setState(const char* stateName, bool clearFields = true);
- const char* getCurrentStateName() { return mCurrentState.stateName; }
- State& getCurrentState() {
- return mCurrentState;
- }
- S32 getStateCount() { return mStates.size(); }
- const char* getStateByIndex(S32 index);
- State& getStateByName(const char* name);
- void checkTransitions(const char* slotName, const char* newValue);
- bool passComparitorCheck(const char* var, StateTransition::Condition transitionRule);
- S32 findFieldByName(const char* name);
- S32 getFieldsCount() { return mFields.size(); }
- StateField getField(U32 index)
- {
- if (index <= mFields.size())
- return mFields[index];
- }
- Signal< void(StateMachine*, S32 stateIdx) > StateMachine::onStateChanged;
- //
- inline bool readStateName(State* state, SimXMLDocument* reader)
- {
- if (reader->pushFirstChildElement("Name"))
- {
- state->stateName = reader->getData();
- reader->popElement();
- return true;
- }
- return false;
- }
- inline bool readStateScriptFunction(State* state, SimXMLDocument* reader)
- {
- if (reader->pushFirstChildElement("ScriptFunction"))
- {
- state->callbackName = reader->getData();
- reader->popElement();
- return true;
- }
- return false;
- }
- inline bool readTransitonTarget(StateTransition* transition, SimXMLDocument* reader)
- {
- if (reader->pushFirstChildElement("StateTarget"))
- {
- transition->mStateTarget = reader->getData();
- reader->popElement();
- return true;
- }
- return false;
- }
- //
- inline bool readFieldName(StateField* newField, SimXMLDocument* reader)
- {
- if (reader->pushFirstChildElement("FieldName"))
- {
- newField->name = reader->getData();
- reader->popElement();
- return true;
- }
- return false;
- }
- inline bool readFieldComparitor(StateTransition::Condition* condition, SimXMLDocument* reader)
- {
- if (reader->pushFirstChildElement("Comparitor"))
- {
- S32 compIdx = parseComparitor(reader->getData());
- condition->triggerComparitor = static_cast<StateTransition::Condition::TriggerValueTarget>(compIdx);
- reader->popElement();
- return true;
- }
- return false;
- }
- inline bool readFieldValue(StateField* field, SimXMLDocument* reader)
- {
- if (reader->pushFirstChildElement("NumValue"))
- {
- field->fieldType = StateField::NumberType;
- field->triggerNumVal = dAtof(reader->getData());
- reader->popElement();
- return true;
- }
- else if (reader->pushFirstChildElement("StringValue"))
- {
- field->fieldType = StateField::StringType;
- field->triggerStringVal = reader->getData();
- reader->popElement();
- return true;
- }
- else if (reader->pushFirstChildElement("BoolValue"))
- {
- field->fieldType = StateField::BooleanType;
- field->triggerBoolVal = dAtob(reader->getData());
- reader->popElement();
- return true;
- }
- return false;
- }
- private:
- S32 parseComparitor(const char* comparitorName);
- };
- #endif
|