393 lines
16 KiB
C++
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
|
|
|