Removal and Replacement of the CryTimer (gEnv->pTimer) (#5409)

Replaced and removed the CryTimer (gEnv->pTimer). The new TimeSystem is a merger of the current time functionality found in the engine.

* Rename TimeSystemComponent.h/.cpp to TimeSystem.h/.cpp
* Adding New TimeSystem
* remove old timer cvars
* small improvements to the time system.
 - updated parts to use the time conversion functions.
 - in AdvanceTickDeltaTimes applying t_simulationTickScale is now uses doubles instead of floats.
* Replace gEnv->pTimer / ITimer usages with TimeSystem
* Updating usages of AZ::TimeMs{ 0 } and AZ::TimeUs{ 0 } to AZ::Time::ZeroTimeMs and AZ::Time::ZeroTimeUs
* red code the CryTimer
* using TimeUs instead of TimeMs is some cases + updating usages of old cvars to new

Signed-off-by: amzn-sean <75276488+amzn-sean@users.noreply.github.com>
This commit is contained in:
amzn-sean
2021-11-15 12:11:58 +00:00
committed by GitHub
parent 0ada8b335b
commit 38a03817bb
142 changed files with 1215 additions and 2090 deletions
@@ -89,7 +89,6 @@ inline int RoundToClosestMB(size_t memSize)
#include <IRenderer.h>
#include <CryFile.h>
#include <ISystem.h>
#include <ITimer.h>
#include <IXml.h>
#include <ICmdLine.h>
#include <IConsole.h>
@@ -19,6 +19,7 @@
#include <CryCommon/StaticInstance.h>
#include <AzCore/Debug/AssetTracking.h>
#include <AzCore/Time/ITime.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/IO/FileOperations.h>
#include <AzFramework/Entity/GameEntityContextBus.h>
@@ -553,8 +554,6 @@ ILevel* CLevelSystem::LoadLevelInternal(const char* _levelName)
// Not remove a scope!!!
{
//m_levelLoadStartTime = gEnv->pTimer->GetAsyncTime();
CLevelInfo* pLevelInfo = GetLevelInfoInternal(levelName);
if (!pLevelInfo)
@@ -693,7 +692,9 @@ void CLevelSystem::PrepareNextLevel(const char* levelName)
// This work not required in-editor.
if (!gEnv || !gEnv->IsEditor())
{
m_levelLoadStartTime = gEnv->pTimer->GetAsyncTime();
const AZ::TimeMs timeMs = AZ::GetRealElapsedTimeMs();
const double timeSec = AZ::TimeMsToSecondsDouble(timeMs);
m_levelLoadStartTime = CTimeValue(timeSec);
// Open pak file for a new level.
pLevelInfo->OpenLevelPak();
@@ -726,7 +727,8 @@ void CLevelSystem::OnLoadingStart(const char* levelName)
gEnv->pCryPak->RecordFileOpen(AZ::IO::IArchive::RFOM_Level);
}
m_fLastTime = gEnv->pTimer->GetAsyncCurTime();
const AZ::TimeMs timeMs = AZ::GetRealElapsedTimeMs();
m_fLastTime = AZ::TimeMsToSeconds(timeMs);
GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_START, 0, 0);
@@ -757,7 +759,9 @@ void CLevelSystem::OnLoadingError(const char* levelName, const char* error)
//------------------------------------------------------------------------
void CLevelSystem::OnLoadingComplete(const char* levelName)
{
CTimeValue t = gEnv->pTimer->GetAsyncTime();
const AZ::TimeMs timeMs = AZ::GetRealElapsedTimeMs();
const double timeSec = AZ::TimeMsToSecondsDouble(timeMs);
const CTimeValue t(timeSec);
m_fLastLevelLoadTime = (t - m_levelLoadStartTime).GetSeconds();
LogLoadingTime();
@@ -851,7 +855,7 @@ void CLevelSystem::UnloadLevel()
gEnv->pCryPak->DisableRuntimeFileAccess(false);
}
CTimeValue tBegin = gEnv->pTimer->GetAsyncTime();
const AZ::TimeMs beginTimeMs = AZ::GetRealElapsedTimeMs();
// Clear level entities and prefab instances.
EBUS_EVENT(AzFramework::GameEntityContextRequestBus, ResetGameContext);
@@ -889,8 +893,8 @@ void CLevelSystem::UnloadLevel()
m_bLevelLoaded = false;
CTimeValue tUnloadTime = gEnv->pTimer->GetAsyncTime() - tBegin;
CryLog("UnloadLevel End: %.1f sec", tUnloadTime.GetSeconds());
const AZ::TimeMs unloadTimeMs = AZ::GetRealElapsedTimeMs() - beginTimeMs;
CryLog("UnloadLevel End: %.1f sec", AZ::TimeMsToSeconds(unloadTimeMs));
// Must be sent last.
// Cleanup all containers
@@ -11,6 +11,7 @@
#include "ILevelSystem.h"
#include <AzFramework/Archive/IArchive.h>
#include <CryCommon/TimeValue.h>
// [LYN-2376] Remove the entire file once legacy slice support is removed
@@ -24,8 +24,8 @@
#include <AzCore/IO/Path/Path.h>
#include <AzCore/Settings/SettingsRegistryVisitorUtils.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzCore/Script/ScriptSystemBus.h>
#include <AzCore/Time/ITime.h>
namespace LegacyLevelSystem
{
@@ -368,7 +368,9 @@ namespace LegacyLevelSystem
// This work not required in-editor.
if (!gEnv || !gEnv->IsEditor())
{
m_levelLoadStartTime = gEnv->pTimer->GetAsyncTime();
const AZ::TimeMs timeMs = AZ::GetRealElapsedTimeMs();
const double timeSec = AZ::TimeMsToSecondsDouble(timeMs);
m_levelLoadStartTime = CTimeValue(timeSec);
// switched to level heap, so now imm start the loading screen (renderer will be reinitialized in the levelheap)
gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_START_LOADINGSCREEN, 0, 0);
@@ -409,7 +411,8 @@ namespace LegacyLevelSystem
gEnv->pCryPak->RecordFileOpen(AZ::IO::IArchive::RFOM_Level);
}
m_fLastTime = gEnv->pTimer->GetAsyncCurTime();
const AZ::TimeMs timeMs = AZ::GetRealElapsedTimeMs();
m_fLastTime = AZ::TimeMsToSeconds(timeMs);
GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_START, 0, 0);
@@ -433,7 +436,9 @@ namespace LegacyLevelSystem
//------------------------------------------------------------------------
void SpawnableLevelSystem::OnLoadingComplete(const char* levelName)
{
CTimeValue t = gEnv->pTimer->GetAsyncTime();
const AZ::TimeMs timeMs = AZ::GetRealElapsedTimeMs();
const double timeSec = AZ::TimeMsToSecondsDouble(timeMs);
const CTimeValue t(timeSec);
m_fLastLevelLoadTime = (t - m_levelLoadStartTime).GetSeconds();
LogLoadingTime();
@@ -532,7 +537,7 @@ namespace LegacyLevelSystem
gEnv->pCryPak->DisableRuntimeFileAccess(false);
}
CTimeValue tBegin = gEnv->pTimer->GetAsyncTime();
const AZ::TimeMs beginTimeMs = AZ::GetRealElapsedTimeMs();
// Clear level entities and prefab instances.
EBUS_EVENT(AzFramework::GameEntityContextRequestBus, ResetGameContext);
@@ -561,8 +566,8 @@ namespace LegacyLevelSystem
m_bLevelLoaded = false;
CTimeValue tUnloadTime = gEnv->pTimer->GetAsyncTime() - tBegin;
AZ_TracePrintf("LevelSystem", "UnloadLevel End: %.1f sec\n", tUnloadTime.GetSeconds());
const AZ::TimeMs unloadTimeMs = AZ::GetRealElapsedTimeMs() - beginTimeMs;
AZ_TracePrintf("LevelSystem", "UnloadLevel End: %.1f sec\n", AZ::TimeMsToSeconds(unloadTimeMs));
// Must be sent last.
// Cleanup all containers
@@ -12,6 +12,7 @@
#include <AzCore/Console/IConsole.h>
#include <AzFramework/Archive/IArchive.h>
#include <AzFramework/Spawnable/RootSpawnableInterface.h>
#include <CryCommon/TimeValue.h>
namespace LegacyLevelSystem
{
@@ -136,6 +136,44 @@ static const char* PLATFORM_INDEPENDENT_LANGUAGE_NAMES[ ILocalizationManager::eP
"da-DK" // Danish (Denmark)
};
#if defined(WIN32) || defined(WIN64)
namespace
{
#if defined(WIN32)
time_t gmt_to_local_win32(void)
{
TIME_ZONE_INFORMATION tzinfo;
DWORD dwStandardDaylight;
long bias;
dwStandardDaylight = GetTimeZoneInformation(&tzinfo);
bias = tzinfo.Bias;
if (dwStandardDaylight == TIME_ZONE_ID_STANDARD)
{
bias += tzinfo.StandardBias;
}
if (dwStandardDaylight == TIME_ZONE_ID_DAYLIGHT)
{
bias += tzinfo.DaylightBias;
}
return (-bias * 60);
}
#endif // #if defined(WIN32)
time_t DateToSecondsUTC(struct tm& inDate)
{
#if defined(WIN32)
return mktime(&inDate) + gmt_to_local_win32();
#else
return mktime(&inDate);
#endif // #if defined(WIN32)
}
}
#endif // #if defined(WIN32) || defined(WIN64)
//////////////////////////////////////////////////////////////////////////
#if !defined(_RELEASE)
static void ReloadDialogData([[maybe_unused]] IConsoleCmdArgs* pArgs)
@@ -2656,7 +2694,7 @@ void CLocalizedStringsManager::LocalizeTime(time_t t, bool bMakeLocalTime, bool
{
struct tm thetime;
localtime_s(&thetime, &t);
t = gEnv->pTimer->DateToSecondsUTC(thetime);
t = DateToSecondsUTC(thetime);
}
outTimeString.clear();
LCID lcID = g_currentLanguageID.lcID ? g_currentLanguageID.lcID : LOCALE_USER_DEFAULT;
@@ -2680,7 +2718,7 @@ void CLocalizedStringsManager::LocalizeDate(time_t t, bool bMakeLocalTime, bool
{
struct tm thetime;
localtime_s(&thetime, &t);
t = gEnv->pTimer->DateToSecondsUTC(thetime);
t = DateToSecondsUTC(thetime);
}
outDateString.resize(0);
LCID lcID = g_currentLanguageID.lcID ? g_currentLanguageID.lcID : LOCALE_USER_DEFAULT;
+28 -28
View File
@@ -22,6 +22,7 @@
#include <AzFramework/IO/FileOperations.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/Time/ITime.h>
#ifdef WIN32
#include <time.h>
@@ -503,7 +504,8 @@ void CLog::LogV(const ELogType type, [[maybe_unused]]int flags, const char* szFo
{
const int sz = sizeof(m_history) / sizeof(m_history[0]);
int i, j;
float time = m_pSystem->GetITimer()->GetCurrTime();
const AZ::TimeMs realTimeMs = AZ::GetRealElapsedTimeMs();
const float time = AZ::TimeMsToSeconds(realTimeMs);
for (i = m_iLastHistoryItem, j = 0; m_history[i].time > time - dt && j < sz; j++, i = i - 1 & sz - 1)
{
if (m_history[i].type != type)
@@ -908,7 +910,7 @@ void CLog::LogStringToFile(const char* szString, ELogType logType, bool bAdd, [[
}
#endif
if (m_pLogIncludeTime && gEnv && gEnv->pTimer)
if (m_pLogIncludeTime)
{
uint32 dwCVarState = m_pLogIncludeTime->GetIVal();
// char szTemp[MAX_TEMP_LENGTH_SIZE];
@@ -933,12 +935,12 @@ void CLog::LogStringToFile(const char* szString, ELogType logType, bool bAdd, [[
}
else if (dwCVarState == 2) // Log_IncludeTime
{
static CTimeValue lasttime;
CTimeValue currenttime = gEnv->pTimer->GetAsyncTime();
if (lasttime != CTimeValue())
static AZ::TimeMs lasttime = AZ::Time::ZeroTimeMs;
const AZ::TimeMs currenttime = AZ::GetRealElapsedTimeMs();
if (lasttime != AZ::Time::ZeroTimeMs)
{
timeStr.clear();
uint32 dwMs = (uint32)((currenttime - lasttime).GetMilliSeconds());
uint32 dwMs = aznumeric_cast<uint32>(currenttime - lasttime);
timeStr = AZStd::string::format("<%3d.%.3d>: ", dwMs / 1000, dwMs % 1000);
tempString = timeStr + tempString;
}
@@ -960,12 +962,12 @@ void CLog::LogStringToFile(const char* szString, ELogType logType, bool bAdd, [[
#endif
tempString = LogStringType(sTime) + tempString;
static CTimeValue lasttime;
CTimeValue currenttime = gEnv->pTimer->GetAsyncTime();
if (lasttime != CTimeValue())
static AZ::TimeMs lasttime = AZ::Time::ZeroTimeMs;
const AZ::TimeMs currenttime = AZ::GetRealElapsedTimeMs();
if (lasttime != AZ::Time::ZeroTimeMs)
{
timeStr.clear();
uint32 dwMs = (uint32)((currenttime - lasttime).GetMilliSeconds());
uint32 dwMs = (uint32)(currenttime - lasttime);
timeStr = AZStd::string::format("<%3d.%.3d>: ", dwMs / 1000, dwMs % 1000);
tempString = timeStr + tempString;
}
@@ -975,22 +977,19 @@ void CLog::LogStringToFile(const char* szString, ELogType logType, bool bAdd, [[
{
static bool bFirst = true;
if (gEnv->pTimer)
static AZ::TimeMs lasttime = AZ::Time::ZeroTimeMs;
const AZ::TimeMs currenttime = AZ::GetRealElapsedTimeMs();
if (lasttime != AZ::Time::ZeroTimeMs)
{
static CTimeValue lasttime;
CTimeValue currenttime = gEnv->pTimer->GetAsyncTime();
if (lasttime != CTimeValue())
{
timeStr.clear();
uint32 dwMs = (uint32)((currenttime - lasttime).GetMilliSeconds());
timeStr = AZStd::string::format("<%3d.%.3d>: ", dwMs / 1000, dwMs % 1000);
tempString = timeStr + tempString;
}
if (bFirst)
{
lasttime = currenttime;
bFirst = false;
}
timeStr.clear();
uint32 dwMs = (uint32)(currenttime - lasttime);
timeStr = AZStd::string::format("<%3d.%.3d>: ", dwMs / 1000, dwMs % 1000);
tempString = timeStr + tempString;
}
if (bFirst)
{
lasttime = currenttime;
bFirst = false;
}
}
else if (dwCVarState == 5) // Log_IncludeTime
@@ -1465,9 +1464,10 @@ void CLog::Update()
if (LogCVars::s_log_tick != 0)
{
static CTimeValue t0 = GetISystem()->GetITimer()->GetAsyncTime();
CTimeValue t1 = GetISystem()->GetITimer()->GetAsyncTime();
if (fabs((t1 - t0).GetSeconds()) > LogCVars::s_log_tick)
static AZ::TimeUs t0 = AZ::GetElapsedTimeUs();
const AZ::TimeUs t1 = AZ::GetElapsedTimeUs();
const float tSec = AZ::TimeUsToSeconds(t1 - t0);
if (tSec > LogCVars::s_log_tick)
{
t0 = t1;
+47 -36
View File
@@ -29,6 +29,7 @@
#include <AzCore/Debug/IEventLogger.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/std/algorithm.h>
#include <AzCore/Time/ITime.h>
#include <AzFramework/Logging/MissingAssetLogger.h>
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
#include <AzCore/Interface/Interface.h>
@@ -156,6 +157,16 @@ SSystemCVars g_cvars;
#include <AzCore/Component/ComponentApplication.h>
#include "AZCoreLogSink.h"
namespace
{
float GetMovieFrameDeltaTime()
{
// Use GetRealTickDeltaTimeUs for CryMovie, because it should not be affected by pausing game time
const AZ::TimeUs delta = AZ::GetRealTickDeltaTimeUs();
return AZ::TimeUsToSeconds(delta);
}
}
/////////////////////////////////////////////////////////////////////////////////
// System Implementation.
//////////////////////////////////////////////////////////////////////////
@@ -192,7 +203,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
//////////////////////////////////////////////////////////////////////////
// Initialize global environment interface pointers.
m_env.pSystem = this;
m_env.pTimer = &m_Time;
m_env.bIgnoreAllAsserts = false;
m_env.bNoAssertDialog = false;
@@ -563,14 +573,15 @@ ISystem* CSystem::GetCrySystem()
//////////////////////////////////////////////////////////////////////////
void CSystem::SleepIfNeeded()
{
ITimer* const pTimer = gEnv->pTimer;
static bool firstCall = true;
typedef MiniQueue<CTimeValue, 32> PrevNow;
static PrevNow prevNow;
if (firstCall)
{
m_lastTickTime = pTimer->GetAsyncTime();
const AZ::TimeMs timeMs = AZ::GetRealElapsedTimeMs();
const double timeSec = AZ::TimeMsToSecondsDouble(timeMs);
m_lastTickTime = CTimeValue(timeSec);
prevNow.Push(m_lastTickTime);
firstCall = false;
return;
@@ -578,8 +589,10 @@ void CSystem::SleepIfNeeded()
const float maxRate = m_svDedicatedMaxRate->GetFVal();
const float minTime = 1.0f / maxRate;
CTimeValue now = pTimer->GetAsyncTime();
float elapsed = (now - m_lastTickTime).GetSeconds();
const AZ::TimeMs nowTimeMs = AZ::GetRealElapsedTimeMs();
const double nowTimeSec = AZ::TimeMsToSecondsDouble(nowTimeMs);
const CTimeValue now = CTimeValue(nowTimeSec);
const float elapsed = (now - m_lastTickTime).GetSeconds();
if (prevNow.Full())
{
@@ -591,7 +604,9 @@ void CSystem::SleepIfNeeded()
if (elapsed > minTime && allowStallCatchup)
{
allowStallCatchup = false;
m_lastTickTime = pTimer->GetAsyncTime();
const AZ::TimeMs lastTimeMs = AZ::GetRealElapsedTimeMs();
const double lastTimeSec = AZ::TimeMsToSecondsDouble(lastTimeMs);
m_lastTickTime = CTimeValue(lastTimeSec);
return;
}
allowStallCatchup = true;
@@ -607,7 +622,9 @@ void CSystem::SleepIfNeeded()
Sleep(sleepMS);
}
m_lastTickTime = pTimer->GetAsyncTime();
const AZ::TimeMs lastTimeMs = AZ::GetRealElapsedTimeMs();
const double lastTimeSec = AZ::TimeMsToSecondsDouble(lastTimeMs);
m_lastTickTime = CTimeValue(lastTimeSec);
}
extern DWORD g_idDebugThreads[];
@@ -734,24 +751,21 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
if (maxFPS > 0 && vSync == 0)
{
CTimeValue timeFrameMax;
const float safeMarginFPS = 0.5f;//save margin to not drop below 30 fps
static CTimeValue sTimeLast = gEnv->pTimer->GetAsyncTime();
timeFrameMax.SetMilliSeconds((int64)(1000.f / ((float)maxFPS + safeMarginFPS)));
const CTimeValue timeLast = timeFrameMax + sTimeLast;
while (timeLast.GetValue() > gEnv->pTimer->GetAsyncTime().GetValue())
static AZ::TimeMs sTimeLast = AZ::GetRealElapsedTimeMs();
const AZ::TimeMs timeFrameMax(static_cast<AZ::TimeMs>(
(int64)(1000.f / ((float)maxFPS + safeMarginFPS))
));
const AZ::TimeMs timeLast = timeFrameMax + sTimeLast;
while (timeLast > AZ::GetRealElapsedTimeMs())
{
CrySleep(0);
}
sTimeLast = gEnv->pTimer->GetAsyncTime();
sTimeLast = AZ::GetRealElapsedTimeMs();
}
}
}
//////////////////////////////////////////////////////////////////////
//update time subsystem
m_Time.UpdateOnFrameStart();
//////////////////////////////////////////////////////////////////////
//update console system
if (m_env.pConsole)
@@ -765,13 +779,10 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
return false;
}
// Use UI timer for CryMovie, because it should not be affected by pausing game time
const float fMovieFrameTime = m_Time.GetFrameTime(ITimer::ETIMER_UI);
// Run movie system pre-update
if (!bNoUpdate)
{
UpdateMovieSystem(updateFlags, fMovieFrameTime, true);
UpdateMovieSystem(updateFlags, GetMovieFrameDeltaTime(), true);
}
return !IsQuitting();
@@ -780,13 +791,14 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
//////////////////////////////////////////////////////////////////////
bool CSystem::UpdatePostTickBus(int updateFlags, int /*nPauseMode*/)
{
CTimeValue updateStart = gEnv->pTimer->GetAsyncTime();
const AZ::TimeMs updateStartTimeMs = AZ::GetRealElapsedTimeMs();
const double updateStartTimeSec = AZ::TimeMsToSecondsDouble(updateStartTimeMs);
const CTimeValue updateStart(updateStartTimeSec);
// Run movie system post-update
if (!m_bNoUpdate)
{
const float fMovieFrameTime = m_Time.GetFrameTime(ITimer::ETIMER_UI);
UpdateMovieSystem(updateFlags, fMovieFrameTime, false);
UpdateMovieSystem(updateFlags, GetMovieFrameDeltaTime(), false);
}
//////////////////////////////////////////////////////////////////////
@@ -797,7 +809,9 @@ bool CSystem::UpdatePostTickBus(int updateFlags, int /*nPauseMode*/)
}
//Now update frame statistics
CTimeValue cur_time = gEnv->pTimer->GetAsyncTime();
const AZ::TimeMs curTimeMs = AZ::GetRealElapsedTimeMs();
const double curTimeSec = AZ::TimeMsToSecondsDouble(curTimeMs);
const CTimeValue cur_time(curTimeSec);
CTimeValue a_second(g_cvars.sys_update_profile_time);
std::vector< std::pair<CTimeValue, float> >::iterator it = m_updateTimes.begin();
@@ -1366,19 +1380,16 @@ const char* CSystem::GetSystemGlobalStateName(const ESystemGlobalState systemGlo
void CSystem::SetSystemGlobalState(const ESystemGlobalState systemGlobalState)
{
static CTimeValue s_startTime = CTimeValue();
static AZ::TimeMs s_startTime = AZ::Time::ZeroTimeMs;
if (systemGlobalState != m_systemGlobalState)
{
if (gEnv && gEnv->pTimer)
{
const CTimeValue endTime = gEnv->pTimer->GetAsyncTime();
[[maybe_unused]] const float numSeconds = endTime.GetDifferenceInSeconds(s_startTime);
CryLog("SetGlobalState %d->%d '%s'->'%s' %3.1f seconds",
m_systemGlobalState, systemGlobalState,
CSystem::GetSystemGlobalStateName(m_systemGlobalState), CSystem::GetSystemGlobalStateName(systemGlobalState),
numSeconds);
s_startTime = gEnv->pTimer->GetAsyncTime();
}
const AZ::TimeMs endTime = AZ::GetRealElapsedTimeMs();
[[maybe_unused]] const double numSeconds = AZ::TimeMsToSecondsDouble(endTime - s_startTime);
CryLog("SetGlobalState %d->%d '%s'->'%s' %3.1f seconds",
m_systemGlobalState, systemGlobalState,
CSystem::GetSystemGlobalStateName(m_systemGlobalState), CSystem::GetSystemGlobalStateName(systemGlobalState),
numSeconds);
s_startTime = AZ::GetRealElapsedTimeMs();
}
m_systemGlobalState = systemGlobalState;
+2 -3
View File
@@ -13,7 +13,6 @@
#include <IRenderer.h>
#include <IWindowMessageHandler.h>
#include "Timer.h"
#include <CryVersion.h>
#include "CmdLine.h"
@@ -23,6 +22,8 @@
#include <AzCore/Module/DynamicModuleHandle.h>
#include <AzCore/Math/Crc.h>
#include <CryCommon/TimeValue.h>
#include <list>
#include <map>
@@ -226,7 +227,6 @@ public:
int GetApplicationInstance() override;
int GetApplicationLogInstance(const char* logFilePath) override;
ITimer* GetITimer() override{ return m_env.pTimer; }
AZ::IO::IArchive* GetIPak() override { return m_env.pCryPak; };
IConsole* GetIConsole() override { return m_env.pConsole; };
IRemoteConsole* GetIRemoteConsole() override;
@@ -382,7 +382,6 @@ private: // ------------------------------------------------------
// System environment.
SSystemGlobalEnvironment m_env;
CTimer m_Time; //!<
bool m_bInitializedSuccessfully; //!< true if the system completed all initialization steps
bool m_bRelaunch; //!< relaunching the app or not (true beforerelaunch)
int m_iLoadingMode; //!< Game is loading w/o changing context (0 not, 1 quickloading, 2 full loading)
-11
View File
@@ -1099,17 +1099,6 @@ AZ_POP_DISABLE_WARNING
AzFramework::SystemCursorState::ConstrainedAndHidden);
}
//////////////////////////////////////////////////////////////////////////
// TIME
//////////////////////////////////////////////////////////////////////////
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Time initialization");
if (!m_Time.Init())
{
AZ_Assert(false, "Failed to initialize CTimer instance.");
return false;
}
m_Time.ResetTimer();
// CONSOLE
//////////////////////////////////////////////////////////////////////////
if (!InitConsole())
-725
View File
@@ -1,725 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "CrySystem_precompiled.h"
#include "Timer.h"
#include <time.h>
#include <ISystem.h>
#include <IConsole.h>
#include <ILog.h>
#include <ISerialize.h>
/////////////////////////////////////////////////////
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#include "Mmsystem.h"
#endif
//#define PROFILING 1
#ifdef PROFILING
static int64 g_lCurrentTime = 0;
#endif
//! Profile smoothing time in seconds (original default was .8 / log(10) ~= .35 s)
static const float fDEFAULT_PROFILE_SMOOTHING = 1.0f;
#define DEFAULT_FRAME_SMOOTHING 1
/////////////////////////////////////////////////////
CTimer::CTimer()
{
// Default CVar values
m_fixed_time_step = 0;
m_max_time_step = 0.25f;
m_cvar_time_scale = 1.0f;
m_TimeSmoothing = DEFAULT_FRAME_SMOOTHING; // note: frame numbers (old version - commented out) are not used but is based on time
m_TimeDebug = 0;
m_profile_smooth_time = fDEFAULT_PROFILE_SMOOTHING;
m_profile_weighting = 1;
// Persistant state
m_bEnabled = true;
//m_fixedTimeModeEnabled = false;
m_nFrameCounter = 0;
m_lTicksPerSec = CryGetTicksPerSec();
m_fSecsPerTick = 1.0 / m_lTicksPerSec;
m_fAverageFrameTime = 1.0f / 30.0f;
for (int i = 0; i < MAX_FRAME_AVERAGE; i++)
{
m_arrFrameTimes[i] = m_fAverageFrameTime;
}
m_fAvgFrameTime = 0.0f;
m_fProfileBlend = 1.0f;
m_fSmoothTime = 0;
m_totalTimeScale = 1.0f;
ClearTimeScales();
ResetTimer();
}
/////////////////////////////////////////////////////
bool CTimer::Init()
{
// if game code was accessing them by name there was something wrong anyway
REGISTER_CVAR2("t_Smoothing", &m_TimeSmoothing, DEFAULT_FRAME_SMOOTHING, 0,
"time smoothing\n"
"0=off, 1=on");
REGISTER_CVAR2("t_FixedStep", &m_fixed_time_step, 0, VF_NET_SYNCED | VF_DEV_ONLY,
"Game updated with this fixed frame time\n"
"0=off, number specifies the frame time in seconds\n"
"e.g. 0.033333(30 fps), 0.1(10 fps), 0.01(100 fps)");
REGISTER_CVAR2("t_MaxStep", &m_max_time_step, 0.25f, 0,
"Game systems clamped to this frame time");
// todo: reconsider exposing that as cvar (negative time, same value is used by Trackview, better would be another value multipled with the internal one)
REGISTER_CVAR2("t_Scale", &m_cvar_time_scale, 1.0f, VF_NET_SYNCED | VF_DEV_ONLY,
"Game time scaled by this - for variable slow motion");
REGISTER_CVAR2("t_Debug", &m_TimeDebug, 0, 0, "Timer debug: 0 = off, 1 = events, 2 = verbose");
// -----------------
REGISTER_CVAR2("profile_smooth", &m_profile_smooth_time, fDEFAULT_PROFILE_SMOOTHING, 0,
"Profiler exponential smoothing interval (seconds)");
REGISTER_CVAR2("profile_weighting", &m_profile_weighting, 1, 0,
"Profiler smoothing mode: 0 = legacy, 1 = average, 2 = peak weighted, 3 = peak hold");
return true;
}
/////////////////////////////////////////////////////
float CTimer::GetFrameTime(ETimer which) const
{
float result = 0.0f;
if (m_bEnabled)
{
if (which != ETIMER_GAME || !m_bGameTimerPaused)
{
if (which == ETIMER_UI)
{
result = m_fRealFrameTime;
}
else
{
result = m_fFrameTime;
}
}
}
return result;
}
/////////////////////////////////////////////////////
float CTimer::GetCurrTime(ETimer which) const
{
assert(which >= 0 && which < ETIMER_LAST && "Bad timer index");
return m_CurrTime[which].GetSeconds();
}
/////////////////////////////////////////////////////
float CTimer::GetRealFrameTime() const
{
return m_bEnabled ? m_fRealFrameTime : 0.0f;
}
/////////////////////////////////////////////////////
float CTimer::GetTimeScale() const
{
return m_cvar_time_scale * m_totalTimeScale;
}
/////////////////////////////////////////////////////
float CTimer::GetTimeScale(uint32 channel) const
{
assert(channel < NUM_TIME_SCALE_CHANNELS);
if (channel >= NUM_TIME_SCALE_CHANNELS)
{
return GetTimeScale();
}
return m_cvar_time_scale * m_timeScaleChannels[channel];
}
/////////////////////////////////////////////////////
void CTimer::SetTimeScale(float scale, uint32 channel /* = 0 */)
{
assert(channel < NUM_TIME_SCALE_CHANNELS);
if (channel >= NUM_TIME_SCALE_CHANNELS)
{
return;
}
const float currentScale = m_timeScaleChannels[channel];
if (scale != currentScale)
{
// Need to adjust previous frame times for time scale to have immediate effect
const float adjustFactor = scale / currentScale;
for (uint32 i = 0; i < MAX_FRAME_AVERAGE; ++i)
{
m_arrFrameTimes[i] *= adjustFactor;
}
// Update total time scale immediately
m_totalTimeScale *= adjustFactor;
}
m_timeScaleChannels[channel] = scale;
}
/////////////////////////////////////////////////////
void CTimer::ClearTimeScales()
{
if (m_totalTimeScale != 1.0f)
{
// Need to adjust previous frame times for time scale to have immediate effect
const float adjustFactor = 1.0f / m_totalTimeScale;
for (uint32 i = 0; i < MAX_FRAME_AVERAGE; ++i)
{
m_arrFrameTimes[i] *= adjustFactor;
}
}
for (int i = 0; i < NUM_TIME_SCALE_CHANNELS; ++i)
{
m_timeScaleChannels[i] = 1.0f;
}
m_totalTimeScale = 1.0f;
}
/////////////////////////////////////////////////////
float CTimer::GetAsyncCurTime()
{
//int64 llNow = CryGetTicks() - m_lBaseTime_Async;
int64 llNow = CryGetTicks() - m_lBaseTime;
return TicksToSeconds(llNow);
}
/////////////////////////////////////////////////////
float CTimer::GetFrameRate()
{
// Use real frame time.
if (m_fRealFrameTime != 0.f)
{
return 1.f / m_fRealFrameTime;
}
return 0.f;
}
void CTimer::UpdateBlending()
{
// Accumulate smoothing time up to specified max.
float fFrameTime = m_fRealFrameTime;
m_fSmoothTime = min(m_fSmoothTime + fFrameTime, m_profile_smooth_time);
if (m_fSmoothTime <= fFrameTime)
{
m_fAvgFrameTime = fFrameTime;
m_fProfileBlend = 1.f;
return;
}
if (m_profile_weighting <= 2)
{
// Update average frame time.
if (m_fSmoothTime < m_fAvgFrameTime)
{
m_fAvgFrameTime = m_fSmoothTime;
}
m_fAvgFrameTime *= m_fSmoothTime / (m_fSmoothTime - fFrameTime + m_fAvgFrameTime);
if (m_profile_weighting == 1)
{
// Weight all frames equally.
m_fProfileBlend = m_fAvgFrameTime / m_fSmoothTime;
}
else
{
// Weight frames by time.
m_fProfileBlend = fFrameTime / m_fSmoothTime;
}
}
else
{
// Decay avg frame time, set as new peak.
m_fAvgFrameTime *= 1.f - fFrameTime / m_fSmoothTime;
if (fFrameTime > m_fAvgFrameTime)
{
m_fAvgFrameTime = fFrameTime;
m_fProfileBlend = 1.f;
}
else
{
m_fProfileBlend = 0.f;
}
}
}
float CTimer::GetProfileFrameBlending(float* pfBlendTime, int* piBlendMode)
{
if (piBlendMode)
{
*piBlendMode = m_profile_weighting;
}
if (pfBlendTime)
{
*pfBlendTime = m_fSmoothTime;
}
return m_fProfileBlend;
}
/////////////////////////////////////////////////////
void CTimer::RefreshGameTime(int64 curTime)
{
assert(curTime + m_lOffsetTime >= 0);
m_CurrTime[ETIMER_GAME].SetSeconds(TicksToSeconds(curTime + m_lOffsetTime));
}
/////////////////////////////////////////////////////
void CTimer::RefreshUITime(int64 curTime)
{
assert(curTime >= 0);
m_CurrTime[ETIMER_UI].SetSeconds(TicksToSeconds(curTime));
}
/////////////////////////////////////////////////////
void CTimer::UpdateOnFrameStart()
{
if (!m_bEnabled)
{
return;
}
//int64 now;
//if (m_fixedTimeModeEnabled)
//{
// m_nFrameCounter++;
// m_fRealFrameTime = m_fFrameTime = m_fixedTimeModeStep;
// m_lCurrentTime += m_fixedTimeModeStep*m_lTicksPerSec;
// now = m_lCurrentTime;
//}
//else
//{
// On Windows before Vista, frequency can change (even though it should be impossible),
// See also: https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
// Win2000, WinXP: Uses RDTSC, which may not be monotonic across all cores (a bug), costs in the order of 10~100 cycles (cheap).
// WinVista: Uses HPET or ACPI timer (a kernel call, and much more expensive than RDTSC, but it's not bugged).
// Win7+: RDTSC if the CPU feature bit for monotonic is set, HPET or ACPI otherwise (not bugged).
#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
if ((m_nFrameCounter & 127) == 0)
{
// every bunch of frames, check frequency to adapt to
// CPU power management clock rate changes
LARGE_INTEGER TTicksPerSec;
if (QueryPerformanceFrequency(&TTicksPerSec))
{
// if returns false, no performance counter is available
m_lTicksPerSec = TTicksPerSec.QuadPart;
m_fSecsPerTick = 1.0 / m_lTicksPerSec;
}
}
m_nFrameCounter++;
#endif
//}
#ifdef PROFILING
m_fRealFrameTime = m_fFrameTime = 0.020f; // 20ms = 50fps
g_lCurrentTime += (int)(m_fFrameTime * (float)(CTimeValue::TIMEVALUE_PRECISION));
m_lLastTime = g_lCurrentTime;
RefreshGameTime(m_lLastTime);
RefreshUITime(m_lLastTime);
return;
#endif
if (m_fixed_time_step < 0.0f)
{
// Enforce real framerate by sleeping.
const int64 elapsedTicks = CryGetTicks() - m_lBaseTime - m_lLastTime;
const int64 minTicks = SecondsToTicks(-m_fixed_time_step);
if (elapsedTicks < minTicks)
{
const int64 ms = (minTicks - elapsedTicks) * 1000 / m_lTicksPerSec;
CrySleep((unsigned int)ms);
}
}
const int64 now = CryGetTicks();
assert(now + 1 >= m_lBaseTime && "Invalid base time"); //+1 margin because QPC may be one off across cores
m_fRealFrameTime = TicksToSeconds(now - m_lBaseTime - m_lLastTime);
if (0.0f != m_fixed_time_step)
{
// Apply fixed_time_step
m_fFrameTime = abs(m_fixed_time_step);
}
else
{
// Clamp to max_time_step
m_fFrameTime = min(m_fRealFrameTime, m_max_time_step);
}
// Dilate time.
m_fFrameTime *= GetTimeScale();
if (m_TimeSmoothing > 0)
{
m_fFrameTime = GetAverageFrameTime();
}
// Time can only go forward.
if (m_fFrameTime < 0.0f)
{
m_fFrameTime = 0.0f;
}
if (m_fRealFrameTime < 0.0f)
{
m_fRealFrameTime = 0.0;
}
// Adjust the base time so that time actually seems to have moved forward m_fFrameTime
const int64 frameTicks = SecondsToTicks(m_fFrameTime);
const int64 realTicks = SecondsToTicks(m_fRealFrameTime);
m_lBaseTime += realTicks - frameTicks;
if (m_lBaseTime > now)
{
// Guard against rounding errors due to float <-> int64 precision
assert(m_lBaseTime - now <= 10 && "Bad base time or adjustment, too much difference for a rounding error");
m_lBaseTime = now;
}
const int64 currentTime = now - m_lBaseTime;
assert(fabsf(TicksToSeconds(currentTime - m_lLastTime) - m_fFrameTime) < 0.01f && "Bad calculation");
assert(currentTime >= m_lLastTime && "Bad adjustment in previous frame");
assert(currentTime + m_lOffsetTime >= 0 && "Sum of game time is negative");
// Update timers
RefreshUITime(currentTime);
if (!m_bGameTimerPaused)
{
RefreshGameTime(currentTime);
}
m_lLastTime = currentTime;
UpdateBlending();
if (m_TimeDebug > 1)
{
CryLogAlways("[CTimer]: Cur=%lld Now=%lld Off=%lld Async=%f CurrTime=%f UI=%f", (long long)currentTime, (long long)now, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI));
}
}
//------------------------------------------------------------------------
//-- average frame-times to avoid stalls and peaks in framerate
//-- note that is is time-base averaging and not frame-based
//------------------------------------------------------------------------
float CTimer::GetAverageFrameTime()
{
f32 LastAverageFrameTime = m_fAverageFrameTime;
f32 FrameTime = m_fFrameTime;
uint32 numFT = MAX_FRAME_AVERAGE;
for (int32 i = (numFT - 2); i > -1; i--)
{
m_arrFrameTimes[i + 1] = m_arrFrameTimes[i];
}
if (FrameTime > 0.4f)
{
FrameTime = 0.4f;
}
if (FrameTime < 0.0f)
{
FrameTime = 0.0f;
}
m_arrFrameTimes[0] = FrameTime;
//get smoothed frame
uint32 avrg_ftime = 1;
if (LastAverageFrameTime)
{
avrg_ftime = uint32(0.25f / LastAverageFrameTime + 0.5f); //average the frame-times for a certain time-period (sec)
if (avrg_ftime > numFT)
{
avrg_ftime = numFT;
}
if (avrg_ftime < 1)
{
avrg_ftime = 1;
}
}
f32 AverageFrameTime = 0;
for (uint32 i = 0; i < avrg_ftime; i++)
{
AverageFrameTime += m_arrFrameTimes[i];
}
AverageFrameTime /= avrg_ftime;
//don't smooth if we pause the game
if (FrameTime < 0.0001f)
{
AverageFrameTime = FrameTime;
}
m_fAverageFrameTime = AverageFrameTime;
return AverageFrameTime;
}
/////////////////////////////////////////////////////
void CTimer::ResetTimer()
{
m_lBaseTime = CryGetTicks();
//m_lBaseTime_Async = CryGetTicks();
m_lLastTime = 0;
m_lOffsetTime = 0;
m_fFrameTime = 0.0f;
m_fRealFrameTime = 0.0f;
RefreshGameTime(0);
RefreshUITime(0);
m_bGameTimerPaused = false;
m_lGameTimerPausedTime = 0;
}
/////////////////////////////////////////////////////
void CTimer::EnableTimer(bool bEnable)
{
m_bEnabled = bEnable;
}
bool CTimer::IsTimerEnabled() const
{
return m_bEnabled;
}
/////////////////////////////////////////////////////
CTimeValue CTimer::GetAsyncTime() const
{
int64 llNow = CryGetTicks();
double fConvert = CTimeValue::TIMEVALUE_PRECISION * m_fSecsPerTick;
return CTimeValue(int64(llNow * fConvert));
}
/////////////////////////////////////////////////////
void CTimer::Serialize(TSerialize ser)
{
// cannot change m_lBaseTime, as this is used for async time (which shouldn't be affected by save games)
if (ser.IsWriting())
{
int64 currentGameTime = m_lLastTime + m_lOffsetTime;
ser.Value("curTime", currentGameTime);
ser.Value("ticksPerSecond", m_lTicksPerSec);
}
else
{
int64 ticksPerSecond = 1, curTime = 1;
ser.Value("curTime", curTime);
ser.Value("ticksPerSecond", ticksPerSecond);
// Adjust curTime for ticksPerSecond on this machine.
// Some precision will be lost if the frequencies are not identical.
const double multiplier = (double)m_lTicksPerSec / (double)ticksPerSecond;
curTime = (int64)((double)curTime * multiplier);
SetOffsetToMatchGameTime(curTime);
if (m_TimeDebug)
{
[[maybe_unused]] const int64 now = CryGetTicks();
CryLogAlways("[CTimer]: Serialize: Last=%lld Now=%lld Off=%lld Async=%f CurrTime=%f UI=%f", (long long)m_lLastTime, (long long)now, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI));
}
}
}
//! try to pause/unpause a timer
// returns true if successfully paused/unpaused, false otherwise
bool CTimer::PauseTimer(ETimer which, bool bPause)
{
if (which != ETIMER_GAME)
{
return false;
}
if (m_bGameTimerPaused == bPause)
{
return false;
}
m_bGameTimerPaused = bPause;
if (bPause)
{
m_lGameTimerPausedTime = m_lLastTime + m_lOffsetTime;
if (m_TimeDebug)
{
CryLogAlways("[CTimer]: Pausing ON: Last=%lld Off=%lld Async=%f CurrTime=%f UI=%f", (long long)m_lLastTime, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI));
}
}
else
{
SetOffsetToMatchGameTime(m_lGameTimerPausedTime);
m_lGameTimerPausedTime = 0;
if (m_TimeDebug)
{
CryLogAlways("[CTimer]: Pausing OFF: Last=%lld Off=%lld Async=%f CurrTime=%f UI=%f", (long long)m_lLastTime, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI));
}
}
return true;
}
//! determine if a timer is paused
// returns true if paused, false otherwise
bool CTimer::IsTimerPaused(ETimer which)
{
if (which != ETIMER_GAME)
{
return false;
}
return m_bGameTimerPaused;
}
//! try to set a timer
// return true if successful, false otherwise
bool CTimer::SetTimer(ETimer which, float timeInSeconds)
{
if (which != ETIMER_GAME)
{
return false;
}
SetOffsetToMatchGameTime(SecondsToTicks(timeInSeconds));
return true;
}
ITimer* CTimer::CreateNewTimer()
{
return new CTimer();
}
void CTimer::SecondsToDateUTC(time_t inTime, struct tm& outDateUTC)
{
#ifdef AZ_COMPILER_MSVC
gmtime_s(&outDateUTC, &inTime);
#else
outDateUTC = *gmtime(&inTime);
#endif
}
#if defined (WIN32) || defined(WIN64)
time_t gmt_to_local_win32(void)
{
TIME_ZONE_INFORMATION tzinfo;
DWORD dwStandardDaylight;
long bias;
dwStandardDaylight = GetTimeZoneInformation(&tzinfo);
bias = tzinfo.Bias;
if (dwStandardDaylight == TIME_ZONE_ID_STANDARD)
{
bias += tzinfo.StandardBias;
}
if (dwStandardDaylight == TIME_ZONE_ID_DAYLIGHT)
{
bias += tzinfo.DaylightBias;
}
return (-bias * 60);
}
#endif
time_t CTimer::DateToSecondsUTC(struct tm& inDate)
{
#if defined (WIN32)
return mktime(&inDate) + gmt_to_local_win32();
#elif defined (LINUX)
#if defined (HAVE_TIMEGM)
// return timegm(&inDate);
#else
// craig: temp disabled the +tm.tm_gmtoff because i can't see the intention here
// and it doesn't compile anymore
// alexl: tm_gmtoff is the offset to greenwhich mean time, whereas mktime uses localtime
// but not all linux distributions have it...
return mktime(&inDate) /*+ tm.tm_gmtoff*/;
#endif
#else
return mktime(&inDate);
#endif
}
void CTimer::EnableFixedTimeMode([[maybe_unused]] bool enable, [[maybe_unused]] float timeStep)
{
//if (enable)
//{
// m_fixedTimeModeEnabled = true;
// m_fixedTimeModeStep = timeStep;
// m_lBaseTime =0;
// m_lBaseTime_Async = 0;
// m_lLastTime = m_lCurrentTime = 0;
// m_fRealFrameTime = m_fFrameTime = timeStep;
// RefreshGameTime(m_lCurrentTime);
// RefreshUITime(m_lCurrentTime);
// m_lForcedGameTime = -1;
// m_bGameTimerPaused = false;
// m_lGameTimerPausedTime = 0;
//}
//else
//{
// m_fixedTimeModeEnabled = false;
// ResetTimer();
//}
}
void CTimer::SetOffsetToMatchGameTime(int64 ticks)
{
[[maybe_unused]] const int64 previousOffset = m_lOffsetTime;
[[maybe_unused]] const float previousGameTime = GetCurrTime(ETIMER_GAME);
m_lOffsetTime = ticks - m_lLastTime;
RefreshGameTime(m_lLastTime);
if (m_bGameTimerPaused)
{
// On un-pause, we will restore the specified time.
// If we don't do this, the un-pause will over-write the offset again.
m_lGameTimerPausedTime = ticks;
}
if (m_TimeDebug)
{
CryLogAlways("[CTimer] SetOffset: Offset %lld -> %lld, GameTime %f -> %f", (long long)previousOffset, (long long)m_lOffsetTime, GetCurrTime(ETIMER_GAME), previousGameTime);
}
}
int64 CTimer::SecondsToTicks(double seconds) const
{
return (int64)(seconds * (double)m_lTicksPerSec);
}
-166
View File
@@ -1,166 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_CRYSYSTEM_TIMER_H
#define CRYINCLUDE_CRYSYSTEM_TIMER_H
# pragma once
#include <ITimer.h>
// Implements all common timing routines
class CTimer
: public ITimer
{
public:
// constructor
CTimer();
// destructor
~CTimer() = default;
bool Init();
// interface ITimer ----------------------------------------------------------
// TODO: Review m_time usage in System.cpp
// if it wants Game Time / UI Time or a new Render Time?
void ResetTimer() override;
void UpdateOnFrameStart() override;
float GetCurrTime(ETimer which = ETIMER_GAME) const override;
CTimeValue GetAsyncTime() const override;
float GetAsyncCurTime() override; // retrieve the actual wall clock time passed since the game started, in seconds
float GetFrameTime(ETimer which = ETIMER_GAME) const override;
float GetRealFrameTime() const override;
float GetTimeScale() const override;
float GetTimeScale(uint32 channel) const override;
void SetTimeScale(float scale, uint32 channel = 0) override;
void ClearTimeScales() override;
void EnableTimer(bool bEnable) override;
float GetFrameRate() override;
float GetProfileFrameBlending(float* pfBlendTime = nullptr, int* piBlendMode = nullptr) override;
void Serialize(TSerialize ser) override;
bool IsTimerEnabled() const override;
//! try to pause/unpause a timer
// returns true if successfully paused/unpaused, false otherwise
bool PauseTimer(ETimer which, bool bPause) override;
//! determine if a timer is paused
// returns true if paused, false otherwise
bool IsTimerPaused(ETimer which) override;
//! try to set a timer
// return true if successful, false otherwise
bool SetTimer(ETimer which, float timeInSeconds) override;
//! make a tm struct from a time_t in UTC (like gmtime)
void SecondsToDateUTC(time_t time, struct tm& outDateUTC) override;
//! make a UTC time from a tm (like timegm, but not available on all platforms)
time_t DateToSecondsUTC(struct tm& timePtr) override;
//! Convert from Tics to Seconds
float TicksToSeconds(int64 ticks) override
{
return float((double)ticks * m_fSecsPerTick);
}
//! Get number of ticks per second
int64 GetTicksPerSecond() override
{
return m_lTicksPerSec;
}
const CTimeValue& GetFrameStartTime(ETimer which = ETIMER_GAME) const override { return m_CurrTime[(int)which]; }
ITimer* CreateNewTimer() override;
void EnableFixedTimeMode(bool enable, float timeStep) override;
private: // ---------------------------------------------------------------------
// ---------------------------------------------------------------------------
// updates m_CurrTime (either pass m_lCurrentTime or custom curTime)
void RefreshGameTime(int64 curTime);
void RefreshUITime(int64 curTime);
void UpdateBlending();
float GetAverageFrameTime();
// Updates the game-time offset to match the the specified time.
// The argument is the new number of ticks since the last Reset().
void SetOffsetToMatchGameTime(int64 ticks);
// Convert seconds to ticks using the timer frequency.
// Note: Loss of precision may occur, especially if magnitude of argument or timer frequency is large.
int64 SecondsToTicks(double seconds) const;
enum
{
MAX_FRAME_AVERAGE = 100,
NUM_TIME_SCALE_CHANNELS = 8,
};
//////////////////////////////////////////////////////////////////////////
// Dynamic state, reset by ResetTimer()
//////////////////////////////////////////////////////////////////////////
CTimeValue m_CurrTime[ETIMER_LAST]; // Time since last Reset(), cached during Update()
int64 m_lBaseTime; // Ticks elapsed since system boot, all other tick-unit variables are relative to this.
int64 m_lLastTime; // Ticks since last Reset(). This is the base for UI time. UI time is monotonic, it always moves forward at a constant rate until the timer is Reset()).
int64 m_lOffsetTime; // Additional ticks for Game time (relative to UI time). Game time can be affected by loading, pausing, time smoothing and time clamping, as well as SetTimer().
//// the GetcurAsyncTime function appears to want to return the actual wall clock time delta
//// but its using the base time (above) which is adjusted when there is a frame skip.
//int64 m_lBaseTime_Async;
float m_fFrameTime; // In seconds since the last Update(), clamped/smoothed etc.
float m_fRealFrameTime; // In real seconds since the last Update(), non-clamped/un-smoothed etc.
bool m_bGameTimerPaused; // Set if the game is paused. GetFrameTime() will return 0, GetCurrTime(ETIMER_GAME) will not progress.
int64 m_lGameTimerPausedTime; // The UI time when the game timer was paused. On un-pause, offset will be adjusted to match.
//////////////////////////////////////////////////////////////////////////
// Persistant state, kept by ResetTimer()
//////////////////////////////////////////////////////////////////////////
bool m_bEnabled;
unsigned int m_nFrameCounter;
int64 m_lTicksPerSec; // Ticks per second
double m_fSecsPerTick; // Seconds per tick
// smoothing
float m_arrFrameTimes[MAX_FRAME_AVERAGE];
float m_fAverageFrameTime; // used for smoothing (AverageFrameTime())
float m_fAvgFrameTime; // used for blend weighting (UpdateBlending())
float m_fProfileBlend; // current blending amount for profile.
float m_fSmoothTime; // smoothing interval (up to m_profile_smooth_time).
// time scale
float m_timeScaleChannels[NUM_TIME_SCALE_CHANNELS];
float m_totalTimeScale;
//////////////////////////////////////////////////////////////////////////
// Console vars, always have default value on secondary CTimer instances
//////////////////////////////////////////////////////////////////////////
float m_fixed_time_step; // in seconds
float m_max_time_step; // in seconds
float m_cvar_time_scale; // slow down time cvar
int m_TimeSmoothing; // Console Variable, 0=off, otherwise on
int m_TimeDebug; // Console Variable, 0=off, otherwise on
// Profile averaging help.
float m_profile_smooth_time; // seconds to exponentially smooth profile results.
int m_profile_weighting; // weighting mode (see RegisterVar desc).
//bool m_fixedTimeModeEnabled;
//float m_fixedTimeModeStep;
};
#endif // CRYINCLUDE_CRYSYSTEM_TIMER_H
+8 -6
View File
@@ -16,7 +16,6 @@
#include "System.h"
#include "ConsoleBatchFile.h"
#include <ITimer.h>
#include <IRenderer.h>
#include <ISystem.h>
#include <ILog.h>
@@ -28,6 +27,7 @@
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
#include <AzCore/std/string/conversions.h>
#include <AzCore/std/algorithm.h>
#include <AzCore/Time/ITime.h>
#include <LyShine/Bus/UiCursorBus.h>
//#define DEFENCE_CVAR_HASH_LOGGING
@@ -105,7 +105,8 @@ void Command_SetWaitSeconds(IConsoleCmdArgs* pCmd)
if (pCmd->GetArgCount() > 1)
{
pConsole->m_waitSeconds.SetSeconds(atof(pCmd->GetArg(1)));
pConsole->m_waitSeconds += gEnv->pTimer->GetFrameStartTime();
const AZ::TimeMs elaspedTimeMs = AZ::GetRealElapsedTimeMs();
pConsole->m_waitSeconds += CTimeValue(AZ::TimeMsToSecondsDouble(elaspedTimeMs));
}
}
@@ -305,7 +306,6 @@ void CXConsole::Init(ISystem* pSystem)
{
m_pFont = pSystem->GetICryFont()->GetFont("default");
}
m_pTimer = pSystem->GetITimer();
AzFramework::InputChannelEventListener::Connect();
AzFramework::InputTextEventListener::Connect();
@@ -934,8 +934,8 @@ void CXConsole::Update()
const float fRepeatDelay = 1.0f / 40.0f; // in sec (similar to Windows default but might differ from actual setting)
const float fHitchDelay = 1.0f / 10.0f; // in sec. Very low, but still reasonable frame-rate (debug builds)
m_fRepeatTimer -= gEnv->pTimer->GetRealFrameTime(); // works even when time is manipulated
// m_fRepeatTimer -= gEnv->pTimer->GetFrameTime(ITimer::ETIMER_UI); // can be used once ETIMER_UI works even with t_FixedTime
const AZ::TimeUs delta = AZ::GetRealTickDeltaTimeUs(); // works even when time is manipulated
m_fRepeatTimer -= AZ::TimeUsToSeconds(delta);
if (m_fRepeatTimer <= 0.0f)
{
@@ -1961,7 +1961,9 @@ void CXConsole::ExecuteDeferredCommands()
if (m_waitSeconds.GetValue())
{
if (m_waitSeconds > gEnv->pTimer->GetFrameStartTime())
const AZ::TimeMs elaspsedTimeMs = AZ::GetRealElapsedTimeMs();
const double elaspedTimeSec = AZ::TimeMsToSecondsDouble(elaspsedTimeMs);
if (m_waitSeconds > CTimeValue(elaspedTimeSec))
{
return;
}
+1 -2
View File
@@ -13,8 +13,8 @@
#pragma once
#include <IConsole.h>
#include "Timer.h"
#include <CryCommon/StlUtils.h>
#include <CryCommon/TimeValue.h>
#include <AzFramework/Components/ConsoleBus.h>
#include <AzFramework/CommandLine/CommandRegistrationBus.h>
@@ -377,7 +377,6 @@ private: // ----------------------------------------------------------
CSystem* m_pSystem;
IFFont* m_pFont;
ITimer* m_pTimer;
ICVar* m_pSysDeactivateConsole;
@@ -10,6 +10,7 @@
#include "CrySystem_precompiled.h"
#include "SerializeXMLReader.h"
#include <ISystem.h>
#include <AzCore/Time/ITime.h>
#define TAG_SCRIPT_VALUE "v"
#define TAG_SCRIPT_TYPE "t"
@@ -21,7 +22,6 @@
CSerializeXMLReaderImpl::CSerializeXMLReaderImpl(const XmlNodeRef& nodeRef)
: m_nErrors(0)
{
//m_curTime = gEnv->pTimer->GetFrameStartTime();
assert(!!nodeRef);
m_nodeStack.push_back(CParseState());
m_nodeStack.back().Init(nodeRef);
@@ -87,18 +87,21 @@ bool CSerializeXMLReaderImpl::Value(const char* name, CTimeValue& value)
}
else
{
const AZ::TimeMs elaspsedTimeMs = AZ::GetRealElapsedTimeMs();
const double elaspedTimeSec = AZ::TimeMsToSecondsDouble(elaspsedTimeMs);
const CTimeValue elaspedTime(elaspedTimeSec);
float delta;
if (!GetAttr(nodeRef, name, delta))
{
//CryWarning( VALIDATOR_MODULE_SYSTEM,VALIDATOR_WARNING,"Failed to read time value %s", name);
//Failed();
value = gEnv->pTimer->GetFrameStartTime(); // in case we don't find the node, it was assumed to be the default value (0.0)
value = elaspedTime; // in case we don't find the node, it was assumed to be the default value (0.0)
// 0.0 means current time, whereas "zero" really means CTimeValue(0.0), see above
return false;
}
else
{
value = CTimeValue(gEnv->pTimer->GetFrameStartTime() + delta);
value = CTimeValue(elaspedTime + delta);
}
}
return true;
@@ -11,7 +11,6 @@
#include "SimpleSerialize.h"
#include <stack>
#include <IXml.h>
#include <ITimer.h>
#include "xml.h"
class CSerializeXMLReaderImpl
@@ -10,6 +10,8 @@
#include "CrySystem_precompiled.h"
#include "SerializeXMLWriter.h"
#include <AzCore/Time/ITime.h>
static const size_t MAX_NODE_STACK_DEPTH = 40;
#define TAG_SCRIPT_VALUE "v"
@@ -18,7 +20,9 @@ static const size_t MAX_NODE_STACK_DEPTH = 40;
CSerializeXMLWriterImpl::CSerializeXMLWriterImpl(const XmlNodeRef& nodeRef)
{
m_curTime = gEnv->pTimer->GetFrameStartTime();
const AZ::TimeMs elaspsedTimeMs = AZ::GetRealElapsedTimeMs();
const double elaspedTimeSec = AZ::TimeMsToSecondsDouble(elaspsedTimeMs);
m_curTime = CTimeValue(elaspedTimeSec);
assert(!!nodeRef);
m_nodeStack.push_back(nodeRef);
@@ -13,7 +13,6 @@
#include <ISystem.h>
#include <ITimer.h>
#include <IXml.h>
#include "SimpleSerialize.h"
@@ -20,7 +20,6 @@ set(FILES
SystemEventDispatcher.cpp
SystemInit.cpp
SystemWin32.cpp
Timer.cpp
XConsole.cpp
XConsoleVariable.cpp
AZCrySystemInitLogSink.h
@@ -36,7 +35,6 @@ set(FILES
CrySystem_precompiled.h
System.h
SystemEventDispatcher.h
Timer.h
XConsole.h
XConsoleVariable.h
XML/SerializeXMLReader.cpp