#include "Base.h"
#include "AIController.h"
#include "Game.h"
namespace gameplay
{
AIController::AIController()
: _paused(false), _firstMessage(NULL), _firstAgent(NULL)
{
}
AIController::~AIController()
{
}
void AIController::initialize()
{
}
void AIController::finalize()
{
// Remove all agents
AIAgent* agent = _firstAgent;
while (agent)
{
AIAgent* temp = agent;
agent = agent->_next;
SAFE_RELEASE(temp);
}
_firstAgent = NULL;
// Remove all messages
AIMessage* message = _firstMessage;
while (message)
{
AIMessage* temp = message;
message = message->_next;
AIMessage::destroy(temp);
}
_firstMessage = NULL;
}
void AIController::pause()
{
_paused = true;
}
void AIController::resume()
{
_paused = false;
}
void AIController::sendMessage(AIMessage* message, float delay)
{
if (delay <= 0)
{
// Send instantly
if (message->getReceiver() == NULL || strlen(message->getReceiver()) == 0)
{
// Broadcast message to all agents
AIAgent* agent = _firstAgent;
while (agent)
{
if (agent->processMessage(message))
break; // message consumed by this agent - stop bubbling
agent = agent->_next;
}
}
else
{
// Single recipient
AIAgent* agent = findAgent(message->getReceiver());
if (agent)
{
agent->processMessage(message);
}
else
{
GP_WARN("Failed to locate AIAgent for message recipient: %s", message->getReceiver());
}
}
// Delete the message, since it is finished being processed
AIMessage::destroy(message);
}
else
{
// Queue for later delivery
if (_firstMessage)
message->_next = _firstMessage;
_firstMessage = message;
}
}
void AIController::update(float elapsedTime)
{
if (_paused)
return;
static Game* game = Game::getInstance();
// Send all pending messages that have expired
AIMessage* prevMsg = NULL;
AIMessage* msg = _firstMessage;
while (msg)
{
// If the message delivery time has expired, send it (this also deletes it)
if (msg->getDeliveryTime() >= game->getGameTime())
{
// Link the message out of our list
if (prevMsg)
prevMsg->_next = msg->_next;
AIMessage* temp = msg;
msg = msg->_next;
temp->_next = NULL;
sendMessage(temp);
}
else
{
prevMsg = msg;
msg = msg->_next;
}
}
// Update all enabled agents
AIAgent* agent = _firstAgent;
while (agent)
{
if (agent->isEnabled())
agent->update(elapsedTime);
agent = agent->_next;
}
}
void AIController::addAgent(AIAgent* agent)
{
agent->addRef();
if (_firstAgent)
agent->_next = _firstAgent;
_firstAgent = agent;
}
void AIController::removeAgent(AIAgent* agent)
{
// Search our linked list of agents and link this agent out.
AIAgent* prevAgent = NULL;
AIAgent* itr = _firstAgent;
while (itr)
{
if (itr == agent)
{
if (prevAgent)
prevAgent->_next = agent->_next;
else
_firstAgent = agent->_next;
agent->_next = NULL;
agent->release();
break;
}
prevAgent = itr;
itr = itr->_next;
}
}
AIAgent* AIController::findAgent(const char* id) const
{
GP_ASSERT(id);
AIAgent* agent = _firstAgent;
while (agent)
{
if (strcmp(id, agent->getId()) == 0)
return agent;
agent = agent->_next;
}
return NULL;
}
}