(engineRoot.size()));
}
//////////////////////////////////////////////////////////////////////////
diff --git a/Code/Editor/Viewport.cpp b/Code/Editor/Viewport.cpp
index c8f2e268d9..37c46f07dd 100644
--- a/Code/Editor/Viewport.cpp
+++ b/Code/Editor/Viewport.cpp
@@ -1407,6 +1407,69 @@ void QtViewport::ProcessRenderLisneters(DisplayContext& rstDisplayContext)
}
//////////////////////////////////////////////////////////////////////////
#if defined(AZ_PLATFORM_WINDOWS)
+// Note: Both CreateAnglesYPR and CreateOrientationYPR were copied verbatim from Cry_Camera.h which has been removed.
+//
+// Description
+//
+// x-YAW
+// y-PITCH (negative=looking down / positive=looking up)
+// z-ROLL
+//
+// Note: If we are looking along the z-axis, its not possible to specify the x and z-angle
+inline Ang3 CreateAnglesYPR(const Matrix33& m)
+{
+ assert(m.IsOrthonormal());
+ float l = Vec3(m.m01, m.m11, 0.0f).GetLength();
+ if (l > 0.0001)
+ {
+ return Ang3(atan2f(-m.m01 / l, m.m11 / l), atan2f(m.m21, l), atan2f(-m.m20 / l, m.m22 / l));
+ }
+ else
+ {
+ return Ang3(0, atan2f(m.m21, l), 0);
+ }
+}
+
+// Description
+// This function builds a 3x3 orientation matrix using YPR-angles
+// Rotation order for the orientation-matrix is Z-X-Y. (Zaxis=YAW / Xaxis=PITCH / Yaxis=ROLL)
+//
+//
+// COORDINATE-SYSTEM
+//
+// z-axis
+// ^
+// |
+// | y-axis
+// | /
+// | /
+// |/
+// +---------------> x-axis
+//
+//
+// Example:
+// Matrix33 orientation=CreateOrientationYPR( Ang3(1,2,3) );
+inline Matrix33 CreateOrientationYPR(const Ang3& ypr)
+{
+ f32 sz, cz;
+ sincos_tpl(ypr.x, &sz, &cz); //Zaxis = YAW
+ f32 sx, cx;
+ sincos_tpl(ypr.y, &sx, &cx); //Xaxis = PITCH
+ f32 sy, cy;
+ sincos_tpl(ypr.z, &sy, &cy); //Yaxis = ROLL
+ Matrix33 c;
+ c.m00 = cy * cz - sy * sz * sx;
+ c.m01 = -sz * cx;
+ c.m02 = sy * cz + cy * sz * sx;
+ c.m10 = cy * sz + sy * sx * cz;
+ c.m11 = cz * cx;
+ c.m12 = sy * sz - cy * sx * cz;
+ c.m20 = -sy * cx;
+ c.m21 = sx;
+ c.m22 = cy * cx;
+ return c;
+}
+
void QtViewport::OnRawInput([[maybe_unused]] UINT wParam, HRAWINPUT lParam)
{
static C3DConnexionDriver* p3DConnexionDriver = 0;
@@ -1450,12 +1513,12 @@ void QtViewport::OnRawInput([[maybe_unused]] UINT wParam, HRAWINPUT lParam)
t *= sys_scale3DMouseTranslation->GetFVal();
float as = 0.001f * gSettings.cameraMoveSpeed;
- Ang3 ypr = CCamera::CreateAnglesYPR(Matrix33(viewTM));
+ Ang3 ypr = CreateAnglesYPR(Matrix33(viewTM));
ypr.x += -all6DOFs[5] * as * fScaleYPR;
ypr.y = AZStd::clamp(ypr.y + all6DOFs[3] * as * fScaleYPR, -1.5f, 1.5f); // to keep rotation in reasonable range
ypr.z = 0; // to have camera always upward
- viewTM = Matrix34(CCamera::CreateOrientationYPR(ypr), viewTM.GetTranslation());
+ viewTM = Matrix34(CreateOrientationYPR(ypr), viewTM.GetTranslation());
viewTM = viewTM * Matrix34::CreateTranslationMat(t);
SetViewTM(viewTM);
diff --git a/Code/Editor/ViewportTitleDlg.cpp b/Code/Editor/ViewportTitleDlg.cpp
index 75d16e9a40..49459fad0f 100644
--- a/Code/Editor/ViewportTitleDlg.cpp
+++ b/Code/Editor/ViewportTitleDlg.cpp
@@ -138,14 +138,11 @@ CViewportTitleDlg::CViewportTitleDlg(QWidget* pParent)
connect(this, &CViewportTitleDlg::ActionTriggered, MainWindow::instance()->GetActionManager(), &ActionManager::ActionTriggered);
- AZ::VR::VREventBus::Handler::BusConnect();
-
OnInitDialog();
}
CViewportTitleDlg::~CViewportTitleDlg()
{
- AZ::VR::VREventBus::Handler::BusDisconnect();
GetISystem()->GetISystemEventDispatcher()->RemoveListener(this);
GetIEditor()->UnregisterNotifyListener(this);
@@ -236,10 +233,6 @@ void CViewportTitleDlg::SetupOverflowMenu()
connect(m_audioMuteAction, &QAction::triggered, this, &CViewportTitleDlg::OnBnClickedMuteAudio);
overFlowMenu->addAction(m_audioMuteAction);
- m_enableVRAction = new QAction("Enable VR Preview", overFlowMenu);
- connect(m_enableVRAction, &QAction::triggered, this, &CViewportTitleDlg::OnBnClickedEnableVR);
- overFlowMenu->addAction(m_enableVRAction);
-
overFlowMenu->addSeparator();
m_enableGridSnappingAction = new QAction("Enable Grid Snapping", overFlowMenu);
@@ -305,16 +298,6 @@ void CViewportTitleDlg::OnInitDialog()
connect(displayInfoHelper, &CViewportTitleDlgDisplayInfoHelper::ViewportInfoStatusUpdated, this, &CViewportTitleDlg::UpdateDisplayInfo);
UpdateDisplayInfo();
- // This is here just in case this class hasn't been created before
- // a VR headset was initialized
- m_enableVRAction->setEnabled(false);
- if (AZ::VR::HMDDeviceRequestBus::GetTotalNumOfEventHandlers() != 0)
- {
- m_enableVRAction->setEnabled(true);
- }
-
- AZ::VR::VREventBus::Handler::BusConnect();
-
QFontMetrics metrics({});
int width = static_cast(metrics.boundingRect("-9999.99").width() * m_fieldWidthMultiplier);
@@ -931,23 +914,6 @@ void CViewportTitleDlg::UpdateMuteActionText()
}
}
-void CViewportTitleDlg::OnHMDInitialized()
-{
- m_enableVRAction->setEnabled(true);
-}
-
-void CViewportTitleDlg::OnHMDShutdown()
-{
- m_enableVRAction->setEnabled(false);
-}
-
-void CViewportTitleDlg::OnBnClickedEnableVR()
-{
- gSettings.bEnableGameModeVR = !gSettings.bEnableGameModeVR;
-
- m_enableVRAction->setText(gSettings.bEnableGameModeVR ? tr("Disable VR Preview") : tr("Enable VR Preview"));
-}
-
inline double Round(double fVal, double fStep)
{
if (fStep > 0.f)
diff --git a/Code/Editor/ViewportTitleDlg.h b/Code/Editor/ViewportTitleDlg.h
index 6996fe7750..a3e19837b4 100644
--- a/Code/Editor/ViewportTitleDlg.h
+++ b/Code/Editor/ViewportTitleDlg.h
@@ -22,7 +22,6 @@
#include
#include
-#include
#endif
// CViewportTitleDlg dialog
@@ -44,7 +43,6 @@ class CViewportTitleDlg
: public QWidget
, public IEditorNotifyListener
, public ISystemEventListener
- , public AZ::VR::VREventBus::Handler
{
Q_OBJECT
public:
@@ -85,13 +83,6 @@ protected:
void OnToggleHelpers();
void UpdateDisplayInfo();
- //////////////////////////////////////////////////////////////////////////
- /// VR Event Bus Implementation
- //////////////////////////////////////////////////////////////////////////
- void OnHMDInitialized() override;
- void OnHMDShutdown() override;
- //////////////////////////////////////////////////////////////////////////
-
void SetupCameraDropdownMenu();
void SetupResolutionDropdownMenu();
void SetupViewportInformationMenu();
@@ -140,7 +131,6 @@ protected:
void OnBnClickedGotoPosition();
void OnBnClickedMuteAudio();
- void OnBnClickedEnableVR();
void UpdateMuteActionText();
@@ -168,7 +158,6 @@ protected:
QAction* m_fullInformationAction = nullptr;
QAction* m_compactInformationAction = nullptr;
QAction* m_audioMuteAction = nullptr;
- QAction* m_enableVRAction = nullptr;
QAction* m_enableGridSnappingAction = nullptr;
QAction* m_enableAngleSnappingAction = nullptr;
QComboBox* m_cameraSpeed = nullptr;
diff --git a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp
index 17f576b5ee..89dfcaffd1 100644
--- a/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp
+++ b/Code/Editor/WelcomeScreen/WelcomeScreenDialog.cpp
@@ -25,8 +25,6 @@
#include
-// AzFramework
-#include
// AzToolsFramework
#include
@@ -173,9 +171,6 @@ void WelcomeScreenDialog::SetRecentFileList(RecentFileList* pList)
m_pRecentList = pList;
- const char* engineRoot;
- EBUS_EVENT_RESULT(engineRoot, AzFramework::ApplicationRequests::Bus, GetEngineRoot);
-
auto projectPath = AZ::Utils::GetProjectPath();
QString gamePath{projectPath.c_str()};
Path::ConvertSlashToBackSlash(gamePath);
diff --git a/Code/Editor/editor_lib_test_files.cmake b/Code/Editor/editor_lib_test_files.cmake
index 2ae3d22c19..17f36228db 100644
--- a/Code/Editor/editor_lib_test_files.cmake
+++ b/Code/Editor/editor_lib_test_files.cmake
@@ -22,6 +22,7 @@ set(FILES
Lib/Tests/test_DisplaySettingsPythonBindings.cpp
Lib/Tests/test_ViewportManipulatorController.cpp
Lib/Tests/test_ModularViewportCameraController.cpp
+ Lib/Tests/Camera/test_EditorCamera.cpp
DisplaySettingsPythonFuncs.cpp
DisplaySettingsPythonFuncs.h
)
diff --git a/Code/Framework/AtomCore/Tests/Main.cpp b/Code/Framework/AtomCore/Tests/Main.cpp
index 29ef408551..eb4c6bc835 100644
--- a/Code/Framework/AtomCore/Tests/Main.cpp
+++ b/Code/Framework/AtomCore/Tests/Main.cpp
@@ -7,7 +7,6 @@
*/
-#include
#include
#include
#include
diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetDataStream.h b/Code/Framework/AzCore/AzCore/Asset/AssetDataStream.h
index 62f5808207..d2b069b55b 100644
--- a/Code/Framework/AzCore/AzCore/Asset/AssetDataStream.h
+++ b/Code/Framework/AzCore/AzCore/Asset/AssetDataStream.h
@@ -70,6 +70,9 @@ namespace AZ::Data
const char* GetFilename() const override { return m_filePath.c_str(); }
+ AZStd::chrono::milliseconds GetStreamingDeadline() const { return m_curDeadline; }
+ AZ::IO::IStreamerTypes::Priority GetStreamingPriority() const { return m_curPriority; }
+
// AssetDataStream specific APIs
//! Whether or not all data has been loaded.
diff --git a/Code/Framework/AzCore/AzCore/AzCoreModule.cpp b/Code/Framework/AzCore/AzCore/AzCoreModule.cpp
index 67123ed826..e7e87559b0 100644
--- a/Code/Framework/AzCore/AzCore/AzCoreModule.cpp
+++ b/Code/Framework/AzCore/AzCore/AzCoreModule.cpp
@@ -19,7 +19,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -40,7 +39,6 @@ namespace AZ
SliceComponent::CreateDescriptor(),
SliceSystemComponent::CreateDescriptor(),
SliceMetadataInfoComponent::CreateDescriptor(),
- TimeSystemComponent::CreateDescriptor(),
LoggerSystemComponent::CreateDescriptor(),
EventSchedulerSystemComponent::CreateDescriptor(),
TaskGraphSystemComponent::CreateDescriptor(),
@@ -59,7 +57,6 @@ namespace AZ
{
return AZ::ComponentTypeList
{
- azrtti_typeid(),
azrtti_typeid(),
azrtti_typeid(),
azrtti_typeid(),
diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp
index ad7e44c2ae..cf23d2b4d7 100644
--- a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp
+++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp
@@ -72,6 +72,7 @@
#include
#include
+#include
static void PrintEntityName(const AZ::ConsoleCommandContainer& arguments)
{
@@ -416,6 +417,7 @@ namespace AZ
ComponentApplication::ComponentApplication(int argC, char** argV)
: m_eventLogger{}
+ , m_timeSystem(AZStd::make_unique())
{
if (Interface::Get() == nullptr)
{
@@ -485,16 +487,6 @@ namespace AZ
constexpr bool executeRegDumpCommands = false;
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands);
- // Query for the Executable Path using OS specific functions
- CalculateExecutablePath();
-
- // Determine the path to the engine
- CalculateEngineRoot();
-
- // If the current platform returns an engaged optional from Utils::GetDefaultAppRootPath(), that is used
- // for the application root.
- CalculateAppRoot();
-
SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(*m_settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands);
SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*m_settingsRegistry);
@@ -584,7 +576,6 @@ namespace AZ
DestroyAllocator();
}
-
void ReportBadEngineRoot()
{
AZStd::string errorMessage = {"Unable to determine a valid path to the engine.\n"
@@ -614,7 +605,8 @@ namespace AZ
{
AZ_Assert(!m_isStarted, "Component application already started!");
- if (m_engineRoot.empty())
+ using Type = AZ::SettingsRegistryInterface::Type;
+ if (m_settingsRegistry->GetType(SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder) == Type::NoType)
{
ReportBadEngineRoot();
return nullptr;
@@ -686,7 +678,6 @@ namespace AZ
ComponentApplicationBus::Handler::BusConnect();
- m_currentTime = AZStd::chrono::system_clock::now();
TickRequestBus::Handler::BusConnect();
#if defined(AZ_ENABLE_DEBUG_TOOLS)
@@ -1180,6 +1171,24 @@ namespace AZ
return ReflectionEnvironment::GetReflectionManager() ? ReflectionEnvironment::GetReflectionManager()->GetReflectContext() : nullptr;
}
+ /// Returns the path to the engine.
+
+ const char* ComponentApplication::GetEngineRoot() const
+ {
+ static IO::FixedMaxPathString engineRoot;
+ engineRoot.clear();
+ m_settingsRegistry->Get(engineRoot, SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
+ return engineRoot.c_str();
+ }
+
+ const char* ComponentApplication::GetExecutableFolder() const
+ {
+ static IO::FixedMaxPathString exeFolder;
+ exeFolder.clear();
+ m_settingsRegistry->Get(exeFolder, SettingsRegistryMergeUtils::FilePathKey_BinaryFolder);
+ return exeFolder.c_str();
+ }
+
//=========================================================================
// CreateReflectionManager
//=========================================================================
@@ -1404,31 +1413,23 @@ namespace AZ
#endif
}
- void ComponentApplication::Tick(float deltaOverride /*= -1.f*/)
+ void ComponentApplication::Tick()
{
+ AZ_PROFILE_SCOPE(System, "Component application simulation tick");
+
{
- AZ_PROFILE_SCOPE(System, "Component application simulation tick");
-
- AZStd::chrono::system_clock::time_point now = AZStd::chrono::system_clock::now();
-
- m_deltaTime = 0.0f;
-
- if (now >= m_currentTime)
- {
- AZStd::chrono::duration delta = now - m_currentTime;
- m_deltaTime = deltaOverride >= 0.f ? deltaOverride : delta.count();
- }
-
- {
- AZ_PROFILE_SCOPE(AzCore, "ComponentApplication::Tick:ExecuteQueuedEvents");
- TickBus::ExecuteQueuedEvents();
- }
- m_currentTime = now;
- {
- AZ_PROFILE_SCOPE(AzCore, "ComponentApplication::Tick:OnTick");
- EBUS_EVENT(TickBus, OnTick, m_deltaTime, ScriptTimePoint(now));
- }
+ AZ_PROFILE_SCOPE(AzCore, "ComponentApplication::Tick:ExecuteQueuedEvents");
+ TickBus::ExecuteQueuedEvents();
}
+
+ {
+ AZ_PROFILE_SCOPE(AzCore, "ComponentApplication::Tick:OnTick");
+ const AZ::TimeUs deltaTimeUs = m_timeSystem->AdvanceTickDeltaTimes();
+ const float deltaTimeSeconds = AZ::TimeUsToSeconds(deltaTimeUs);
+ AZ::TickBus::Broadcast(&TickEvents::OnTick, deltaTimeSeconds, GetTimeAtCurrentTick());
+ }
+
+ m_timeSystem->ApplyTickRateLimiterIfNeeded();
}
void ComponentApplication::TickSystem()
@@ -1485,27 +1486,6 @@ namespace AZ
}
}
- //=========================================================================
- // CalculateExecutablePath
- //=========================================================================
- void ComponentApplication::CalculateExecutablePath()
- {
- m_exeDirectory = Utils::GetExecutableDirectory();
- }
-
- void ComponentApplication::CalculateAppRoot()
- {
- if (AZStd::optional appRootPath = Utils::GetDefaultAppRootPath(); appRootPath)
- {
- m_appRoot = AZStd::move(*appRootPath);
- }
- }
-
- void ComponentApplication::CalculateEngineRoot()
- {
- m_engineRoot = AZ::SettingsRegistryMergeUtils::FindEngineRoot(*m_settingsRegistry).Native();
- }
-
void ComponentApplication::ResolveModulePath([[maybe_unused]] AZ::OSString& modulePath)
{
// No special parsing of the Module Path is done by the Component Application anymore
@@ -1531,13 +1511,10 @@ namespace AZ
appType.m_maskValue = AZ::ApplicationTypeQuery::Masks::Invalid;
}
- //=========================================================================
- // GetFrameTime
- // [1/22/2016]
- //=========================================================================
float ComponentApplication::GetTickDeltaTime()
{
- return m_deltaTime;
+ const AZ::TimeUs gameTickTime = m_timeSystem->GetSimulationTickDeltaTimeUs();
+ return AZ::TimeUsToSeconds(gameTickTime);
}
//=========================================================================
@@ -1546,7 +1523,8 @@ namespace AZ
//=========================================================================
ScriptTimePoint ComponentApplication::GetTimeAtCurrentTick()
{
- return ScriptTimePoint(m_currentTime);
+ const AZ::TimeUs lastGameTickTime = m_timeSystem->GetLastSimulationTickTime();
+ return ScriptTimePoint(AZ::TimeUsToChrono(lastGameTickTime));
}
//=========================================================================
diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h
index 6df93aff4e..f245b5f5da 100644
--- a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h
+++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h
@@ -30,12 +30,14 @@
#include
#include
+
namespace AZ
{
class BehaviorContext;
class IConsole;
class Module;
class ModuleManager;
+ class TimeSystem;
}
namespace AZ::Debug
{
@@ -221,13 +223,10 @@ namespace AZ
BehaviorContext* GetBehaviorContext() override;
/// Returns the json registration context that has been registered with the app, if there is one.
JsonRegistrationContext* GetJsonRegistrationContext() override;
- /// Returns the working root folder that has been registered with the app, if there is one.
- /// It's expected that derived applications will implement an application root.
- const char* GetAppRoot() const override { return m_appRoot.c_str(); }
/// Returns the path to the engine.
- const char* GetEngineRoot() const override { return m_engineRoot.c_str(); }
+ const char* GetEngineRoot() const override;
/// Returns the path to the folder the executable is in.
- const char* GetExecutableFolder() const override { return m_exeDirectory.c_str(); }
+ const char* GetExecutableFolder() const override;
//////////////////////////////////////////////////////////////////////////
/// TickRequestBus
@@ -240,7 +239,7 @@ namespace AZ
/**
* Ticks all components using the \ref AZ::TickBus during simulation time. May not tick if the application is not active (i.e. not in focus)
*/
- virtual void Tick(float deltaOverride = -1.f);
+ virtual void Tick();
/**
* Ticks all using the \ref AZ::SystemTickBus at all times. Should always tick even if the application is not active.
@@ -352,15 +351,6 @@ namespace AZ
/// Adds system components requested by modules and the application to the system entity.
void AddRequiredSystemComponents(AZ::Entity* systemEntity);
- /// Calculates the directory the application executable comes from.
- void CalculateExecutablePath();
-
- /// Calculates the root directory of the engine.
- void CalculateEngineRoot();
-
- /// Deprecated: The term "AppRoot" has no meaning
- void CalculateAppRoot();
-
template
static void NormalizePath(Iterator begin, Iterator end, bool doLowercase = true)
{
@@ -371,8 +361,6 @@ namespace AZ
}
}
- AZStd::chrono::system_clock::time_point m_currentTime{ AZStd::chrono::system_clock::time_point::max() };
- float m_deltaTime{ 0.0f };
AZStd::unique_ptr m_moduleManager;
AZStd::unique_ptr m_settingsRegistry;
EntityAddedEvent m_entityAddedEvent;
@@ -388,14 +376,13 @@ namespace AZ
void* m_fixedMemoryBlock{ nullptr }; //!< Pointer to the memory block allocator, so we can free it OnDestroy.
IAllocatorAllocate* m_osAllocator{ nullptr };
EntitySetType m_entities;
- AZ::IO::FixedMaxPath m_exeDirectory;
- AZ::IO::FixedMaxPath m_engineRoot;
- AZ::IO::FixedMaxPath m_appRoot;
AZ::SettingsRegistryInterface::NotifyEventHandler m_projectPathChangedHandler;
AZ::SettingsRegistryInterface::NotifyEventHandler m_projectNameChangedHandler;
AZ::SettingsRegistryInterface::NotifyEventHandler m_commandLineUpdatedHandler;
+ AZStd::unique_ptr m_timeSystem;
+
// ConsoleFunctorHandle is responsible for unregistering the Settings Registry Console
// from the m_console member when it goes out of scope
AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle m_settingsRegistryConsoleFunctors;
diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.h b/Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.h
index 0c0977384a..feefa95973 100644
--- a/Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.h
+++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.h
@@ -175,10 +175,6 @@ namespace AZ
//! the serializers used by the best-effort json serialization.
virtual class JsonRegistrationContext* GetJsonRegistrationContext() = 0;
- //! Gets the name of the working root folder that was registered with the app.
- //! @return a pointer to the name of the app's root folder, if a root folder was registered.
- virtual const char* GetAppRoot() const = 0;
-
//! Gets the path of the working engine folder that the app is a part of.
//! @return a pointer to the engine path.
virtual const char* GetEngineRoot() const = 0;
diff --git a/Code/Framework/AzCore/AzCore/EBus/EventSchedulerSystemComponent.cpp b/Code/Framework/AzCore/AzCore/EBus/EventSchedulerSystemComponent.cpp
index 3cdc3fc461..dd92b340c5 100644
--- a/Code/Framework/AzCore/AzCore/EBus/EventSchedulerSystemComponent.cpp
+++ b/Code/Framework/AzCore/AzCore/EBus/EventSchedulerSystemComponent.cpp
@@ -60,7 +60,7 @@ namespace AZ
void EventSchedulerSystemComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
{
- TimeMs startTime = GetElapsedTimeMs();
+ TimeMs startTime = AZ::GetElapsedTimeMs();
bool usingTimeslice = bg_maxScheduledEventProcessTimeMs != TimeMs{ 0 };
while (!m_queue.empty())
@@ -76,7 +76,7 @@ namespace AZ
while (!m_pendingQueue.empty())
{
- if (usingTimeslice && (GetElapsedTimeMs() - startTime > bg_maxScheduledEventProcessTimeMs))
+ if (usingTimeslice && (AZ::GetElapsedTimeMs() - startTime > bg_maxScheduledEventProcessTimeMs))
{
AZLOG_WARN("Failed to trigger all pending scheduled events, %u events remain on the pending queue", aznumeric_cast(m_pendingQueue.size()));
break;
@@ -103,7 +103,7 @@ namespace AZ
durationMs = TimeMs{ 0 };
}
- TimeMs currentMilliseconds = GetElapsedTimeMs();
+ TimeMs currentMilliseconds = AZ::GetElapsedTimeMs();
if (timedEvent->m_handle == nullptr)
{
timedEvent->m_handle = AllocateHandle();
@@ -122,7 +122,7 @@ namespace AZ
durationMs = TimeMs{ 0 };
}
- TimeMs currentMilliseconds = GetElapsedTimeMs();
+ TimeMs currentMilliseconds = AZ::GetElapsedTimeMs();
ScheduledEvent* timedEvent = AllocateManagedEvent(callback, eventName);
const bool ownsScheduledEvent = true;
*(timedEvent->m_handle) = ScheduledEventHandle(TimeMs(currentMilliseconds + durationMs), durationMs, timedEvent, ownsScheduledEvent);
diff --git a/Code/Framework/AzCore/AzCore/EBus/ScheduledEvent.cpp b/Code/Framework/AzCore/AzCore/EBus/ScheduledEvent.cpp
index 8e496c3dbc..41230958e4 100644
--- a/Code/Framework/AzCore/AzCore/EBus/ScheduledEvent.cpp
+++ b/Code/Framework/AzCore/AzCore/EBus/ScheduledEvent.cpp
@@ -76,7 +76,7 @@ namespace AZ
TimeMs ScheduledEvent::TimeInQueueMs() const
{
- return GetElapsedTimeMs() - m_timeInserted;
+ return AZ::GetElapsedTimeMs() - m_timeInserted;
}
TimeMs ScheduledEvent::RemainingTimeInQueueMs() const
diff --git a/Code/Framework/AzCore/AzCore/IO/Streamer/FullFileDecompressor.cpp b/Code/Framework/AzCore/AzCore/IO/Streamer/FullFileDecompressor.cpp
index 6427571f10..797f96e53f 100644
--- a/Code/Framework/AzCore/AzCore/IO/Streamer/FullFileDecompressor.cpp
+++ b/Code/Framework/AzCore/AzCore/IO/Streamer/FullFileDecompressor.cpp
@@ -62,6 +62,7 @@ namespace AZ
, m_alignment(alignment)
{
JobManagerDesc jobDesc;
+ jobDesc.m_jobManagerName = "Full File Decompressor";
u32 numThreads = AZ::GetMin(maxNumJobs, AZStd::thread::hardware_concurrency());
for (u32 i = 0; i < numThreads; ++i)
{
diff --git a/Code/Framework/AzCore/AzCore/Jobs/Internal/JobManagerWorkStealing.cpp b/Code/Framework/AzCore/AzCore/Jobs/Internal/JobManagerWorkStealing.cpp
index c05590ca91..ce8455d9a1 100644
--- a/Code/Framework/AzCore/AzCore/Jobs/Internal/JobManagerWorkStealing.cpp
+++ b/Code/Framework/AzCore/AzCore/Jobs/Internal/JobManagerWorkStealing.cpp
@@ -14,6 +14,7 @@
#include
#include
#include
+#include
#include
@@ -83,7 +84,7 @@ AZ_THREAD_LOCAL JobManagerWorkStealing::ThreadInfo* JobManagerWorkStealing::m_cu
JobManagerWorkStealing::JobManagerWorkStealing(const JobManagerDesc& desc)
: m_isAsynchronous(!desc.m_workerThreads.empty())
- , m_workerThreads(AZStd::move(CreateWorkerThreads(desc.m_workerThreads)))
+ , m_workerThreads(AZStd::move(CreateWorkerThreads(desc)))
{
//allow workers to begin processing after they have all been created, needed to wait since they may access each others queues
m_initSemaphore.release(static_cast(desc.m_workerThreads.size()));
@@ -618,8 +619,9 @@ JobManagerWorkStealing::ThreadInfo* JobManagerWorkStealing::FindCurrentThreadInf
return info;
}
-JobManagerWorkStealing::ThreadList JobManagerWorkStealing::CreateWorkerThreads(const JobManagerDesc::DescList& workerDescList)
+JobManagerWorkStealing::ThreadList JobManagerWorkStealing::CreateWorkerThreads(const JobManagerDesc& jmDesc)
{
+ const JobManagerDesc::DescList& workerDescList = jmDesc.m_workerThreads;
ThreadList workerThreads(workerDescList.size());
m_threads.reserve(workerDescList.size());
@@ -632,8 +634,12 @@ JobManagerWorkStealing::ThreadList JobManagerWorkStealing::CreateWorkerThreads(c
info->m_owningManager = this;
info->m_workerId = iThread;
+ AZStd::fixed_string<128> threadName = AZStd::fixed_string<128>::format(
+ "%s worker thread %d",
+ jmDesc.m_jobManagerName[0] != '\0' ? jmDesc.m_jobManagerName : "AZ JobManager",
+ iThread);
AZStd::thread_desc threadDesc;
- threadDesc.m_name = "AZ JobManager worker thread";
+ threadDesc.m_name = threadName.c_str();
threadDesc.m_cpuId = desc.m_cpuId;
threadDesc.m_priority = desc.m_priority;
if (desc.m_stackSize != 0)
diff --git a/Code/Framework/AzCore/AzCore/Jobs/Internal/JobManagerWorkStealing.h b/Code/Framework/AzCore/AzCore/Jobs/Internal/JobManagerWorkStealing.h
index 55de872d86..734c166d6a 100644
--- a/Code/Framework/AzCore/AzCore/Jobs/Internal/JobManagerWorkStealing.h
+++ b/Code/Framework/AzCore/AzCore/Jobs/Internal/JobManagerWorkStealing.h
@@ -115,7 +115,7 @@ namespace AZ
void ProcessJobsAssist(ThreadInfo* info, Job* suspendedJob, AZStd::atomic* notifyFlag);
void ProcessJobsSynchronous(ThreadInfo* info, Job* suspendedJob, AZStd::atomic* notifyFlag);
void ProcessJobsInternal(ThreadInfo* info, Job* suspendedJob, AZStd::atomic* notifyFlag);
- ThreadList CreateWorkerThreads(const JobManagerDesc::DescList& workerDescList);
+ ThreadList CreateWorkerThreads(const JobManagerDesc& jmDesc);
#ifndef AZ_MONOLITHIC_BUILD
ThreadInfo* CrossModuleFindAndSetWorkerThreadInfo() const;
#endif
diff --git a/Code/Framework/AzCore/AzCore/Jobs/JobManagerComponent.cpp b/Code/Framework/AzCore/AzCore/Jobs/JobManagerComponent.cpp
index 6f5ccc93e4..883fa15991 100644
--- a/Code/Framework/AzCore/AzCore/Jobs/JobManagerComponent.cpp
+++ b/Code/Framework/AzCore/AzCore/Jobs/JobManagerComponent.cpp
@@ -51,6 +51,7 @@ namespace AZ
JobManagerBus::Handler::BusConnect();
JobManagerDesc desc;
+ desc.m_jobManagerName = "Default JobManager";
JobManagerThreadDesc threadDesc;
int numberOfWorkerThreads = m_numberOfWorkerThreads;
diff --git a/Code/Framework/AzCore/AzCore/Jobs/JobManagerDesc.h b/Code/Framework/AzCore/AzCore/Jobs/JobManagerDesc.h
index 94f84f27b3..b2156291bc 100644
--- a/Code/Framework/AzCore/AzCore/Jobs/JobManagerDesc.h
+++ b/Code/Framework/AzCore/AzCore/Jobs/JobManagerDesc.h
@@ -51,6 +51,8 @@ namespace AZ
{
JobManagerDesc() {}
+ const char* m_jobManagerName = "";
+
using DescList = AZStd::fixed_vector;
DescList m_workerThreads; ///< List of worker threads to create
};
diff --git a/Code/Framework/AzCore/AzCore/Math/Vector3.h b/Code/Framework/AzCore/AzCore/Math/Vector3.h
index 821dc8292c..6b7c53266d 100644
--- a/Code/Framework/AzCore/AzCore/Math/Vector3.h
+++ b/Code/Framework/AzCore/AzCore/Math/Vector3.h
@@ -100,7 +100,7 @@ namespace AZ
void Set(float x, float y, float z);
//! Sets components from an array of 3 floats in xyz order.
- void Set(float values[]);
+ void Set(const float values[]);
//! Indexed access using operator(), just for convenience.
float operator()(int32_t index) const;
diff --git a/Code/Framework/AzCore/AzCore/Math/Vector3.inl b/Code/Framework/AzCore/AzCore/Math/Vector3.inl
index 879ade38cf..6371c688b8 100644
--- a/Code/Framework/AzCore/AzCore/Math/Vector3.inl
+++ b/Code/Framework/AzCore/AzCore/Math/Vector3.inl
@@ -186,7 +186,7 @@ namespace AZ
}
- AZ_MATH_INLINE void Vector3::Set(float values[])
+ AZ_MATH_INLINE void Vector3::Set(const float values[])
{
m_value = Simd::Vec3::LoadImmediate(values[0], values[1], values[2]);
}
diff --git a/Code/Framework/AzCore/AzCore/Name/NameDictionary.cpp b/Code/Framework/AzCore/AzCore/Name/NameDictionary.cpp
index 3047a2894e..6cba54a17f 100644
--- a/Code/Framework/AzCore/AzCore/Name/NameDictionary.cpp
+++ b/Code/Framework/AzCore/AzCore/Name/NameDictionary.cpp
@@ -50,7 +50,12 @@ namespace AZ
if (!s_instance)
{
- s_instance = Environment::FindVariable(NameDictionaryInstanceName);
+ // Because the NameDictionary allocates memory using the AZ::Allocator and it is created
+ // in the executable memory space, it's ownership cannot be transferred to other module memory spaces
+ // Otherwise this could cause the the NameDictionary to be destroyed in static de-init
+ // after the AZ::Allocators have been destroyed
+ // Therefore we supply the isTransferOwnership value of false using CreateVariableEx
+ s_instance = AZ::Environment::CreateVariableEx(NameDictionaryInstanceName, true, false);
}
return s_instance.IsConstructed();
diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp b/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp
index b03d413507..45f7876993 100644
--- a/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp
+++ b/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp
@@ -3408,7 +3408,14 @@ LUA_API const Node* lua_getDummyNode()
const BehaviorParameter* arg = method->GetArgument(iArg);
BehaviorClass* argClass = nullptr;
LuaLoadFromStack fromStack = FromLuaStack(context, arg, argClass);
- AZ_Assert(fromStack, "Argument %s for Method %s doesn't have support to be converted to Lua!", arg->m_name, method->m_name.c_str());
+ AZ_Assert(fromStack,
+ "The argument type: %s for method: %s is not serialized and/or reflected for scripting.\n"
+ "Make sure %s is added to the SerializeContext and reflected to the BehaviorContext\n"
+ "For example, verify these two exist and are being called in a Reflect function:\n"
+ "serializeContext->Class<%s>();\n"
+ "behaviorContext->Class<%s>();\n"
+ "%s will not be available for scripting unless these requirements are met."
+ , arg->m_name, method->m_name.c_str(), arg->m_name, arg->m_name, arg->m_name, method->m_name.c_str());
m_fromLua.push_back(AZStd::make_pair(fromStack, argClass));
}
diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp
index 3668ab14fd..975217a131 100644
--- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp
+++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp
@@ -266,7 +266,8 @@ namespace AZ::SettingsRegistryMergeUtils
// Step 3 locate the project root and attempt to find the engine root using the registered engine
// for the project in the project.json file
- AZ::IO::FixedMaxPath projectRoot = FindProjectRoot(settingsRegistry);
+ AZ::IO::FixedMaxPath projectRoot;
+ settingsRegistry.Get(projectRoot.Native(), FilePathKey_ProjectPath);
if (projectRoot.empty())
{
return {};
@@ -668,7 +669,7 @@ namespace AZ::SettingsRegistryMergeUtils
// NOTE: We make the project-path in the BootstrapSettingsRootKey absolute first
AZ::IO::FixedMaxPath projectPath = FindProjectRoot(registry);
- if (constexpr auto projectPathKey = FixedValueString(BootstrapSettingsRootKey) + "/project_path";
+ if ([[maybe_unused]] constexpr auto projectPathKey = FixedValueString(BootstrapSettingsRootKey) + "/project_path";
!projectPath.empty())
{
if (projectPath.IsRelative())
@@ -693,6 +694,7 @@ namespace AZ::SettingsRegistryMergeUtils
R"(Project path isn't set in the Settings Registry at "%.*s".)"
" Project-related filepaths will be set relative to the executable directory\n",
AZ_STRING_ARG(projectPathKey));
+ projectPath = exePath;
registry.Set(FilePathKey_ProjectPath, exePath.Native());
}
diff --git a/Code/Framework/AzCore/AzCore/StringFunc/StringFunc.cpp b/Code/Framework/AzCore/AzCore/StringFunc/StringFunc.cpp
index ff30291a70..a953d53c33 100644
--- a/Code/Framework/AzCore/AzCore/StringFunc/StringFunc.cpp
+++ b/Code/Framework/AzCore/AzCore/StringFunc/StringFunc.cpp
@@ -1427,26 +1427,36 @@ namespace AZ
namespace AssetPath
{
- void CalculateBranchToken(const AZStd::string& appRootPath, AZStd::string& token)
+ namespace Internal
{
- // Normalize the token to prepare for CRC32 calculation
- AZStd::string normalized = appRootPath;
+ AZ::u32 CalculateBranchTokenHash(AZStd::string_view engineRootPath)
+ {
+ // Normalize the token to prepare for CRC32 calculation
+ auto NormalizeEnginePath = [](const char element) -> char
+ {
+ // Substitute path separators with '_' and lower case
+ return element == AZ::IO::WindowsPathSeparator || element == AZ::IO::PosixPathSeparator
+ ? '_' : static_cast(std::tolower(element));
+ };
- // Strip out any trailing path separators
- AZ::StringFunc::Strip(normalized, AZ_CORRECT_FILESYSTEM_SEPARATOR_STRING AZ_WRONG_FILESYSTEM_SEPARATOR_STRING,false, false, true);
+ // Trim off trailing path separators
+ engineRootPath = RStrip(engineRootPath, AZ_CORRECT_AND_WRONG_FILESYSTEM_SEPARATOR);
+ AZ::IO::FixedMaxPathString enginePath;
+ AZStd::transform(engineRootPath.begin(), engineRootPath.end(),
+ AZStd::back_inserter(enginePath), AZStd::move(NormalizeEnginePath));
- // Lower case always
- AZStd::to_lower(normalized.begin(), normalized.end());
-
- // Substitute path separators with '_'
- AZStd::replace(normalized.begin(), normalized.end(), '\\', '_');
- AZStd::replace(normalized.begin(), normalized.end(), '/', '_');
-
- // Perform the CRC32 calculation
- const AZ::Crc32 branchTokenCrc(normalized.c_str(), normalized.size(), true);
- char branchToken[12];
- azsnprintf(branchToken, AZ_ARRAY_SIZE(branchToken), "0x%08X", static_cast(branchTokenCrc));
- token = AZStd::string(branchToken);
+ // Perform the CRC32 calculation
+ constexpr bool forceLowercase = true;
+ return static_cast(AZ::Crc32(enginePath.c_str(), enginePath.size(), forceLowercase));
+ }
+ }
+ void CalculateBranchToken(AZStd::string_view engineRootPath, AZStd::string& token)
+ {
+ token = AZStd::string::format("0x%08X", Internal::CalculateBranchTokenHash(engineRootPath));
+ }
+ void CalculateBranchToken(AZStd::string_view engineRootPath, AZ::IO::FixedMaxPathString& token)
+ {
+ token = AZ::IO::FixedMaxPathString::format("0x%08X", Internal::CalculateBranchTokenHash(engineRootPath));
}
}
diff --git a/Code/Framework/AzCore/AzCore/StringFunc/StringFunc.h b/Code/Framework/AzCore/AzCore/StringFunc/StringFunc.h
index 1e651afc93..55236a0fff 100644
--- a/Code/Framework/AzCore/AzCore/StringFunc/StringFunc.h
+++ b/Code/Framework/AzCore/AzCore/StringFunc/StringFunc.h
@@ -485,10 +485,11 @@ namespace AZ
//! CalculateBranchToken
/*! Calculate the branch token that is used for asset processor connection negotiations
*
- * \param appRootPath - The absolute path of the app root to base the token calculation on
+ * \param engineRootPath - The absolute path to the engine root to base the token calculation on
* \param token - The result of the branch token calculation
*/
- void CalculateBranchToken(const AZStd::string& appRootPath, AZStd::string& token);
+ void CalculateBranchToken(AZStd::string_view engineRootPath, AZStd::string& token);
+ void CalculateBranchToken(AZStd::string_view engineRootPath, AZ::IO::FixedMaxPathString& token);
}
//////////////////////////////////////////////////////////////////////////
diff --git a/Code/Framework/AzCore/AzCore/Time/ITime.h b/Code/Framework/AzCore/AzCore/Time/ITime.h
index a97ba2319a..a3dcca09ea 100644
--- a/Code/Framework/AzCore/AzCore/Time/ITime.h
+++ b/Code/Framework/AzCore/AzCore/Time/ITime.h
@@ -12,8 +12,8 @@
#include
#include
#include
-#include
#include
+#include
namespace AZ
{
@@ -24,15 +24,21 @@ namespace AZ
//! Using int64_t as the underlying type, this is good to represent approximately 292,471 years
AZ_TYPE_SAFE_INTEGRAL(TimeUs, int64_t);
+ namespace Time
+ {
+ static const AZ::TimeMs ZeroTimeMs = AZ::TimeMs{ 0 };
+ static const AZ::TimeUs ZeroTimeUs = AZ::TimeUs{ 0 };
+ }
+
//! @class ITime
//! @brief This is an AZ::Interface<> for managing time related operations.
//! AZ::ITime and associated types may not operate in realtime. These abstractions are to allow our application
//! simulation to operate both slower and faster than realtime in a well defined and user controllable manner
- //! The rate at which time passes for AZ::ITime is controlled by the cvar t_scale
- //! t_scale == 0 means simulation time should halt
- //! 0 < t_scale < 1 will cause time to pass slower than realtime, with t_scale 0.1 being roughly 1/10th realtime
- //! t_scale == 1 will cause time to pass at roughly realtime
- //! t_scale > 1 will cause time to pass faster than normal, with t_scale 10 being roughly 10x realtime
+ //! The rate at which time passes for AZ::ITime is controlled by the cvar t_simulationTickScale
+ //! t_simulationTickScale == 0 means simulation time should halt
+ //! 0 < t_simulationTickScale < 1 will cause time to pass slower than realtime, with t_simulationTickScale 0.1 being roughly 1/10th realtime
+ //! t_simulationTickScale == 1 will cause time to pass at roughly realtime
+ //! t_simulationTickScale > 1 will cause time to pass faster than normal, with t_simulationTickScale 10 being roughly 10x realtime
class ITime
{
public:
@@ -41,15 +47,72 @@ namespace AZ
ITime() = default;
virtual ~ITime() = default;
- //! Returns the number of milliseconds since application start.
- //! @return the number of milliseconds that have elapsed since application start
+ //! Returns the number of milliseconds since application start scaled by t_simulationTickScale.
+ //! @return The number of milliseconds that have elapsed since application start.
virtual TimeMs GetElapsedTimeMs() const = 0;
- //! Returns the number of microseconds since application start.
+ //! Returns the number of microseconds since application start scaled by t_simulationTickScale.
//! @return the number of microseconds that have elapsed since application start
virtual TimeUs GetElapsedTimeUs() const = 0;
+
+ //! Returns the number of milliseconds since application start.
+ //! This value is not affected by the t_simulationTickScale cvar.
+ //! @return The number of milliseconds that have elapsed since application start.
+ virtual TimeMs GetRealElapsedTimeMs() const = 0;
+
+ //! Returns the number of microseconds since application start.
+ //! This value is not affected by the t_simulationTickScale cvar.
+ //! @return The number of microseconds that have elapsed since application start.
+ virtual TimeUs GetRealElapsedTimeUs() const = 0;
+
+ //! Returns the current simulation tick delta time.
+ //! This is affected by the cvars t_simulationTickScale, t_simulationTickDeltaOverride, and t_maxGameTickDelta.
+ //! @return The number of microseconds elapsed since the last game tick.
+ virtual TimeUs GetSimulationTickDeltaTimeUs() const = 0;
+
+ //! Returns the non-manipulated tick time.
+ //! @return The number of microseconds elapsed since the last game tick.
+ virtual TimeUs GetRealTickDeltaTimeUs() const = 0;
+
+ //! Returns the time since application start of when the last simulation tick was updated.
+ virtual TimeUs GetLastSimulationTickTime() const = 0;
+
+ //! If > 0 this will override the simulation tick delta time with the provided value.
+ //! When enabled this will ignore any set simulation tick scale.
+ //! Setting to 0 disables the override.
+ //! @param timeMs The time in milliseconds to use for the tick delta.
+ virtual void SetSimulationTickDeltaOverride(TimeMs timeMs) = 0;
+
+ //! Returns the current simulation tick override.
+ //! 0 means disabled.
+ //! @returns The current simulation tick override in milliseconds.
+ virtual TimeMs GetSimulationTickDeltaOverride() const = 0;
+
+ //! A scalar amount to adjust the passage of time by, 1.0 == realtime, 0.5 == half realtime, 2.0 == doubletime.
+ //! @param scale The scalar value to apply to the simulation time.
+ virtual void SetSimulationTickScale(float scale) = 0;
+
+ //! Returns the current simulation tick scale.
+ //! 1.0 == realtime, 0.5 == half realtime, 2.0 == doubletime.
+ //! @returns The simulation tick scale value.
+ virtual float GetSimulationTickScale() const = 0;
+
+ //! The minimum rate to force the simulation tick to run.
+ //! 0 for as fast as possible. 30 = ~33ms, 60 = ~16ms.
+ //! Setting to 0 will disable rate limiting.
+ //! @note It is not guaranteed to hit the requested tick rate exactly.
+ //! @param rate The rate in frames per second.
+ virtual void SetSimulationTickRate(int rate) = 0;
+
+ //! Return the current simulation tick rate.
+ //! 0 means disabled.
+ //! @return The rate in frames per second.
+ virtual int32_t GetSimulationTickRate() const = 0;
AZ_DISABLE_COPY_MOVE(ITime);
+
+ static const AZ::TimeMs ZeroTimeMs = AZ::TimeMs{ 0 };
+ static const AZ::TimeUs ZeroTimeUs = AZ::TimeUs{ 0 };
};
// EBus wrapper for ScriptCanvas
@@ -74,6 +137,29 @@ namespace AZ
return AZ::Interface::Get()->GetElapsedTimeUs();
}
+ inline TimeMs GetRealElapsedTimeMs()
+ {
+ return AZ::Interface::Get()->GetRealElapsedTimeMs();
+ }
+
+ //! This is a simple convenience wrapper
+ inline TimeUs GetSimulationTickDeltaTimeUs()
+ {
+ return AZ::Interface::Get()->GetSimulationTickDeltaTimeUs();
+ }
+
+ //! This is a simple convenience wrapper
+ inline TimeUs GetRealTickDeltaTimeUs()
+ {
+ return AZ::Interface::Get()->GetRealTickDeltaTimeUs();
+ }
+
+ //! This is a simple convenience wrapper
+ inline TimeUs GetLastSimulationTickTime()
+ {
+ return AZ::Interface::Get()->GetLastSimulationTickTime();
+ }
+
//! Converts from milliseconds to microseconds
inline TimeUs TimeMsToUs(TimeMs value)
{
@@ -92,12 +178,24 @@ namespace AZ
return static_cast(value) / 1000.0f;
}
+ //! Converts from milliseconds to seconds
+ inline double TimeMsToSecondsDouble(TimeMs value)
+ {
+ return static_cast(value) / 1000.0;
+ }
+
//! Converts from microseconds to seconds
inline float TimeUsToSeconds(TimeUs value)
{
return static_cast(value) / 1000000.0f;
}
+ //! Converts from microseconds to seconds
+ inline double TimeUsToSecondsDouble(TimeUs value)
+ {
+ return static_cast(value) / 1000000.0;
+ }
+
//! Converts from milliseconds to AZStd::chrono::time_point
inline auto TimeMsToChrono(TimeMs value)
{
@@ -113,6 +211,20 @@ namespace AZ
auto chronoValue = AZStd::chrono::microseconds(aznumeric_cast(value));
return epoch + chronoValue;
}
+
+ //! A utility function to convert from seconds to TimeMs
+ inline TimeMs SecondsToTimeMs(const double value)
+ {
+ const double valueMs = value * 1000.0;
+ return static_cast(static_cast(valueMs));
+ }
+
+ //! A utility function to convert from seconds to TimeUs
+ inline TimeUs SecondsToTimeUs(const double value)
+ {
+ const double valueMs = value * 1000000.0;
+ return static_cast(static_cast(valueMs));
+ }
} // namespace AZ
AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(AZ::TimeMs);
diff --git a/Code/Framework/AzCore/AzCore/Time/TimeSystem.cpp b/Code/Framework/AzCore/AzCore/Time/TimeSystem.cpp
new file mode 100644
index 0000000000..cd0170749f
--- /dev/null
+++ b/Code/Framework/AzCore/AzCore/Time/TimeSystem.cpp
@@ -0,0 +1,214 @@
+/*
+ * 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
+#include
+#include
+#include
+
+namespace AZ
+{
+ namespace
+ {
+ void cvar_t_simulationTickScale_Changed(const float& value)
+ {
+ if (auto* timeSystem = AZ::Interface::Get())
+ {
+ timeSystem->SetSimulationTickScale(value);
+ }
+ }
+
+ void cvar_t_simulationTickDeltaOverride_Changed(const float& value)
+ {
+ if (auto* timeSystem = AZ::Interface::Get())
+ {
+ timeSystem->SetSimulationTickDeltaOverride(AZ::SecondsToTimeMs(value));
+ }
+ }
+
+ void cvar_t_simulationTickRate_Changed(const int& rate)
+ {
+ AZ_Warning("tick", false, "Simulation tick rate limiting is currently disabled. Setting will not be applied.");
+ if (auto* timeSystem = AZ::Interface::Get())
+ {
+ timeSystem->SetSimulationTickRate(rate);
+ }
+ }
+ } // namespace
+
+ AZ_CVAR(float, t_simulationTickScale, 1.0f, cvar_t_simulationTickScale_Changed, AZ::ConsoleFunctorFlags::Null,
+ "A scalar amount to adjust time passage by, 1.0 == realtime, 0.5 == half realtime, 2.0 == doubletime");
+
+ AZ_CVAR(float, t_simulationTickDeltaOverride, 0.0f, cvar_t_simulationTickDeltaOverride_Changed, AZ::ConsoleFunctorFlags::Null,
+ "If > 0, overrides the simulation tick delta time with the provided value (Seconds) and ignores any t_simulationTickScale value.");
+
+ AZ_CVAR(int, t_simulationTickRate, 0, cvar_t_simulationTickRate_Changed, AZ::ConsoleFunctorFlags::Null,
+ "The minimum rate to force the game simulation tick to run. 0 for as fast as possible. 30 = ~33ms, 60 = ~16ms");
+
+ void TimeSystem::Reflect(AZ::ReflectContext* context)
+ {
+ if (AZ::SerializeContext* serializeContext = azrtti_cast(context))
+ {
+ serializeContext->Class()
+ ->Version(1);
+ }
+ }
+
+ TimeSystem::TimeSystem()
+ {
+ m_lastInvokedTimeUs = static_cast(AZStd::GetTimeNowMicroSecond());
+ AZ::Interface::Register(this);
+ ITimeRequestBus::Handler::BusConnect();
+ }
+
+ TimeSystem::~TimeSystem()
+ {
+ AZ::Interface::Unregister(this);
+ ITimeRequestBus::Handler::BusDisconnect();
+ }
+
+ TimeMs TimeSystem::GetElapsedTimeMs() const
+ {
+ return AZ::TimeUsToMs(GetElapsedTimeUs());
+ }
+
+ TimeUs TimeSystem::GetElapsedTimeUs() const
+ {
+ TimeUs currentTime = static_cast(AZStd::GetTimeNowMicroSecond());
+ TimeUs deltaTime = currentTime - m_lastInvokedTimeUs;
+
+ if (t_simulationTickScale != 1.0f)
+ {
+ const float floatDelta = AZStd::GetMax(static_cast(deltaTime) * t_simulationTickScale, 1.0f);
+ deltaTime = static_cast(static_cast(floatDelta));
+ }
+
+ m_accumulatedTimeUs += deltaTime;
+ m_lastInvokedTimeUs = currentTime;
+
+ return m_accumulatedTimeUs;
+ }
+
+ TimeMs TimeSystem::GetRealElapsedTimeMs() const
+ {
+ return AZ::TimeUsToMs(GetRealElapsedTimeUs());
+ }
+
+ TimeUs TimeSystem::GetRealElapsedTimeUs() const
+ {
+ return static_cast(AZStd::GetTimeNowMicroSecond());
+ }
+
+ TimeUs TimeSystem::GetSimulationTickDeltaTimeUs() const
+ {
+ return m_simulationTickDeltaTimeUs;
+ }
+
+ TimeUs TimeSystem::GetRealTickDeltaTimeUs() const
+ {
+ return m_realTickDeltaTimeUs;
+ }
+
+ TimeUs TimeSystem::GetLastSimulationTickTime() const
+ {
+ return m_lastSimulationTickTimeUs;
+ }
+
+ TimeUs TimeSystem::AdvanceTickDeltaTimes()
+ {
+ const TimeUs currentTimeUs = static_cast(AZStd::GetTimeNowMicroSecond());
+
+ //real time
+ m_realTickDeltaTimeUs = currentTimeUs - m_lastRealTickTimeUs;
+ m_lastRealTickTimeUs = currentTimeUs;
+
+ //game time
+ if (m_simulationTickDeltaOverride > AZ::Time::ZeroTimeUs)
+ {
+ m_simulationTickDeltaTimeUs = m_simulationTickDeltaOverride;
+ m_lastSimulationTickTimeUs = m_simulationTickDeltaTimeUs;
+ return m_simulationTickDeltaTimeUs;
+ }
+
+ m_simulationTickDeltaTimeUs = currentTimeUs - m_lastSimulationTickTimeUs;
+
+ if (!AZ::IsClose(t_simulationTickScale, 1.0f))
+ {
+ const double floatDelta = AZStd::GetMax(static_cast(m_simulationTickDeltaTimeUs) * static_cast(t_simulationTickScale), 1.0);
+ m_simulationTickDeltaTimeUs = static_cast(static_cast(floatDelta));
+ }
+ m_lastSimulationTickTimeUs = currentTimeUs;
+
+ return m_simulationTickDeltaTimeUs;
+ }
+
+ void TimeSystem::ApplyTickRateLimiterIfNeeded()
+ {
+ // Currently disabling the Tick rate limiter as there are some reported issues when using it.
+ #ifdef ENABLE_TICK_RATE_LIMITER
+ // If tick rate limiting is on, ensure (1 / t_simulationTickRate) ms has elapsed since the last frame,
+ // sleeping if there's still time remaining.
+ if (t_simulationTickRate > 0)
+ {
+ const TimeUs currentTimeUs = AZ::GetRealElapsedTimeUs();
+ const TimeUs timeUntilNextTick = (m_lastSimulationTickTimeUs + m_simulationTickLimitTimeUs) - currentTimeUs;
+ if (timeUntilNextTick > AZ::Time::ZeroTimeUs)
+ {
+ AZ_TracePrintf("tick", "Sleeping for %.2f", AZ::TimeUsToSecondsDouble(timeUntilNextTick));
+ AZStd::this_thread::sleep_for(AZStd::chrono::microseconds(static_cast(timeUntilNextTick)));
+ }
+ }
+ #endif // #ifdef ENABLE_TICK_RATE_LIMITER
+ }
+
+ void TimeSystem::SetSimulationTickDeltaOverride(TimeMs timeMs)
+ {
+ const TimeUs timeUs = AZ::TimeMsToUs(timeMs);
+ if (timeUs != m_simulationTickDeltaOverride)
+ {
+ m_simulationTickDeltaOverride = timeUs;
+ t_simulationTickDeltaOverride = AZ::TimeUsToSeconds(timeUs); //update the cvar
+ }
+ }
+
+ TimeMs TimeSystem::GetSimulationTickDeltaOverride() const
+ {
+ return AZ::TimeUsToMs(m_simulationTickDeltaOverride);
+ }
+
+ void TimeSystem::SetSimulationTickScale(float scale)
+ {
+ if (!AZ::IsClose(scale, t_simulationTickScale))
+ {
+ t_simulationTickScale = scale;
+ }
+ }
+
+ float TimeSystem::GetSimulationTickScale() const
+ {
+ return t_simulationTickScale;
+ }
+
+ void TimeSystem::SetSimulationTickRate(int rate)
+ {
+ m_simulationTickLimitRate = AZStd::abs(rate);
+ if (m_simulationTickLimitRate != 0)
+ {
+ m_simulationTickLimitTimeUs = AZ::SecondsToTimeUs(1.0f / m_simulationTickLimitRate);
+ }
+ else
+ {
+ m_simulationTickLimitTimeUs = AZ::Time::ZeroTimeUs;
+ }
+ }
+
+ int32_t TimeSystem::GetSimulationTickRate() const
+ {
+ return m_simulationTickLimitRate;
+ }
+} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/Time/TimeSystem.h b/Code/Framework/AzCore/AzCore/Time/TimeSystem.h
new file mode 100644
index 0000000000..d2587c76d8
--- /dev/null
+++ b/Code/Framework/AzCore/AzCore/Time/TimeSystem.h
@@ -0,0 +1,84 @@
+/*
+ * 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
+ *
+ */
+
+#pragma once
+
+#include
+#include
+
+namespace AZ
+{
+ class ReflectContext;
+
+ //! Implementation of the ITime system interface.
+ class TimeSystem
+ : public ITimeRequestBus::Handler
+ {
+ public:
+ AZ_RTTI(AZ::TimeSystem, "{CE1C5E4F-7DC1-4248-B10C-AC55E8924A48}", AZ::ITime);
+
+ static void Reflect(AZ::ReflectContext* context);
+
+ TimeSystem();
+ virtual ~TimeSystem();
+
+ //! ITime overrides.
+ //! @{
+ TimeMs GetElapsedTimeMs() const override;
+ TimeUs GetElapsedTimeUs() const override;
+ TimeMs GetRealElapsedTimeMs() const override;
+ TimeUs GetRealElapsedTimeUs() const override;
+ TimeUs GetSimulationTickDeltaTimeUs() const override;
+ TimeUs GetRealTickDeltaTimeUs() const override;
+ TimeUs GetLastSimulationTickTime() const override;
+ void SetSimulationTickDeltaOverride(TimeMs timeMs) override;
+ TimeMs GetSimulationTickDeltaOverride() const override;
+ void SetSimulationTickScale(float scale) override;
+ float GetSimulationTickScale() const override;
+ void SetSimulationTickRate(int rate) override;
+ int32_t GetSimulationTickRate() const override;
+ //! @}
+
+ //! Advances the Simulation and Real tick delta time counters.
+ //! This is called from the owner of the TimeSystem, ComponentApplication in Tick().
+ //! @return The delta in microseconds from the last call to AdvanceTickDeltaTimes(). Value will be the same as GetSimulationTickDeltaTimeUs().
+ TimeUs AdvanceTickDeltaTimes();
+
+ //! If t_simulationTickRate is >0 this will try to have the game delta time run at a maximum of the rate set.
+ //! This is called from the owner of the TimeSystem, ComponentApplication in Tick().
+ //! example. If t_simulationTickRate is set to 60Fps, and the game tick delta is <17ms(60fps), this will add a sleep for the remaining time.
+ //! example. If t_simulationTickRate is set to 60Fps, and the game tick delta is >=17ms(60fps), this will not sleep at all.
+ //! @note It is not guaranteed to hit the requested tick rate exactly.
+ void ApplyTickRateLimiterIfNeeded();
+ private:
+ //! Used to calculate the delta time between calls to GetElapsedTimeMs/TimeUs().
+ //! Mutable to allow GetElapsedTimeMs/TimeUs() to be a const functions.
+ mutable TimeUs m_lastInvokedTimeUs = AZ::Time::ZeroTimeUs;
+
+ //! Accumulates the delta time of GetElapsedTimeMs/TimeUs() calls.
+ //! Mutable to allow GetElapsedTimeMs/TimeUs() to be a const functions.
+ mutable TimeUs m_accumulatedTimeUs = AZ::Time::ZeroTimeUs;
+
+ //! The current game tick delta time.
+ //! Can be affected by time system cvars.
+ //! Updated in AdvanceTickDeltaTimes().
+ TimeUs m_simulationTickDeltaTimeUs = AZ::Time::ZeroTimeUs;
+
+ //! The current real tick delta time.
+ //! Will not be affected by time system cvars.
+ //! Updated in AdvanceTickDeltaTimes().
+ TimeUs m_realTickDeltaTimeUs = AZ::Time::ZeroTimeUs;
+
+ TimeUs m_lastSimulationTickTimeUs = AZ::Time::ZeroTimeUs; //!< Used to determine the game tick delta time (affected by cvars).
+ TimeUs m_lastRealTickTimeUs = AZ::Time::ZeroTimeUs; //!< Used to determine the real game tick delta time (not affected by cvars).
+
+ TimeUs m_simulationTickDeltaOverride = AZ::Time::ZeroTimeUs; //
-#include
-#include
-
-namespace AZ
-{
- AZ_CVAR(float, t_scale, 1.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "A scalar amount to adjust time passage by, 1.0 == realtime, 0.5 == half realtime, 2.0 == doubletime");
-
- void TimeSystemComponent::Reflect(AZ::ReflectContext* context)
- {
- if (AZ::SerializeContext* serializeContext = azrtti_cast(context))
- {
- serializeContext->Class()
- ->Version(1);
- }
- }
-
- void TimeSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
- {
- provided.push_back(AZ_CRC_CE("TimeService"));
- }
-
- void TimeSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
- {
- incompatible.push_back(AZ_CRC_CE("TimeService"));
- }
-
- TimeSystemComponent::TimeSystemComponent()
- {
- m_lastInvokedTimeUs = static_cast(AZStd::GetTimeNowMicroSecond());
- AZ::Interface::Register(this);
- ITimeRequestBus::Handler::BusConnect();
- }
-
- TimeSystemComponent::~TimeSystemComponent()
- {
- ITimeRequestBus::Handler::BusDisconnect();
- AZ::Interface::Unregister(this);
- }
-
- void TimeSystemComponent::Activate()
- {
- ;
- }
-
- void TimeSystemComponent::Deactivate()
- {
- ;
- }
-
- TimeMs TimeSystemComponent::GetElapsedTimeMs() const
- {
- return TimeUsToMs(GetElapsedTimeUs());
- }
-
- TimeUs TimeSystemComponent::GetElapsedTimeUs() const
- {
- TimeUs currentTime = static_cast(AZStd::GetTimeNowMicroSecond());
- TimeUs deltaTime = currentTime - m_lastInvokedTimeUs;
-
- if (t_scale != 1.0f)
- {
- float floatDelta = static_cast(deltaTime) * t_scale;
- deltaTime = static_cast(static_cast(floatDelta));
- }
-
- m_accumulatedTimeUs += deltaTime;
- m_lastInvokedTimeUs = currentTime;
-
- return m_accumulatedTimeUs;
- }
-}
diff --git a/Code/Framework/AzCore/AzCore/Time/TimeSystemComponent.h b/Code/Framework/AzCore/AzCore/Time/TimeSystemComponent.h
deleted file mode 100644
index 3ab3dbc234..0000000000
--- a/Code/Framework/AzCore/AzCore/Time/TimeSystemComponent.h
+++ /dev/null
@@ -1,50 +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
- *
- */
-
-#pragma once
-
-#include
-#include
-#include
-
-namespace AZ
-{
- //! Implementation of the ITime system interface.
- class TimeSystemComponent
- : public AZ::Component
- , public ITimeRequestBus::Handler
- {
- public:
-
- AZ_COMPONENT(TimeSystemComponent, "{CE1C5E4F-7DC1-4248-B10C-AC55E8924A48}");
-
- static void Reflect(AZ::ReflectContext* context);
- static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
- static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
-
- TimeSystemComponent();
- virtual ~TimeSystemComponent();
-
- //! AZ::Component overrides.
- //! @{
- void Activate() override;
- void Deactivate() override;
- //! @}
-
- //! ITime overrides.
- //! @{
- TimeMs GetElapsedTimeMs() const override;
- TimeUs GetElapsedTimeUs() const override;
- //! @}
-
- private:
-
- mutable TimeUs m_lastInvokedTimeUs = TimeUs{0};
- mutable TimeUs m_accumulatedTimeUs = TimeUs{0};
- };
-}
diff --git a/Code/Framework/AzCore/AzCore/UnitTest/MockComponentApplication.h b/Code/Framework/AzCore/AzCore/UnitTest/MockComponentApplication.h
index 8f069da9dd..190fa09cb7 100644
--- a/Code/Framework/AzCore/AzCore/UnitTest/MockComponentApplication.h
+++ b/Code/Framework/AzCore/AzCore/UnitTest/MockComponentApplication.h
@@ -41,7 +41,6 @@ namespace UnitTest
MOCK_METHOD0(GetSerializeContext, AZ::SerializeContext* ());
MOCK_METHOD0(GetJsonRegistrationContext, AZ::JsonRegistrationContext* ());
MOCK_METHOD0(GetBehaviorContext, AZ::BehaviorContext* ());
- MOCK_CONST_METHOD0(GetAppRoot, const char* ());
MOCK_CONST_METHOD0(GetEngineRoot, const char* ());
MOCK_CONST_METHOD0(GetExecutableFolder, const char* ());
MOCK_CONST_METHOD1(QueryApplicationType, void(AZ::ApplicationTypeQuery&));
diff --git a/Code/Framework/AzCore/AzCore/UnitTest/Mocks/MockITime.h b/Code/Framework/AzCore/AzCore/UnitTest/Mocks/MockITime.h
new file mode 100644
index 0000000000..3d31056e27
--- /dev/null
+++ b/Code/Framework/AzCore/AzCore/UnitTest/Mocks/MockITime.h
@@ -0,0 +1,119 @@
+/*
+ * 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
+ *
+ */
+#pragma once
+
+#include
+#include
+
+namespace AZ
+{
+ class MockTimeSystem;
+ using NiceTimeSystemMock =::testing::NiceMock;
+
+ //used if you wish to mock any of the Get time functions.
+ class MockTimeSystem
+ : public ITimeRequestBus::Handler
+ {
+ public:
+ MockTimeSystem()
+ {
+ AZ::Interface::Register(this);
+ ITimeRequestBus::Handler::BusConnect();
+ }
+ virtual ~MockTimeSystem()
+ {
+ AZ::Interface::Unregister(this);
+ ITimeRequestBus::Handler::BusDisconnect();
+ }
+
+ MOCK_CONST_METHOD0(GetElapsedTimeMs, TimeMs());
+ MOCK_CONST_METHOD0(GetElapsedTimeUs, TimeUs());
+ MOCK_CONST_METHOD0(GetRealElapsedTimeMs, TimeMs());
+ MOCK_CONST_METHOD0(GetRealElapsedTimeUs, TimeUs());
+ MOCK_CONST_METHOD0(GetSimulationTickDeltaTimeUs, TimeUs());
+ MOCK_CONST_METHOD0(GetRealTickDeltaTimeUs, TimeUs());
+ MOCK_CONST_METHOD0(GetLastSimulationTickTime, TimeUs());
+ MOCK_METHOD1(SetSimulationTickDeltaOverride, void(TimeMs));
+ MOCK_CONST_METHOD0(GetSimulationTickDeltaOverride, TimeMs());
+ MOCK_METHOD1(SetSimulationTickScale, void(float));
+ MOCK_CONST_METHOD0(GetSimulationTickScale, float());
+ MOCK_METHOD1(SetSimulationTickRate, void(int));
+ MOCK_CONST_METHOD0(GetSimulationTickRate, int32_t());
+ };
+
+ //used if you wish to override any of the Get time functions with specific functionality.
+ class StubTimeSystem
+ : public AZ::TimeSystem
+ {
+ public:
+ AZ_RTTI(AZ::StubTimeSystem, "{DD5D5A6A-345F-49FD-A61E-A40E63C49CFA}", AZ::TimeSystem);
+
+ virtual AZ::TimeMs GetElapsedTimeMs() const override
+ {
+ return AZ::Time::ZeroTimeMs;
+ }
+
+ virtual AZ::TimeUs GetElapsedTimeUs() const override
+ {
+ return AZ::Time::ZeroTimeUs;
+ }
+
+ virtual AZ::TimeMs GetRealElapsedTimeMs() const override
+ {
+ return AZ::Time::ZeroTimeMs;
+ }
+
+ virtual AZ::TimeUs GetRealElapsedTimeUs() const override
+ {
+ return AZ::Time::ZeroTimeUs;
+ }
+
+ virtual AZ::TimeUs GetSimulationTickDeltaTimeUs() const override
+ {
+ return AZ::Time::ZeroTimeUs;
+ }
+
+ virtual AZ::TimeUs GetRealTickDeltaTimeUs() const override
+ {
+ return AZ::Time::ZeroTimeUs;
+ }
+
+ virtual AZ::TimeUs GetLastSimulationTickTime() const override
+ {
+ return AZ::Time::ZeroTimeUs;
+ }
+
+ virtual void SetSimulationTickDeltaOverride([[maybe_unused]]TimeMs timeMs) override
+ {
+ }
+
+ virtual TimeMs GetSimulationTickDeltaOverride() const override
+ {
+ return AZ::Time::ZeroTimeMs;
+ }
+
+ virtual void SetSimulationTickScale([[maybe_unused]] float scale) override
+ {
+ }
+
+ virtual float GetSimulationTickScale() const override
+ {
+ return 1.0f;
+ }
+
+ virtual void SetSimulationTickRate([[maybe_unused]] int rate) override
+ {
+ }
+
+ virtual int32_t GetSimulationTickRate() const override
+ {
+ return 0;
+ }
+ };
+
+} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/azcore_files.cmake b/Code/Framework/AzCore/AzCore/azcore_files.cmake
index a5cc3fdcd4..30662f37c4 100644
--- a/Code/Framework/AzCore/AzCore/azcore_files.cmake
+++ b/Code/Framework/AzCore/AzCore/azcore_files.cmake
@@ -654,8 +654,8 @@ set(FILES
Threading/ThreadUtils.h
Threading/ThreadUtils.cpp
Time/ITime.h
- Time/TimeSystemComponent.cpp
- Time/TimeSystemComponent.h
+ Time/TimeSystem.cpp
+ Time/TimeSystem.h
)
# Prevent the following files from being grouped in UNITY builds
diff --git a/Code/Framework/AzCore/AzCore/azcoretestcommon_files.cmake b/Code/Framework/AzCore/AzCore/azcoretestcommon_files.cmake
index 6c25641f9f..e31dc803b9 100644
--- a/Code/Framework/AzCore/AzCore/azcoretestcommon_files.cmake
+++ b/Code/Framework/AzCore/AzCore/azcoretestcommon_files.cmake
@@ -12,5 +12,6 @@ set(FILES
UnitTest/UnitTest.h
UnitTest/TestTypes.h
UnitTest/Mocks/MockFileIOBase.h
+ UnitTest/Mocks/MockITime.h
UnitTest/Mocks/MockSettingsRegistry.h
)
diff --git a/Code/Framework/AzCore/Tests/BehaviorContextFixture.h b/Code/Framework/AzCore/Tests/BehaviorContextFixture.h
index 1895f2e35b..3c6d48add7 100644
--- a/Code/Framework/AzCore/Tests/BehaviorContextFixture.h
+++ b/Code/Framework/AzCore/Tests/BehaviorContextFixture.h
@@ -59,7 +59,6 @@ namespace UnitTest
AZ::SerializeContext* GetSerializeContext() override { return nullptr; }
AZ::BehaviorContext* GetBehaviorContext() override { return m_behaviorContext; }
AZ::JsonRegistrationContext* GetJsonRegistrationContext() override { return nullptr; }
- const char* GetAppRoot() const override { return nullptr; }
const char* GetEngineRoot() const override { return nullptr; }
const char* GetExecutableFolder() const override { return nullptr; }
void EnumerateEntities(const EntityCallback& /*callback*/) override {}
diff --git a/Code/Framework/AzCore/Tests/Components.cpp b/Code/Framework/AzCore/Tests/Components.cpp
index 55b1c193b3..013d998c52 100644
--- a/Code/Framework/AzCore/Tests/Components.cpp
+++ b/Code/Framework/AzCore/Tests/Components.cpp
@@ -1060,26 +1060,21 @@ namespace UnitTest
/**
* UserSettingsComponent test
*/
- class UserSettingsTestApp
- : public ComponentApplication
- , public UserSettingsFileLocatorBus::Handler
- {
- public:
- void SetExecutableFolder(const char* path)
- {
- m_exeDirectory = path;
- }
-
+ class UserSettingsTestApp
+ : public ComponentApplication
+ , public UserSettingsFileLocatorBus::Handler
+ {
+ public:
AZStd::string ResolveFilePath(u32 providerId) override
{
AZStd::string filePath;
if (providerId == UserSettings::CT_GLOBAL)
{
- filePath = (m_exeDirectory / "GlobalUserSettings.xml").String();
+ filePath = (AZ::IO::Path(GetTestFolderPath()) / "GlobalUserSettings.xml").Native();
}
else if (providerId == UserSettings::CT_LOCAL)
{
- filePath = (m_exeDirectory / "LocalUserSettings.xml").String();
+ filePath = (AZ::IO::Path(GetTestFolderPath()) / "LocalUserSettings.xml").Native();
}
return filePath;
}
@@ -1117,7 +1112,6 @@ namespace UnitTest
ComponentApplication::Descriptor appDesc;
appDesc.m_memoryBlocksByteSize = 10 * 1024 * 1024;
Entity* systemEntity = app.Create(appDesc);
- app.SetExecutableFolder(GetTestFolderPath().c_str());
app.UserSettingsFileLocatorBus::Handler::BusConnect();
// Make sure user settings file does not exist at this point
diff --git a/Code/Framework/AzCore/Tests/Debug.cpp b/Code/Framework/AzCore/Tests/Debug.cpp
index 0d6e1a51e0..bd90611af3 100644
--- a/Code/Framework/AzCore/Tests/Debug.cpp
+++ b/Code/Framework/AzCore/Tests/Debug.cpp
@@ -6,7 +6,6 @@
*
*/
-#include
#include
#include
#include
diff --git a/Code/Framework/AzCore/Tests/EBus/ScheduledEventTests.cpp b/Code/Framework/AzCore/Tests/EBus/ScheduledEventTests.cpp
index ec9a09fb09..b9c690edcc 100644
--- a/Code/Framework/AzCore/Tests/EBus/ScheduledEventTests.cpp
+++ b/Code/Framework/AzCore/Tests/EBus/ScheduledEventTests.cpp
@@ -11,7 +11,7 @@
#include
#include
#include
-#include