AIStateMachine.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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. if (AIState::_empty)
  26. {
  27. if (AIState::_empty->getRefCount() == 1)
  28. {
  29. SAFE_RELEASE(AIState::_empty);
  30. }
  31. else
  32. {
  33. AIState::_empty->release();
  34. }
  35. }
  36. }
  37. AIAgent* AIStateMachine::getAgent() const
  38. {
  39. return _agent;
  40. }
  41. AIState* AIStateMachine::addState(const char* id)
  42. {
  43. AIState* state = AIState::create(id);
  44. _states.push_back(state);
  45. return state;
  46. }
  47. void AIStateMachine::addState(AIState* state)
  48. {
  49. state->addRef();
  50. _states.push_back(state);
  51. }
  52. void AIStateMachine::removeState(AIState* state)
  53. {
  54. std::list<AIState*>::iterator itr = std::find(_states.begin(), _states.end(), state);
  55. if (itr != _states.end())
  56. {
  57. _states.erase(itr);
  58. state->release();
  59. }
  60. }
  61. AIState* AIStateMachine::getState(const char* id) const
  62. {
  63. GP_ASSERT(id);
  64. AIState* state;
  65. for (std::list<AIState*>::const_iterator itr = _states.begin(); itr != _states.end(); ++itr)
  66. {
  67. state = (*itr);
  68. if (strcmp(id, state->getId()) == 0)
  69. return state;
  70. }
  71. return NULL;
  72. }
  73. AIState* AIStateMachine::getActiveState() const
  74. {
  75. return _currentState;
  76. }
  77. bool AIStateMachine::hasState(AIState* state) const
  78. {
  79. GP_ASSERT(state);
  80. return (std::find(_states.begin(), _states.end(), state) != _states.end());
  81. }
  82. AIState* AIStateMachine::setState(const char* id)
  83. {
  84. AIState* state = getState(id);
  85. if (state)
  86. sendChangeStateMessage(state);
  87. return state;
  88. }
  89. bool AIStateMachine::setState(AIState* state)
  90. {
  91. if (hasState(state))
  92. {
  93. sendChangeStateMessage(state);
  94. return true;
  95. }
  96. return false;
  97. }
  98. void AIStateMachine::sendChangeStateMessage(AIState* newState)
  99. {
  100. AIMessage* message = AIMessage::create(0, _agent->getId(), _agent->getId(), 1);
  101. message->_messageType = AIMessage::MESSAGE_TYPE_STATE_CHANGE;
  102. message->setString(0, newState->getId());
  103. Game::getInstance()->getAIController()->sendMessage(message);
  104. }
  105. void AIStateMachine::setStateInternal(AIState* state)
  106. {
  107. GP_ASSERT(hasState(state));
  108. // Fire the exit event for the current state
  109. _currentState->exit(this);
  110. // Set the new state
  111. _currentState = state;
  112. // Fire the enter event for the new state
  113. _currentState->enter(this);
  114. }
  115. void AIStateMachine::update(float elapsedTime)
  116. {
  117. _currentState->update(this, elapsedTime);
  118. }
  119. }