AIStateMachine.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. for (std::list<AIState*>::const_iterator itr = _states.begin(); itr != _states.end(); ++itr)
  65. {
  66. AIState* state = (*itr);
  67. if (strcmp(id, state->getId()) == 0)
  68. return state;
  69. }
  70. return NULL;
  71. }
  72. AIState* AIStateMachine::getActiveState() const
  73. {
  74. return _currentState;
  75. }
  76. bool AIStateMachine::hasState(AIState* state) const
  77. {
  78. GP_ASSERT(state);
  79. return (std::find(_states.begin(), _states.end(), state) != _states.end());
  80. }
  81. AIState* AIStateMachine::setState(const char* id)
  82. {
  83. AIState* state = getState(id);
  84. if (state)
  85. sendChangeStateMessage(state);
  86. return state;
  87. }
  88. bool AIStateMachine::setState(AIState* state)
  89. {
  90. if (hasState(state))
  91. {
  92. sendChangeStateMessage(state);
  93. return true;
  94. }
  95. return false;
  96. }
  97. void AIStateMachine::sendChangeStateMessage(AIState* newState)
  98. {
  99. AIMessage* message = AIMessage::create(0, _agent->getId(), _agent->getId(), 1);
  100. message->_messageType = AIMessage::MESSAGE_TYPE_STATE_CHANGE;
  101. message->setString(0, newState->getId());
  102. Game::getInstance()->getAIController()->sendMessage(message);
  103. }
  104. void AIStateMachine::setStateInternal(AIState* state)
  105. {
  106. GP_ASSERT(hasState(state));
  107. // Fire the exit event for the current state
  108. _currentState->exit(this);
  109. // Set the new state
  110. _currentState = state;
  111. // Fire the enter event for the new state
  112. _currentState->enter(this);
  113. }
  114. void AIStateMachine::update(float elapsedTime)
  115. {
  116. _currentState->update(this, elapsedTime);
  117. }
  118. }