diff options
Diffstat (limited to 'src/libjin/ai/state_machine.h')
-rw-r--r-- | src/libjin/ai/state_machine.h | 414 |
1 files changed, 414 insertions, 0 deletions
diff --git a/src/libjin/ai/state_machine.h b/src/libjin/ai/state_machine.h new file mode 100644 index 0000000..d70563d --- /dev/null +++ b/src/libjin/ai/state_machine.h @@ -0,0 +1,414 @@ +#ifndef __JE_STATE_MACHINE_H__ +#define __JE_STATE_MACHINE_H__ + +#include "../core/configuration.h" +#if defined(jin_ai) + +#include <map> +#include <vector> +#include <functional> + +#include "../common/temporary.h" +#include "../common/types.h" +#include "../common/object.h" + +namespace JinEngine +{ + namespace AI + { + + /// + /// A single layer statemachine. + /// + class StateMachine : public Object + { + public: + /// + /// + /// + enum ParameterExpression + { + INT_GREATER = 0x02, + INT_LESS = 0x04, + INT_EQUAL = 0x08, + + FLOAT_GREATER = 0x10, + FLOAT_LESS = 0x20, + FLOAT_EQUAL = 0x40, + + BOOL_IS = 0x80, + BOOL_NOT = 0x100, + }; + + private: + /// + /// + /// + enum ParameterType + { + Int, ///< A integer value. + Float, ///< A float value. + Bool, ///< A bool value. + Trigger ///< A trigger will be reset to false after activated. + }; + + /// + /// + /// + union ParameterValue + { + int _int; ///< 0 by default. + float _float; ///< 0 by default. + bool _bool; ///< false by default. + bool _trigger; ///< false by default. + }; + + /// + /// Traslation's condition. + /// + struct Condition + { + int parameter; + ParameterExpression expression; + ParameterType type; + ParameterValue value; + }; + + public: + /// + /// + /// + enum Mode + { + Iterative, ///< Process until reach condition failed.(May cause endless loop) + Stepwise ///< Process one state each update. + }; + + struct Conditions : Temporary + { + Conditions() + { + } + + Conditions(const Conditions& condition) + { + conditions = condition.conditions; + } + + void operator = (const Conditions& condition) + { + conditions = condition.conditions; + } + + inline Conditions& andi(int parameter, ParameterExpression expression, int value) + { + Condition condition; + condition.expression = expression; + condition.parameter = parameter; + condition.value._int = value; + condition.type = ParameterType::Int; + conditions.push_back(condition); + return *this; + } + + inline Conditions& andf(int parameter, ParameterExpression expression , float value) + { + Condition condition; + condition.expression = expression; + condition.parameter = parameter; + condition.value._int = value; + condition.type = ParameterType::Float; + conditions.push_back(condition); + return *this; + } + + inline Conditions& andb(int parameter, ParameterExpression expression, bool value) + { + Condition condition; + condition.expression = expression; + condition.parameter = parameter; + condition.value._int = value; + condition.type = ParameterType::Bool; + conditions.push_back(condition); + return *this; + } + + inline Conditions& andt(int parameter) + { + Condition condition; + condition.parameter = parameter; + condition.type = ParameterType::Trigger; + conditions.push_back(condition); + return *this; + } + + private: + friend class StateMachine; + std::vector<Condition> conditions; + }; + + /// + /// + /// + typedef std::function<void(void*)> StateChangeCallback; + + /// + /// + /// + typedef std::function<void(void*)> StateUpdateCallback; + + /// + /// + /// + typedef std::function<void(void*)> StateTranslateCallback; + + /// + /// + /// + typedef std::function<void(int, void*)> SingleStateCallback; + + /// + /// + /// + typedef std::function<void(int, const int, void*)> DoubleStateCallback; + + /// + /// State machine constructor. + /// + StateMachine(Mode mode = Mode::Stepwise, void* userdata = nullptr); + + /// + /// State machine destructor. + /// + ~StateMachine(); + + /// + /// + /// + void setMode(Mode mode); + + /// + /// Process current state.. + /// + void update(); + + /// + /// Get current state name. + /// + int getCurrentState(); + + /// + /// Add a integer parameter. + /// + void addParameteri(int name); + + /// + /// + /// + void addParameterf(int name); + + /// + /// + /// + void addParameterb(int name); + + /// + /// + /// + void addParametert(int name); + + /// + /// Add a state. + /// + void addState(int name); + + /// + /// + /// + void addTransition(int from, int to, const Conditions& conditions); + + /// + /// Set parameter value. + /// + void setParameteri(int name, int value); + + /// + /// Set parameter value. + /// + void setParameterf(int name, float value); + + /// + /// Set parameter value. + /// + void setParameterb(int name, bool value); + + /// + /// Set parameter value. + /// + void setParametert(int name); + + /// + /// Force change to state. + /// + void forceToState(int name); + + /// + /// + /// + void addEnterListener(int state, const StateChangeCallback& callback); + + /// + /// Call state update function. + /// + void addUpdateListener(int state, const StateUpdateCallback& callback); + + /// + /// + /// + void addExitListener(int state, const StateChangeCallback& callback); + + /// + /// + /// + void addTranslateListener(int from, int to, const StateChangeCallback& callback); + + /// + /// + /// + void setEnterListener(const SingleStateCallback& callback); + + /// + /// + /// + void setUpdateListener(const SingleStateCallback& callback); + + /// + /// + /// + void setExitListener(const SingleStateCallback& callback); + + /// + /// + /// + void setTranslateListener(const DoubleStateCallback& callback); + + private: + + /// + /// + /// + struct Parameter + { + ParameterType type; + ParameterValue value; + }; + + /// + /// Translate to another state. + /// + struct Transition + { + Conditions conditions; ///< Condition to active transition. + int state; ///< State to translate to. + }; + + /// + /// A single state. + /// + struct State + { + int name; ///< Name of state. + std::vector<Transition> transitions; ///< All transitions this state have. + }; + + const char* parameterTypeString(ParameterType type); + + /// + /// Check if condition is full filled. + /// + /// @param condition Condition to check. + /// + bool processCondition(const Condition& condition); + + /// + /// + /// + void stepwiseProcess(); + + /// + /// + /// + void iterativeProcess(); + + /// + /// + /// + void invokeCallback(int from, int to); + + /// + /// All state this state machine keeps. + /// + std::map<int, State> mStates; + + /// + /// + /// + std::map<int, StateChangeCallback> mOnEnterState; + + /// + /// + /// + std::map<int, StateUpdateCallback> mOnUpdateState; + + /// + /// + /// + std::map<int, StateChangeCallback> mOnExitState; + + /// + /// From first to second. + /// + std::map<std::pair<int, int>, StateTranslateCallback> mOnStateTranslate; + + /// + /// + /// + SingleStateCallback mEnterCallback; + + /// + /// + /// + SingleStateCallback mUpdateCallback; + + /// + /// + /// + SingleStateCallback mExitCallback; + + /// + /// + /// + DoubleStateCallback mTraslateCallback; + + /// + /// Current state. + /// + int mCurrentState; + + /// + /// All parameters. + /// + std::map<int, Parameter> mParameters; + + Mode mMode; + + void* const mUserData; + + }; + + } // namespace Graphics +} // namespace JinEngine + +#endif // jin_ai + +#endif
\ No newline at end of file |