deargui-vpl/ref/virtools/Includes/CKTimeManager.h

393 lines
16 KiB
C++

/*************************************************************************/
/* File : CKTimemanager.h */
/* Author : Romain Sididris */
/* */
/* A Manager to provide the same acces to time to behaviors */
/* The time as seen by behaviors can be the real time or clamped */
/* and stretched to slow or accelerate "real" time */
/* */
/* Virtools SDK */
/* Copyright (c) Virtools 2000, All Rights Reserved. */
/*************************************************************************/
#ifndef CKTIMEMANAGER_H
#define CKTIMEMANAGER_H "$Id:$"
#include "CKDefines.h"
#include "CKBaseManager.h"
#if _MSC_VER > 1000
#pragma warning(disable:4786)
#endif
/*******************************************************
{filename:CK_FRAMERATE_LIMITS}
Summary:Time limits settings
Remarks:
+ The default settings for the process loop is to
execute one behavioral process then one rendering (with
a synchonization to screen refresh rate).
+ Behavioral process and Rendering can have a maximum frame rate
in which case it is guaranteed the rendering and behavioral loop
will not be called more than the given fps time per second. The asked frame rate
may not be achieved but it will not be exceed.
See also:CKTimeManager
********************************************************/
typedef enum CK_FRAMERATE_LIMITS
{
CK_RATE_NOP = 0x00000000,
CK_BEHRATE_SYNC = 0x00000001, // Behavioral Rate is synchronized to frame rate
CK_BEHRATE_LIMIT = 0x00000004, // Behavioral Rate is limited to a maximum value (see CKTimeManager::SetBehavioralRateLimit)
CK_BEHRATE_MASK = 0x0000000F, // Mask for values concerning behavioral rate
CK_FRAMERATE_SYNC = 0x00000010, // Frame Rate is synchronized to screen refresh rate (Render function will wait for vertical blank signal)
CK_FRAMERATE_FREE = 0x00000020, // Frame Rate is free. Rendering occurs at the maximum possible rate.
CK_FRAMERATE_LIMIT = 0x00000040, // Frame Rate is limited to a maximum value (see CKTimeManager::SetFrameRateLimit)
CK_FRAMERATE_MASK = 0x000000F0, // Mask for values concerning frame rate
} CK_FRAMERATE_LIMITS;
/**************************************************************************
Name: CKTimeManager
Summary: Story and execution time management
Remarks:
+ The Time manager stores and updates time for the story but also real time.
+ Each frame the time manager computes the time elapsed since last process loop. This time
is then multiplied by the scale factor and clamped to a minimum
and maximum value to avoid extreme values which could produces jump in the playback if its time dependant.
This delta value is added to the current time to compute the absolute time elapsed since
the playback started.
+ The time as it appears to behaviors can be multiplied by a scale
factor and also be clamped to minimum and maximum values.
+ The CKContext::Pause,Reset,Play automatically call
the appropriate functions in CKTimeManager to pause and restart the timers.
+ Since the time taken to render a scene and execute the scripts can greatly vary
from one frame to another, it is recommended to perform time dependant actions rather
the frame dependant.
+ The unique instance of the time manager can be retrieved through the CKContext::GetTimeManager method
See also: Time Management,Creating a Standalone Application,CKContext::GetTimeManager
*****************************************************************************/
class CKTimeManager:public CKBaseManager {
public :
//*********** Processing **********************
/**************************************************
Summary: Returns the number of process loop (call to CKContext::Process()) since startup.
See also: GetTime,GetAbsoluteTime,GetLastDeltaTime,SetLastDeltaTime
***************************************************/
CKDWORD GetMainTickCount() { return m_MainTickCount; }
/**************************************************
Summary: Returns time elapsed since startup in milliseconds.
Remarks:
+ Use a high-precision timer to return the time elapsed since creation of this context.
+ The returned time does NOT take scale factors,minimum and maximum values into account.
+ The behaviors should not use this function but rather GetAbsoluteTime which takes scale factor into account.
Use only this function to be relative to the "real" time.
See also: GetAbsoluteTime,GetLastDeltaTime,SetLastDeltaTime
*****************************************************/
float GetTime() { return m_StartupChrono.Current(); }
/*******************************************************
Summary: Returns time elapsed since last frame in milliseconds.
Remarks:
+ The returned time takes scale factors,minimum and maximum values into account.
See also: GetTime,GetLastDeltaTime,SetMinimumDeltaTime,SetMaximumDeltaTime,SetTimeScaleFactor
*********************************************************/
float GetLastDeltaTime() { return m_DeltaTime; }
/*******************************************************
Summary: Returns real time elapsed since last frame in milliseconds.
Remarks:
+ The returned time does NOT takes scale factors,minimum and maximum values into account.
+ The behaviors should not use this function but rather GetLastDeltaTime which takes scale factor into account.
Use only this function to be relative to the "real" time. For example if between two frames an action takes
a very long time, the GetLastDeltaTime() method will return the maximum allowed delta time (GetMaximumDeltaTime)
while this method will return the exact time elapsed.
See also: GetTime,GetLastDeltaTime,SetLastDeltaTime,SetMinimumDeltaTime,SetMaximumDeltaTime,SetTimeScaleFactor
*********************************************************/
float GetLastDeltaTimeFree() { return m_DeltaTimeFree; }
/*********************************************************
Summary: Returns time elapsed since last call to CKContext::Reset() in milliseconds.
Remarks:
+ The returned time takes scale factors,minimum and maximum values into account.
See also: GetTime,GetLastDeltaTime,SetLastDeltaTime,SetMinimumDeltaTime,SetMaximumDeltaTime,SetTimeScaleFactor
**********************************************************/
float GetAbsoluteTime() { return m_PlayTime; }
//*********** Time scale factors **********************
/*********************************************************
Summary: Sets the time scaling factor.
Arguments:
mulfactor: A scale factor by which real time value will be multiplied.
Remarks:
+ All time dependant operations in behaviors use the time manager methods,
with a scale factor you can simulate a slower of faster time flow.
See also: GetTime,GetLastDeltaTime,SetLastDeltaTime,SetMinimumDeltaTime,SetMaximumDeltaTime,GetTimeScaleFactor
*********************************************************/
void SetTimeScaleFactor(float mulfactor) { m_TimeScaleFactor=mulfactor; }
/*********************************************************
Summary: Gets the time scaling factor.
Return Value: Current scale factor by which real time value is multiplied.
Remarks:
+ All time dependant operations in behaviors use the time manager methods,
with a scale factor you can simulate a slower of faster time flow.
See also: GetTime,GetLastDeltaTime,SetLastDeltaTime,SetMinimumDeltaTime,SetMaximumDeltaTime,SetTimeScaleFactor
*********************************************************/
float GetTimeScaleFactor() { return m_TimeScaleFactor; }
//------------ Limits --------------------
/****************************************************
Summary: Gets the rendering and behavioral frame rate limits.
Remarks:
+ Returns a combination of CK_FRAMERATE_LIMITS flags
specifying the behavioral and frame rate limits.
See Also:CK_FRAMERATE_LIMITS,ChangeLimitOptions
*****************************************************/
CKDWORD GetLimitOptions() { return m_LimitOptions; }
/****************************************************
Summary: Gets the frame rate limit
Return Value:
Maximum render loops per second.
Remarks:
+ This value is only used when the frame rate is limited (GetLimitOptions() & CK_FRAMERATE_LIMIT)
See Also:SetFrameRateLimit,GetLimitOptions,ChangeLimitOptions
*****************************************************/
float GetFrameRateLimit() { return m_LimitFrameRate; }
/****************************************************
Summary: Gets the behavioral rate limit
Return Value:
Maximum process loops per second.
Remarks:
+ This value is only used when the behavioral rate is limited (GetLimitOptions() & CK_BEHRATE_LIMIT)
See Also:SetBehavioralRateLimit,GetLimitOptions,ChangeLimitOptions
*****************************************************/
float GetBehavioralRateLimit() { return m_LimitBehRate; }
/****************************************************
Summary: Gets the minimum delta time.
Remarks:
+ Each frame the time manager computes the time elapsed since last process loop. This time
is then multiplied by the scale factor. This time are also be clamped to a minimum
and maximum value to avoid extreme values.
+ Default minimum delta time = 1 millisecond.
See Also:SetMinimumDeltaTime,GetMaximumDeltaTime
*****************************************************/
float GetMinimumDeltaTime() { return m_MinimumDeltaTime; }
/****************************************************
Summary: Gets the maximum delta time.
Remarks:
+ Each frame the time manager computes the time elapsed since last process loop. This time
is then multiplied by the scale factor. This time are also be clamped to a minimum
and maximum value to avoid extreme values.
+ Default maximum delta time = 200 millisecond.
See Also:GetMinimumDeltaTime,SetMaximumDeltaTime
*****************************************************/
float GetMaximumDeltaTime() { return m_MaximumDeltaTime; }
/****************************************************
Summary: Changes the rendering and behavioral frame rate limits.
Arguments:
FpsOptions: CK_FRAMERATE_SYNC to synchronize to screen refresh rate (Render
function will wait for vertical blank signal),CK_FRAMERATE_FREE to render
at the maximum possible rate or CK_FRAMERATE_LIMIT to set a maximum frame rate.
BehOptions: CK_BEHRATE_SYNC to synchronise the process loop with rendering (a behavioral processing is done
before each rendering) or CK_BEHRATE_LIMIT to set a maximum behavioral rate.
Remarks:
+ If the frame or behavioral rate is limited, the limits can be set by the
SetFrameRateLimit or SetBehavioralRateLimit methods.
See Also:CK_FRAMERATE_LIMITS,SetBehavioralRateLimit,SetFrameRateLimit,GetLimitOptions
*****************************************************/
void ChangeLimitOptions(CK_FRAMERATE_LIMITS FpsOptions,CK_FRAMERATE_LIMITS BehOptions=CK_RATE_NOP);
/****************************************************
Summary: Sets the frame rate limit
Arguments:
FRLimit: Maximum render loops per second.
Remarks:
+ This value is only used when the frame rate is limited (GetLimitOptions() & CK_FRAMERATE_LIMIT)
See Also:GetFrameRateLimit,GetLimitOptions,ChangeLimitOptions
*****************************************************/
void SetFrameRateLimit(float FRLimit);
/****************************************************
Summary: Sets the behavioral rate limit
Arguments:
BRLimit: Maximum process loops per second.
Remarks:
+ This value is only used when the behavioral rate is limited (GetLimitOptions() & CK_BEHRATE_LIMIT)
See Also:GetBehavioralRateLimit,GetLimitOptions,ChangeLimitOptions
*****************************************************/
void SetBehavioralRateLimit(float BRLimit);
/****************************************************
Summary: Sets the minimum delta time.
Arguments:
DtMax: Minimum value for the delta time in milliseconds.
Remarks:
+ Each frame the time manager computes the time elapsed since last process loop. This time
is then multiplied by the scale factor. This time are also be clamped to a minimum
and maximum value to avoid extreme values.
+ Default minimum delta time = 1 millisecond.
See Also:SetMaximumDeltaTime,GetMinimumDeltaTime
*****************************************************/
void SetMinimumDeltaTime(float DtMin);
/****************************************************
Summary: Sets the maximum delta time.
Arguments:
DtMax: Maximum value for the delta time in milliseconds.
Remarks:
+ Each frame the time manager computes the time elapsed since last process loop. This time
is then multiplied by the scale factor. This time are also be clamped to a minimum
and maximum value to avoid extreme values.
+ Default maximum delta time = 200 millisecond.
See Also:SetMinimumDeltaTime,GetMaximumDeltaTime
*****************************************************/
void SetMaximumDeltaTime(float DtMax);
/*******************************************************
Summary: Set the DeltaTime for custom use.
Remarks:
+This is usefull for special purposes.
See also: GetTime,GetLastDeltaTime,SetLastDeltaTime,SetMinimumDeltaTime,SetMaximumDeltaTime,SetTimeScaleFactor
*********************************************************/
void SetLastDeltaTime(float DtSet) { m_DeltaTime = DtSet; }
//----------------------------------------------------
//-- Runtime
/***************************************************************
Summary: Returns the time to wait to respect the time manager limits.
Arguments:
TimeBeforeRender: Time in milliseconds to wait before performing
a rendering.
TimeBeforeBeh: Time in milliseconds to wait before performing
a process loop.
Remarks:
+ This method returns the time to wait in milliseconds
to perfom a rendering or a process loop so that the
time manager limits are respected.
+ If the rendering or the behavioral process are not limited to given frame rate the
method returns 0 values.
Example
// This is a standard loop that takes potential frame rate limitats
// into account
CKTimeManager* TheTimeManager = TheContext->GetTimeManager();
while(1) {
float TimeBeforeRender=0,TimeBeforeBeh=0;
// Ask the time manager the time to wait before
// doing a render and a process
// if the time is positive we keep on looping
// without doing anything
TheTimeManager->GetTimeToWaitForLimits(TimeBeforeRender,TimeBeforeBeh);
BOOL DoBehaviors = (TimeBeforeBeh <=0);
BOOL DoRender = (TimeBeforeRender <=0);
// If a rendering or a behavioral process is done
// we restart the chronos for the next iteration
TheTimeManager->ResetChronos(DoRender,DoBehaviors);
if (DoBehaviors) TheCKContext->Process();
if (DoRender) TheRenderContext->Render();
}
See Also:Creating a Standalone Application
*****************************************************/
void GetTimeToWaitForLimits(float& TimeBeforeRender,float& TimeBeforeBeh);
void ResetChronos(CKBOOL RenderChrono,CKBOOL BehavioralChrono);
//-------------------------------------------------------------------------
// Internal functions
#ifdef DOCJETDUMMY // DOCJET secret macro
#else
virtual CKERROR PreProcess();
virtual CKERROR OnCKPlay();
virtual CKERROR OnCKPause();
virtual CKERROR OnCKReset();
virtual CKERROR PostClearAll();
virtual CKBOOL IsPaused();
virtual CKERROR LoadData(CKStateChunk *chunk,CKFile* LoadedFile);
virtual CKStateChunk* SaveData(CKFile *SavedFile);
virtual CKDWORD GetValidFunctionsMask() { return CKMANAGER_FUNC_OnCKPause|
CKMANAGER_FUNC_OnCKPlay|
CKMANAGER_FUNC_OnCKReset|
CKMANAGER_FUNC_PostClearAll|
CKMANAGER_FUNC_PreProcess; }
virtual int GetFunctionPriority(CKMANAGER_FUNCTIONS Function) { if (Function!=CKMANAGER_FUNC_PreProcess)
return DEFAULT_MANAGERFUNC_PRIORITY;
else return MAX_MANAGERFUNC_PRIORITY; }
CKTimeManager(CKContext *Context);
protected :
CKDWORD m_MainTickCount;
float m_LastTime,m_CurrentTime;
float m_PlayTime,m_DeltaTime;
//----------- Limits
float m_LimitFrameRate;
float m_LimitBehRate;
float m_MaximumDeltaTime;
float m_MinimumDeltaTime;
CKDWORD m_LimitOptions;
//--- Calculated from FPS Limitations
float m_LimitFPSDeltaTime;
float m_LimitBehDeltaTime;
CKBOOL m_Paused;
float m_TimeScaleFactor;
#ifdef PSP
VxTimeProfilerPSP m_BehChrono;
VxTimeProfilerPSP m_FpsChrono;
VxTimeProfilerPSP m_StartupChrono;
#else
VxTimeProfiler m_BehChrono;
VxTimeProfiler m_FpsChrono;
VxTimeProfiler m_StartupChrono;
#endif
float m_DeltaTimeFree;
#endif // Docjet secret macro
};
#endif