Show ActionController.cpp syntax highlighted
////////////////////////////////////////////////////////////////////////////////
// Scorched3D (c) 2000-2003
//
// This file is part of Scorched3D.
//
// Scorched3D is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Scorched3D is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Scorched3D; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
////////////////////////////////////////////////////////////////////////////////
#include <engine/ActionController.h>
#include <engine/ScorchedContext.h>
#include <engine/SyncCheck.h>
#include <movement/TargetMovement.h>
#include <common/Logger.h>
#include <common/OptionsScorched.h>
#include <list>
ActionController::ActionController() :
GameStateI("ActionController"),
speed_(1.0f), referenceCount_(0), time_(0.0f),
context_(0), lastTraceTime_(0.0f),
actionTracing_(false), stepTime_(0.0f),
actionEvents_(false), actionProfiling_(false),
actionNumber_(0)
{
}
ActionController::~ActionController()
{
}
void ActionController::clear(bool warn)
{
// New actions
std::list<Action *>::iterator newItor;
for (newItor = newActions_.begin();
newItor != newActions_.end();
newItor++)
{
Action *act = *newItor;
if (warn)
{
Logger::log(formatString("Warning: removing added timed out action %s, %s",
act->getActionType(), (act->getReferenced()?"Ref":"UnRef")));
}
delete act;
}
newActions_.clear();
// Current actions
for (int a=0; a<actions_.actionCount; a++)
{
Action *act = actions_.actions[a];
if (warn)
{
Logger::log(formatString("Warning: removing added timed out action %s, %s",
act->getActionType(), (act->getReferenced()?"Ref":"UnRef")));
}
delete act;
}
actions_.clear();
// Ref count
referenceCount_ = 0;
}
bool ActionController::allEvents()
{
// Criteria to add more events :-
// Check that there are referenced actions in the simulation,
// and that these referenced actions are not events
std::list<Action *>::iterator newItor;
for (newItor = newActions_.begin();
newItor != newActions_.end();
newItor++)
{
Action *act = *newItor;
if (!act->getActionEvent() &&
act->getReferenced()) return false;
}
for (int a=0; a<actions_.actionCount; a++)
{
Action *act = actions_.actions[a];
if (!act->getActionEvent() &&
act->getReferenced()) return false;
}
return true;
}
void ActionController::logActions()
{
Logger::log(formatString("ActionLog : Time %.2f, New %i, Ref %i",
time_,
(int) newActions_.size(),
referenceCount_));
for (int a=0; a<actions_.actionCount; a++)
{
Action *act = actions_.actions[a];
Logger::log(formatString("Action : %s", act->getActionType()));
}
}
void ActionController::logProfiledActions()
{
if (!actionProfiling_) return;
Logger::log("Logging Profiled Actions --------------------");
int totalCount = 0;
std::map<std::string, int>::iterator itor;
for (itor = actionProfile_.begin();
itor != actionProfile_.end();
itor++)
{
const std::string &name = (*itor).first;
int count = (*itor).second;
totalCount += count;
Logger::log(formatString("%s - %i", name.c_str(), count));
}
Logger::log(formatString("Total - %i", totalCount));
Logger::log("---------------------------------------------");
actionProfile_.clear();
}
bool ActionController::noReferencedActions()
{
bool finished = (newActions_.empty() &&
(referenceCount_ == 0));
if (actionTracing_)
{
if (time_ - lastTraceTime_ > 5.0f)
{
lastTraceTime_ = time_;
logActions();
}
}
return finished;
}
void ActionController::resetTime()
{
time_ = 0.0f;
lastTraceTime_ = 0.0f;
stepTime_ = 0.0f;
}
void ActionController::setScorchedContext(ScorchedContext *context)
{
context_ = context;
}
void ActionController::setFast(float speedMult)
{
speed_ = speedMult;
}
void ActionController::addAction(Action *action)
{
action->setScorchedContext(context_);
action->setActionStartTime(time_);
action->setActionEvent(actionEvents_);
if (action->getReferenced())
{
action->setActionNumber(++actionNumber_);
/*SyncCheck::instance()->addString(*context_,
formatString("Action : %f %u %s",
time_, action->getActionNumber(), action->getActionType()));*/
}
newActions_.push_back(action);
if (actionProfiling_)
{
std::map<std::string, int>::iterator findItor =
actionProfile_.find(action->getActionType());
if (findItor == actionProfile_.end())
{
actionProfile_[action->getActionType()] = 1;
}
else
{
(*findItor).second++;
}
}
}
void ActionController::addNewActions()
{
while (!newActions_.empty())
{
Action *action = newActions_.front();
action->setScorchedContext(context_);
action->setActionStartTime(time_);
if (action->getReferenced()) referenceCount_ ++;
action->init();
actions_.push_back(action);
newActions_.pop_front();
}
}
void ActionController::draw(const unsigned state)
{
// Itterate and draw all of the actions
for (int a=0; a<actions_.actionCount; a++)
{
Action *act = actions_.actions[a];
act->draw();
}
}
void ActionController::simulate(const unsigned state, float frameTime)
{
frameTime *= speed_;
// As this simulator gives differing results dependant on
// step size, always ensure step size is the same
stepTime_ += frameTime;
// step size = 1.0 / physics fps = steps per second
const float stepSize = 1.0f / float(context_->optionsGame->getPhysicsFPS());
while (stepTime_ >= stepSize)
{
time_ += stepSize;
stepActions(stepSize);
// More time has passed
stepTime_ -= stepSize;
}
}
void ActionController::stepActions(float frameTime)
{
// Ensure any new actions are added
addNewActions();
// Add any new events (if allowed)
if (time_ < 10.0f && !allEvents())
{
actionEvents_ = true;
events_.simulate(frameTime, *context_);
actionEvents_ = false;
}
// Move the targets
context_->targetMovement->simulate(frameTime);
// Itterate and draw all of the actions
int keepcount=0;
for (int a=0; a<actions_.actionCount; a++)
{
Action *act = actions_.actions[a];
bool remove = false;
act->simulate(frameTime, remove);
// Ensure that no referenced actions over do their time
if (act->getReferenced())
{
if ((time_ - act->getActionStartTime() > 30.0f))
{
Logger::log(formatString("Warning: removing timed out action %s",
act->getActionType()));
remove = true;
}
}
// If this action has finished add to list to be removed
if (remove)
{
if (act->getReferenced())
{
referenceCount_--;
if (referenceCount_<0) referenceCount_ = 0;
}
delete act;
}
else
{
actions_.actions[keepcount] = act;
keepcount++;
}
}
actions_.actionCount = keepcount;
}
See more files for this project here