AIStateMachine.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #include "Base.h"
  2. #include "AIStateMachine.h"
  3. #include "AIAgent.h"
  4. #include "AIMessage.h"
  5. #include "Game.h"
  6. namespace gameplay
  7. {
  8. AIStateMachine::AIStateMachine(AIAgent* agent)
  9. : _agent(agent)
  10. {
  11. GP_ASSERT(agent);
  12. if (AIState::_empty)
  13. AIState::_empty->addRef();
  14. else
  15. AIState::_empty = new AIState("");
  16. _currentState = AIState::_empty;
  17. }
  18. AIStateMachine::~AIStateMachine()
  19. {
  20. // Release all states
  21. for (std::list<AIState*>::iterator itr = _states.begin(); itr != _states.end(); ++itr)
  22. {
  23. (*itr)->release();
  24. }
  25. SAFE_RELEASE(AIState::_empty);
  26. }
  27. AIAgent* AIStateMachine::getAgent() const
  28. {
  29. return _agent;
  30. }
  31. AIState* AIStateMachine::addState(const char* id)
  32. {
  33. AIState* state = AIState::create(id);
  34. _states.push_back(state);
  35. return state;
  36. }
  37. void AIStateMachine::addState(AIState* state)
  38. {
  39. state->addRef();
  40. _states.push_back(state);
  41. }
  42. void AIStateMachine::removeState(AIState* state)
  43. {
  44. std::list<AIState*>::iterator itr = std::find(_states.begin(), _states.end(), state);
  45. if (itr != _states.end())
  46. {
  47. _states.erase(itr);
  48. state->release();
  49. }
  50. }
  51. AIState* AIStateMachine::getState(const char* id) const
  52. {
  53. GP_ASSERT(id);
  54. AIState* state;
  55. for (std::list<AIState*>::const_iterator itr = _states.begin(); itr != _states.end(); ++itr)
  56. {
  57. state = (*itr);
  58. if (strcmp(id, state->getId()) == 0)
  59. return state;
  60. }
  61. return NULL;
  62. }
  63. AIState* AIStateMachine::getActiveState() const
  64. {
  65. return _currentState;
  66. }
  67. bool AIStateMachine::hasState(AIState* state) const
  68. {
  69. GP_ASSERT(state);
  70. return (std::find(_states.begin(), _states.end(), state) != _states.end());
  71. }
  72. AIState* AIStateMachine::setState(const char* id)
  73. {
  74. AIState* state = getState(id);
  75. if (state)
  76. sendChangeStateMessage(state);
  77. return state;
  78. }
  79. bool AIStateMachine::setState(AIState* state)
  80. {
  81. if (hasState(state))
  82. {
  83. sendChangeStateMessage(state);
  84. return true;
  85. }
  86. return false;
  87. }
  88. void AIStateMachine::sendChangeStateMessage(AIState* newState)
  89. {
  90. AIMessage* message = AIMessage::create(0, _agent->getId(), _agent->getId(), 1);
  91. message->_messageType = AIMessage::MESSAGE_TYPE_STATE_CHANGE;
  92. message->setString(0, newState->getId());
  93. Game::getInstance()->getAIController()->sendMessage(message);
  94. }
  95. void AIStateMachine::setStateInternal(AIState* state)
  96. {
  97. GP_ASSERT(hasState(state));
  98. // Fire the exit event for the current state
  99. _currentState->exit(this);
  100. // Set the new state
  101. _currentState = state;
  102. // Fire the enter event for the new state
  103. _currentState->enter(this);
  104. }
  105. void AIStateMachine::update(float elapsedTime)
  106. {
  107. _currentState->update(this, elapsedTime);
  108. }
  109. }