#include "Scene/RuntimeLoop.h" #include namespace XCEngine { namespace Components { namespace { RuntimeLoop::Settings SanitizeSettings(RuntimeLoop::Settings settings) { if (settings.fixedDeltaTime <= 0.0f) { settings.fixedDeltaTime = 1.0f / 50.0f; } if (settings.maxFrameDeltaTime < 0.0f) { settings.maxFrameDeltaTime = 0.0f; } if (settings.maxFixedStepsPerFrame == 0) { settings.maxFixedStepsPerFrame = 1; } return settings; } } // namespace RuntimeLoop::RuntimeLoop(Settings settings) : m_settings(SanitizeSettings(settings)) { } void RuntimeLoop::SetSettings(const Settings& settings) { m_settings = SanitizeSettings(settings); } void RuntimeLoop::Start(Scene* scene) { m_fixedAccumulator = 0.0f; m_paused = false; m_stepRequested = false; m_sceneRuntime.Start(scene); } void RuntimeLoop::Stop() { m_sceneRuntime.Stop(); m_fixedAccumulator = 0.0f; m_paused = false; m_stepRequested = false; } void RuntimeLoop::ReplaceScene(Scene* scene) { m_sceneRuntime.ReplaceScene(scene); m_fixedAccumulator = 0.0f; m_stepRequested = false; } void RuntimeLoop::Tick(float deltaTime) { if (!IsRunning()) { return; } if (m_paused && !m_stepRequested) { return; } const float clampedDeltaTime = std::clamp(deltaTime, 0.0f, m_settings.maxFrameDeltaTime); m_fixedAccumulator += clampedDeltaTime; uint32_t fixedStepsExecuted = 0; while (m_fixedAccumulator >= m_settings.fixedDeltaTime && fixedStepsExecuted < m_settings.maxFixedStepsPerFrame) { m_sceneRuntime.FixedUpdate(m_settings.fixedDeltaTime); m_fixedAccumulator -= m_settings.fixedDeltaTime; ++fixedStepsExecuted; } m_sceneRuntime.Update(clampedDeltaTime); m_sceneRuntime.LateUpdate(clampedDeltaTime); m_stepRequested = false; } void RuntimeLoop::Pause() { if (!IsRunning()) { return; } m_paused = true; m_stepRequested = false; } void RuntimeLoop::Resume() { if (!IsRunning()) { return; } m_paused = false; m_stepRequested = false; } void RuntimeLoop::StepFrame() { if (!IsRunning()) { return; } m_paused = true; m_stepRequested = true; } } // namespace Components } // namespace XCEngine