diff options
author | chai <chaifix@163.com> | 2020-02-11 11:29:07 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2020-02-11 11:29:07 +0800 |
commit | 160e1299ef3d95f8e8c48706d7f61dd3dc6c6b60 (patch) | |
tree | abe5ae5242d9cc6caf6edf103e662c44e978fca0 /src/libjin/ai | |
parent | e095043485d1d298571af6d9eca7f0db9009ea7a (diff) |
Diffstat (limited to 'src/libjin/ai')
-rw-r--r-- | src/libjin/ai/behavior_tree.h | 90 | ||||
-rw-r--r-- | src/libjin/ai/state_machine.cpp | 872 | ||||
-rw-r--r-- | src/libjin/ai/state_machine.h | 786 |
3 files changed, 874 insertions, 874 deletions
diff --git a/src/libjin/ai/behavior_tree.h b/src/libjin/ai/behavior_tree.h index eb36e9f..8e59e29 100644 --- a/src/libjin/ai/behavior_tree.h +++ b/src/libjin/ai/behavior_tree.h @@ -8,51 +8,51 @@ namespace JinEngine { - namespace AI - { - - /// - /// - /// - class BehaviorTree : public Object - { - public: - BehaviorTree(void* userData) : mUserData(userData){} - - class Node : public Object - { - public: - enum Type - { - - }; - - enum Status - { - Running, - Success, - Failure - }; - - Status status; - }; - - typedef std::function<Node::Status(void*)> UpdateCallback; - - Node makeNode(Node::Type type, UpdateCallback callback); - - private: - - /// - /// - /// - void* const mUserData; - - }; - - typedef BehaviorTree::Node::Status BahaviorNodeStatus; - - } // namespace AI + namespace AI + { + + /// + /// + /// + class BehaviorTree : public Object + { + public: + BehaviorTree(void* userData) : mUserData(userData){} + + class Node : public Object + { + public: + enum Type + { + + }; + + enum Status + { + Running, + Success, + Failure + }; + + Status status; + }; + + typedef std::function<Node::Status(void*)> UpdateCallback; + + Node makeNode(Node::Type type, UpdateCallback callback); + + private: + + /// + /// + /// + void* const mUserData; + + }; + + typedef BehaviorTree::Node::Status BahaviorNodeStatus; + + } // namespace AI } // namespace JinEngine #endif // jin_ai diff --git a/src/libjin/ai/state_machine.cpp b/src/libjin/ai/state_machine.cpp index cefd0b9..96450ae 100644 --- a/src/libjin/ai/state_machine.cpp +++ b/src/libjin/ai/state_machine.cpp @@ -6,440 +6,440 @@ using namespace std; namespace JinEngine { - namespace AI - { - - StateMachine::StateMachine(Mode mode, void* userdata) - : mCurrentState(0) - , mUserData(userdata) - , mMode(mode) - { - addState(0); - } - - StateMachine::~StateMachine() - { - } - - void StateMachine::invokeCallback(int from, int to) - { - if (mExitCallback != nullptr) - mExitCallback(from, mUserData); - if (mTraslateCallback != nullptr) - mTraslateCallback(from, to, mUserData); - if (mEnterCallback != nullptr) - mEnterCallback(to, mUserData); - map<int, StateChangeCallback>::iterator it = mOnExitState.find(from); - if (it != mOnExitState.end()) - it->second(mUserData); - map<pair<int, int>, StateTranslateCallback>::iterator transItr - = mOnStateTranslate.find(pair<int, int>(from, to)); - if (transItr != mOnStateTranslate.end()) - transItr->second(mUserData); - it = mOnEnterState.find(to); - if (it != mOnEnterState.end()) - it->second(mUserData); - } - - void StateMachine::stepwiseProcess() - { - map<int, State>::iterator it = mStates.find(mCurrentState); - if (it == mStates.end()) - { - jin_log_error("The state [%d] is not exist.", mCurrentState); - return; - } - State& state = it->second; - for (int i = 0; i < state.transitions.size(); ++i) - { - Conditions conditions = state.transitions[i].conditions; - bool isActive = true; - for (int j = 0; j < conditions.conditions.size(); ++j) - { - isActive &= processCondition(conditions.conditions[j]); - if (!isActive) - break; - } - if (isActive) - { - // Traslate - mCurrentState = state.transitions[i].state; - invokeCallback(state.name, mCurrentState); - break; - } - } - // Call update - if (mUpdateCallback != nullptr) - mUpdateCallback(mCurrentState, mUserData); - map<int, StateUpdateCallback>::iterator uit = mOnUpdateState.find(mCurrentState); - if (uit != mOnUpdateState.end()) - uit->second(mUserData); - } - - void StateMachine::iterativeProcess() - { - map<int, State>::iterator it = mStates.find(mCurrentState); - if (it == mStates.end()) - { - jin_log_error("The state [%d] is not exist.", mCurrentState); - return; - } - State& state = it->second; - bool isActive = true; - for (int i = 0; i < state.transitions.size(); ++i) - { - Conditions conditions = state.transitions[i].conditions; - isActive = true; - for (int j = 0; j < conditions.conditions.size(); ++j) - { - isActive &= processCondition(conditions.conditions[j]); - if (!isActive) - break; - } - if (isActive) - { - // Traslate - mCurrentState = state.transitions[i].state; - invokeCallback(state.name, mCurrentState); - break; - } - } - // Call update - if (mUpdateCallback != nullptr) - mUpdateCallback(mCurrentState, mUserData); - map<int, StateUpdateCallback>::iterator uit = mOnUpdateState.find(mCurrentState); - if (uit != mOnUpdateState.end()) - uit->second(mUserData); - // Recursive. - if(isActive) - return iterativeProcess(); - } - - void StateMachine::setMode(Mode mode) - { - mMode = mode; - } - - void StateMachine::update() - { - switch (mMode) - { - case Mode::Iterative: iterativeProcess(); break; - case Mode::Stepwise: stepwiseProcess(); break; - } - } - - bool StateMachine::processCondition(const Condition& condition) - { - map<int, Parameter>::iterator it = mParameters.find(condition.parameter); - if (it == mParameters.end()) - { - jin_log_error("The parameter <%d> is not exist", condition.parameter); - return false; - } - Parameter& p = it->second; - switch (p.type) - { - case ParameterType::Int: - { - int value = p.value._int; - int cvalue = condition.value._int; - bool is = false; - is |= ((condition.expression & ParameterExpression::INT_GREATER) ? value > cvalue : false); - is |= ((condition.expression & ParameterExpression::INT_EQUAL) ? value == cvalue : false); - is |= ((condition.expression & ParameterExpression::INT_LESS) ? value < cvalue : false); - return is; - } - case ParameterType::Float: - { - float value = p.value._float; - float cvalue = condition.value._float; - bool is = false; - is |= ((condition.expression & ParameterExpression::FLOAT_GREATER) ? value > cvalue : false); - is |= ((condition.expression & ParameterExpression::FLOAT_EQUAL) ? value == cvalue : false); - is |= ((condition.expression & ParameterExpression::FLOAT_LESS) ? value < cvalue : false); - return is; - } - case ParameterType::Bool: - { - bool value = p.value._bool; - bool cvalue = condition.value._bool; - bool is = false; - is |= ((condition.expression & ParameterExpression::BOOL_IS) ? value == cvalue : false); - is |= ((condition.expression & ParameterExpression::BOOL_NOT) ? value != cvalue : false); - return is; - } - case ParameterType::Trigger: - { - bool is = p.value._trigger; - // Close trigger. - p.value._trigger = false; - return is; - } - } - return false; - } - - int StateMachine::getCurrentState() - { - return mCurrentState; - } - - void StateMachine::addParameteri(int name) - { - if (mParameters.find(name) != mParameters.end()) - { - jin_log_error("The parameter <%d> is already exist.", name); - return; - } - Parameter p; - p.type = ParameterType::Int; - p.value._int = 0; - mParameters.insert(pair<int, Parameter>(name, p)); - } - - void StateMachine::addParameterf(int name) - { - if (mParameters.find(name) != mParameters.end()) - { - jin_log_error("The parameter <%d> is already exist.", name); - return; - } - Parameter p; - p.type = ParameterType::Float; - p.value._float = 0.0f; - mParameters.insert(pair<int, Parameter>(name, p)); - } - - void StateMachine::addParameterb(int name) - { - if (mParameters.find(name) != mParameters.end()) - { - jin_log_error("The parameter <%d> is already exist.", name); - return; - } - Parameter p; - p.type = ParameterType::Bool; - p.value._bool = false; - mParameters.insert(pair<int, Parameter>(name, p)); - } - - void StateMachine::addParametert(int name) - { - if (mParameters.find(name) != mParameters.end()) - { - jin_log_error("The parameter <%d> is already exist.", name); - return; - } - Parameter p; - p.type = ParameterType::Trigger; - p.value._trigger = false; - mParameters.insert(pair<int, Parameter>(name, p)); - } - - void StateMachine::addState(int name) - { - if (mStates.find(name) != mStates.end()) - { - jin_log_error("The state [%d] is already exist.", name); - return; - } - State state; - state.name = name; - mStates.insert(pair<int, State>(name, state)); - } - - const char* StateMachine::parameterTypeString(ParameterType type) - { - switch (type) - { - case ParameterType::Int: return "int"; - case ParameterType::Float: return "float"; - case ParameterType::Bool: return "bool"; - case ParameterType::Trigger: return "trigger"; - } - } - - void StateMachine::addTransition(int from, int to, const Conditions& conditions) - { - map<int, State>::iterator it; - it = mStates.find(from); - if (it == mStates.end()) - { - jin_log_error("The state [%d] is not exist.", from); - return; - } - State& fromState = it->second; - it = mStates.find(to); - if (it == mStates.end()) - { - jin_log_error("The state [%d] is not exist.", to); - return; - } - // Check condtion correctness. - for (int i = 0; i < conditions.conditions.size(); ++i) - { - const Condition& condition = conditions.conditions[i]; - map<int, Parameter>::iterator itp; - itp = mParameters.find(condition.parameter); - if (itp == mParameters.end()) - { - jin_log_error("The parameter <%d> is not exist.", condition.parameter); - return; - } - Parameter& p = itp->second; - if (p.type != condition.type) - { - jin_log_error("The type of parameter <%d> is a %s, but the transition gives a %s value." - , condition.parameter, parameterTypeString(p.type), parameterTypeString(condition.type)); - return; - } - } - // Add transition. - Transition transition; - transition.conditions = conditions; - transition.state = to; - fromState.transitions.push_back(transition); - } - - void StateMachine::setParameteri(int name, int value) - { - map<int, Parameter>::iterator it = mParameters.find(name); - if (it == mParameters.end()) - { - jin_log_error("The state [%d] is not exist.", name); - return; - } - Parameter& p = it->second; - if (p.type != ParameterType::Int) - { - jin_log_error("The type of parameter <%d> is %s, but try to assign a int value to it", name, parameterTypeString(p.type)); - return; - } - p.value._int = value; - } - - void StateMachine::setParameterf(int name, float value) - { - map<int, Parameter>::iterator it = mParameters.find(name); - if (it == mParameters.end()) - { - jin_log_error("The state [%d] is not exist.", name); - return; - } - Parameter& p = it->second; - if (p.type != ParameterType::Float) - { - jin_log_error("The type of parameter <%d> is %s, but try to assign a float value to it", name, parameterTypeString(p.type)); - return; - } - p.value._float = value; - } - - void StateMachine::setParameterb(int name, bool value) - { - map<int, Parameter>::iterator it = mParameters.find(name); - if (it == mParameters.end()) - { - jin_log_error("The state %s is not exist.", name); - return; - } - Parameter& p = it->second; - if (p.type != ParameterType::Bool) - { - jin_log_error("The type of parameter <%d> is %s, but try to assign a bool value to it", name, parameterTypeString(p.type)); - return; - } - p.value._bool = value; - } - - void StateMachine::setParametert(int name) - { - map<int, Parameter>::iterator it = mParameters.find(name); - if (it == mParameters.end()) - { - jin_log_error("The state %s is not exist.", name); - return; - } - Parameter& p = it->second; - if (p.type != ParameterType::Trigger) - { - jin_log_error("The type of parameter <%d> is %s, but try to assign a trigger value to it", name, parameterTypeString(p.type)); - return; - } - p.value._trigger = true; - } - - void StateMachine::forceToState(int name) - { - if (mStates.find(name) == mStates.end()) - { - jin_log_error("The state [%d] is not exist.", name); - return; - } - mCurrentState = name; - } - - void StateMachine::addEnterListener(int state, const StateChangeCallback& callback) - { - if (mOnEnterState.find(state) != mOnEnterState.end()) - { - jin_log_error("The enter listener of [%d] is already exist.", state); - return; - } - mOnEnterState.insert(pair<int, StateChangeCallback>(state, callback)); - } - - void StateMachine::addUpdateListener(int state, const StateUpdateCallback& callback) - { - if (mOnUpdateState.find(state) != mOnUpdateState.end()) - { - jin_log_error("The update listener of [%d] is already exist.", state); - return; - } - mOnUpdateState.insert(pair<int, StateUpdateCallback>(state, callback)); - } - - void StateMachine::addExitListener(int state, const StateChangeCallback& callback) - { - if (mOnExitState.find(state) != mOnExitState.end()) - { - jin_log_error("The exit listener of [%d] is already exist.", state); - return; - } - mOnExitState.insert(pair<int, StateChangeCallback>(state, callback)); - } - - void StateMachine::addTranslateListener(int from, int to, const StateChangeCallback& callback) - { - if (mOnStateTranslate.find(pair<int, int>(from, to)) != mOnStateTranslate.end()) - { - jin_log_error("The traslate listener of [%d] to [%d] is already exist.", from, to); - return; - } - pair<int, int> key(from, to); - mOnStateTranslate.insert(pair<pair<int, int>, StateTranslateCallback>(key, callback)); - } - - void StateMachine::setUpdateListener(const SingleStateCallback& callback) - { - mUpdateCallback = callback; - } - - void StateMachine::setEnterListener(const SingleStateCallback& callback) - { - mEnterCallback = callback; - } - - void StateMachine::setExitListener(const SingleStateCallback& callback) - { - mExitCallback = callback; - } - - void StateMachine::setTranslateListener(const DoubleStateCallback& callback) - { - mTraslateCallback = callback; - } - - } // namespace AI + namespace AI + { + + StateMachine::StateMachine(Mode mode, void* userdata) + : mCurrentState(0) + , mUserData(userdata) + , mMode(mode) + { + addState(0); + } + + StateMachine::~StateMachine() + { + } + + void StateMachine::invokeCallback(int from, int to) + { + if (mExitCallback != nullptr) + mExitCallback(from, mUserData); + if (mTraslateCallback != nullptr) + mTraslateCallback(from, to, mUserData); + if (mEnterCallback != nullptr) + mEnterCallback(to, mUserData); + map<int, StateChangeCallback>::iterator it = mOnExitState.find(from); + if (it != mOnExitState.end()) + it->second(mUserData); + map<pair<int, int>, StateTranslateCallback>::iterator transItr + = mOnStateTranslate.find(pair<int, int>(from, to)); + if (transItr != mOnStateTranslate.end()) + transItr->second(mUserData); + it = mOnEnterState.find(to); + if (it != mOnEnterState.end()) + it->second(mUserData); + } + + void StateMachine::stepwiseProcess() + { + map<int, State>::iterator it = mStates.find(mCurrentState); + if (it == mStates.end()) + { + jin_log_error("The state [%d] is not exist.", mCurrentState); + return; + } + State& state = it->second; + for (int i = 0; i < state.transitions.size(); ++i) + { + Conditions conditions = state.transitions[i].conditions; + bool isActive = true; + for (int j = 0; j < conditions.conditions.size(); ++j) + { + isActive &= processCondition(conditions.conditions[j]); + if (!isActive) + break; + } + if (isActive) + { + // Traslate + mCurrentState = state.transitions[i].state; + invokeCallback(state.name, mCurrentState); + break; + } + } + // Call update + if (mUpdateCallback != nullptr) + mUpdateCallback(mCurrentState, mUserData); + map<int, StateUpdateCallback>::iterator uit = mOnUpdateState.find(mCurrentState); + if (uit != mOnUpdateState.end()) + uit->second(mUserData); + } + + void StateMachine::iterativeProcess() + { + map<int, State>::iterator it = mStates.find(mCurrentState); + if (it == mStates.end()) + { + jin_log_error("The state [%d] is not exist.", mCurrentState); + return; + } + State& state = it->second; + bool isActive = true; + for (int i = 0; i < state.transitions.size(); ++i) + { + Conditions conditions = state.transitions[i].conditions; + isActive = true; + for (int j = 0; j < conditions.conditions.size(); ++j) + { + isActive &= processCondition(conditions.conditions[j]); + if (!isActive) + break; + } + if (isActive) + { + // Traslate + mCurrentState = state.transitions[i].state; + invokeCallback(state.name, mCurrentState); + break; + } + } + // Call update + if (mUpdateCallback != nullptr) + mUpdateCallback(mCurrentState, mUserData); + map<int, StateUpdateCallback>::iterator uit = mOnUpdateState.find(mCurrentState); + if (uit != mOnUpdateState.end()) + uit->second(mUserData); + // Recursive. + if(isActive) + return iterativeProcess(); + } + + void StateMachine::setMode(Mode mode) + { + mMode = mode; + } + + void StateMachine::update() + { + switch (mMode) + { + case Mode::Iterative: iterativeProcess(); break; + case Mode::Stepwise: stepwiseProcess(); break; + } + } + + bool StateMachine::processCondition(const Condition& condition) + { + map<int, Parameter>::iterator it = mParameters.find(condition.parameter); + if (it == mParameters.end()) + { + jin_log_error("The parameter <%d> is not exist", condition.parameter); + return false; + } + Parameter& p = it->second; + switch (p.type) + { + case ParameterType::Int: + { + int value = p.value._int; + int cvalue = condition.value._int; + bool is = false; + is |= ((condition.expression & ParameterExpression::INT_GREATER) ? value > cvalue : false); + is |= ((condition.expression & ParameterExpression::INT_EQUAL) ? value == cvalue : false); + is |= ((condition.expression & ParameterExpression::INT_LESS) ? value < cvalue : false); + return is; + } + case ParameterType::Float: + { + float value = p.value._float; + float cvalue = condition.value._float; + bool is = false; + is |= ((condition.expression & ParameterExpression::FLOAT_GREATER) ? value > cvalue : false); + is |= ((condition.expression & ParameterExpression::FLOAT_EQUAL) ? value == cvalue : false); + is |= ((condition.expression & ParameterExpression::FLOAT_LESS) ? value < cvalue : false); + return is; + } + case ParameterType::Bool: + { + bool value = p.value._bool; + bool cvalue = condition.value._bool; + bool is = false; + is |= ((condition.expression & ParameterExpression::BOOL_IS) ? value == cvalue : false); + is |= ((condition.expression & ParameterExpression::BOOL_NOT) ? value != cvalue : false); + return is; + } + case ParameterType::Trigger: + { + bool is = p.value._trigger; + // Close trigger. + p.value._trigger = false; + return is; + } + } + return false; + } + + int StateMachine::getCurrentState() + { + return mCurrentState; + } + + void StateMachine::addParameteri(int name) + { + if (mParameters.find(name) != mParameters.end()) + { + jin_log_error("The parameter <%d> is already exist.", name); + return; + } + Parameter p; + p.type = ParameterType::Int; + p.value._int = 0; + mParameters.insert(pair<int, Parameter>(name, p)); + } + + void StateMachine::addParameterf(int name) + { + if (mParameters.find(name) != mParameters.end()) + { + jin_log_error("The parameter <%d> is already exist.", name); + return; + } + Parameter p; + p.type = ParameterType::Float; + p.value._float = 0.0f; + mParameters.insert(pair<int, Parameter>(name, p)); + } + + void StateMachine::addParameterb(int name) + { + if (mParameters.find(name) != mParameters.end()) + { + jin_log_error("The parameter <%d> is already exist.", name); + return; + } + Parameter p; + p.type = ParameterType::Bool; + p.value._bool = false; + mParameters.insert(pair<int, Parameter>(name, p)); + } + + void StateMachine::addParametert(int name) + { + if (mParameters.find(name) != mParameters.end()) + { + jin_log_error("The parameter <%d> is already exist.", name); + return; + } + Parameter p; + p.type = ParameterType::Trigger; + p.value._trigger = false; + mParameters.insert(pair<int, Parameter>(name, p)); + } + + void StateMachine::addState(int name) + { + if (mStates.find(name) != mStates.end()) + { + jin_log_error("The state [%d] is already exist.", name); + return; + } + State state; + state.name = name; + mStates.insert(pair<int, State>(name, state)); + } + + const char* StateMachine::parameterTypeString(ParameterType type) + { + switch (type) + { + case ParameterType::Int: return "int"; + case ParameterType::Float: return "float"; + case ParameterType::Bool: return "bool"; + case ParameterType::Trigger: return "trigger"; + } + } + + void StateMachine::addTransition(int from, int to, const Conditions& conditions) + { + map<int, State>::iterator it; + it = mStates.find(from); + if (it == mStates.end()) + { + jin_log_error("The state [%d] is not exist.", from); + return; + } + State& fromState = it->second; + it = mStates.find(to); + if (it == mStates.end()) + { + jin_log_error("The state [%d] is not exist.", to); + return; + } + // Check condtion correctness. + for (int i = 0; i < conditions.conditions.size(); ++i) + { + const Condition& condition = conditions.conditions[i]; + map<int, Parameter>::iterator itp; + itp = mParameters.find(condition.parameter); + if (itp == mParameters.end()) + { + jin_log_error("The parameter <%d> is not exist.", condition.parameter); + return; + } + Parameter& p = itp->second; + if (p.type != condition.type) + { + jin_log_error("The type of parameter <%d> is a %s, but the transition gives a %s value." + , condition.parameter, parameterTypeString(p.type), parameterTypeString(condition.type)); + return; + } + } + // Add transition. + Transition transition; + transition.conditions = conditions; + transition.state = to; + fromState.transitions.push_back(transition); + } + + void StateMachine::setParameteri(int name, int value) + { + map<int, Parameter>::iterator it = mParameters.find(name); + if (it == mParameters.end()) + { + jin_log_error("The state [%d] is not exist.", name); + return; + } + Parameter& p = it->second; + if (p.type != ParameterType::Int) + { + jin_log_error("The type of parameter <%d> is %s, but try to assign a int value to it", name, parameterTypeString(p.type)); + return; + } + p.value._int = value; + } + + void StateMachine::setParameterf(int name, float value) + { + map<int, Parameter>::iterator it = mParameters.find(name); + if (it == mParameters.end()) + { + jin_log_error("The state [%d] is not exist.", name); + return; + } + Parameter& p = it->second; + if (p.type != ParameterType::Float) + { + jin_log_error("The type of parameter <%d> is %s, but try to assign a float value to it", name, parameterTypeString(p.type)); + return; + } + p.value._float = value; + } + + void StateMachine::setParameterb(int name, bool value) + { + map<int, Parameter>::iterator it = mParameters.find(name); + if (it == mParameters.end()) + { + jin_log_error("The state %s is not exist.", name); + return; + } + Parameter& p = it->second; + if (p.type != ParameterType::Bool) + { + jin_log_error("The type of parameter <%d> is %s, but try to assign a bool value to it", name, parameterTypeString(p.type)); + return; + } + p.value._bool = value; + } + + void StateMachine::setParametert(int name) + { + map<int, Parameter>::iterator it = mParameters.find(name); + if (it == mParameters.end()) + { + jin_log_error("The state %s is not exist.", name); + return; + } + Parameter& p = it->second; + if (p.type != ParameterType::Trigger) + { + jin_log_error("The type of parameter <%d> is %s, but try to assign a trigger value to it", name, parameterTypeString(p.type)); + return; + } + p.value._trigger = true; + } + + void StateMachine::forceToState(int name) + { + if (mStates.find(name) == mStates.end()) + { + jin_log_error("The state [%d] is not exist.", name); + return; + } + mCurrentState = name; + } + + void StateMachine::addEnterListener(int state, const StateChangeCallback& callback) + { + if (mOnEnterState.find(state) != mOnEnterState.end()) + { + jin_log_error("The enter listener of [%d] is already exist.", state); + return; + } + mOnEnterState.insert(pair<int, StateChangeCallback>(state, callback)); + } + + void StateMachine::addUpdateListener(int state, const StateUpdateCallback& callback) + { + if (mOnUpdateState.find(state) != mOnUpdateState.end()) + { + jin_log_error("The update listener of [%d] is already exist.", state); + return; + } + mOnUpdateState.insert(pair<int, StateUpdateCallback>(state, callback)); + } + + void StateMachine::addExitListener(int state, const StateChangeCallback& callback) + { + if (mOnExitState.find(state) != mOnExitState.end()) + { + jin_log_error("The exit listener of [%d] is already exist.", state); + return; + } + mOnExitState.insert(pair<int, StateChangeCallback>(state, callback)); + } + + void StateMachine::addTranslateListener(int from, int to, const StateChangeCallback& callback) + { + if (mOnStateTranslate.find(pair<int, int>(from, to)) != mOnStateTranslate.end()) + { + jin_log_error("The traslate listener of [%d] to [%d] is already exist.", from, to); + return; + } + pair<int, int> key(from, to); + mOnStateTranslate.insert(pair<pair<int, int>, StateTranslateCallback>(key, callback)); + } + + void StateMachine::setUpdateListener(const SingleStateCallback& callback) + { + mUpdateCallback = callback; + } + + void StateMachine::setEnterListener(const SingleStateCallback& callback) + { + mEnterCallback = callback; + } + + void StateMachine::setExitListener(const SingleStateCallback& callback) + { + mExitCallback = callback; + } + + void StateMachine::setTranslateListener(const DoubleStateCallback& callback) + { + mTraslateCallback = callback; + } + + } // namespace AI } // namespace JinEngine
\ No newline at end of file diff --git a/src/libjin/ai/state_machine.h b/src/libjin/ai/state_machine.h index d70563d..151853c 100644 --- a/src/libjin/ai/state_machine.h +++ b/src/libjin/ai/state_machine.h @@ -14,399 +14,399 @@ 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 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 |