OpenGTA/opensteer/include/OpenSteer/Clock.h
Anonymous Maarten e20673c2cd 2007-04-16
2015-12-03 01:37:37 +01:00

206 lines
7.5 KiB
C++

// ----------------------------------------------------------------------------
//
//
// OpenSteer -- Steering Behaviors for Autonomous Characters
//
// Copyright (c) 2002-2005, Sony Computer Entertainment America
// Original author: Craig Reynolds <craig_reynolds@playstation.sony.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
//
// ----------------------------------------------------------------------------
//
//
// discrete time simulation clock for OpenSteerDemo
//
// Keeps track of real clock time and simulation time. Encapsulates the time
// API of the underlying operating system. Can be put in either "as fast as
// possible" variable time step mode (where simulation time steps are based on
// real time elapsed between updates), or in fixed "target FPS" mode where the
// simulation steps are constrained to start on 1/FPS boundaries (e.g. on a 60
// hertz video game console). Also handles the notion of "pausing" simulation
// time.
//
// Usage: allocate a clock, set its "paused" or "targetFPS" parameters, then
// call updateGlobalSimulationClock before each simulation step.
//
// 10-04-04 bk: put everything into the OpenSteer namespace
// 11-11-03 cwr: another overhaul: support aniamtion mode, switch to
// functional API, move smoothed stats inside this class
// 09-24-02 cwr: major overhaul
// 06-26-02 cwr: created
//
//
// ----------------------------------------------------------------------------
#ifndef OPENSTEER_CLOCK_H
#define OPENSTEER_CLOCK_H
#include "OpenSteer/Utilities.h"
#if defined (_XBOX)
#include <xtl.h>
#elif defined (_WIN32)
#include <windows.h>
#endif
namespace OpenSteer {
class Clock
{
public:
// constructor
Clock ();
// update this clock, called exactly once per simulation step ("frame")
void update (void);
// returns the number of seconds of real time (represented as a float)
// since the clock was first updated.
float realTimeSinceFirstClockUpdate (void);
// force simulation time ahead, ignoring passage of real time.
// Used for OpenSteerDemo's "single step forward" and animation mode
float advanceSimulationTimeOneFrame (void);
void advanceSimulationTime (const float seconds);
// "wait" until next frame time
void frameRateSync (void);
// main clock modes: variable or fixed frame rate, real-time or animation
// mode, running or paused.
private:
// run as fast as possible, simulation time is based on real time
bool variableFrameRateMode;
// fixed frame rate (ignored when in variable frame rate mode) in
// real-time mode this is a "target", in animation mode it is absolute
int fixedFrameRate;
// used for offline, non-real-time applications
bool animationMode;
// is simulation running or paused?
bool paused;
public:
int getFixedFrameRate (void) {return fixedFrameRate;}
int setFixedFrameRate (int ffr) {return fixedFrameRate = ffr;}
bool getAnimationMode (void) {return animationMode;}
bool setAnimationMode (bool am) {return animationMode = am;}
bool getVariableFrameRateMode (void) {return variableFrameRateMode;}
bool setVariableFrameRateMode (bool vfrm)
{return variableFrameRateMode = vfrm;}
bool togglePausedState (void) {return (paused = !paused);};
bool getPausedState (void) {return paused;};
bool setPausedState (bool newPS) {return paused = newPS;};
// clock keeps track of "smoothed" running average of recent frame rates.
// When a fixed frame rate is used, a running average of "CPU load" is
// kept (aka "non-wait time", the percentage of each frame time (time
// step) that the CPU is busy).
private:
float smoothedFPS;
float smoothedUsage;
void updateSmoothedRegisters (void)
{
const float rate = getSmoothingRate ();
if (elapsedRealTime > 0)
blendIntoAccumulator (rate, 1 / elapsedRealTime, smoothedFPS);
if (! getVariableFrameRateMode ())
blendIntoAccumulator (rate, getUsage (), smoothedUsage);
}
public:
float getSmoothedFPS (void) const {return smoothedFPS;}
float getSmoothedUsage (void) const {return smoothedUsage;}
float getSmoothingRate (void) const
{
if (smoothedFPS == 0) return 1; else return elapsedRealTime * 1.5f;
}
float getUsage (void)
{
// run time per frame over target frame time (as a percentage)
return ((100 * elapsedNonWaitRealTime) / (1.0f / fixedFrameRate));
}
// clock state member variables and public accessors for them
private:
// real "wall clock" time since launch
float totalRealTime;
// total time simulation has run
float totalSimulationTime;
// total time spent paused
float totalPausedTime;
// sum of (non-realtime driven) advances to simulation time
float totalAdvanceTime;
// interval since last simulation time
// (xxx does this need to be stored in the instance? xxx)
float elapsedSimulationTime;
// interval since last clock update time
// (xxx does this need to be stored in the instance? xxx)
float elapsedRealTime;
// interval since last clock update,
// exclusive of time spent waiting for frame boundary when targetFPS>0
float elapsedNonWaitRealTime;
public:
float getTotalRealTime (void) {return totalRealTime;}
float getTotalSimulationTime (void) {return totalSimulationTime;}
float getTotalPausedTime (void) {return totalPausedTime;}
float getTotalAdvanceTime (void) {return totalAdvanceTime;}
float getElapsedSimulationTime (void) {return elapsedSimulationTime;}
float getElapsedRealTime (void) {return elapsedRealTime;}
float getElapsedNonWaitRealTime (void) {return elapsedNonWaitRealTime;}
private:
// "manually" advance clock by this amount on next update
float newAdvanceTime;
// "Calendar time" when this clock was first updated
#ifdef _WIN32
// from QueryPerformanceCounter on Windows
LONGLONG basePerformanceCounter;
#else
// from gettimeofday on Linux and Mac OS X
int baseRealTimeSec;
int baseRealTimeUsec;
#endif
};
} // namespace OpenSteer
// ----------------------------------------------------------------------------
#endif // OPENSTEER_CLOCK_H