aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/ai/state_machine.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libjin/ai/state_machine.h')
-rw-r--r--src/libjin/ai/state_machine.h414
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