feat: add runtime play tick and play-mode scene editing semantics
This commit is contained in:
@@ -377,9 +377,11 @@ add_library(XCEngine STATIC
|
||||
# Scene
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Scene/Scene.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Scene/SceneRuntime.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Scene/RuntimeLoop.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Scene/SceneManager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Scene/Scene.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Scene/SceneRuntime.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Scene/RuntimeLoop.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Scene/SceneManager.cpp
|
||||
|
||||
# Platform
|
||||
|
||||
45
engine/include/XCEngine/Scene/RuntimeLoop.h
Normal file
45
engine/include/XCEngine/Scene/RuntimeLoop.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Scene/SceneRuntime.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
|
||||
class RuntimeLoop {
|
||||
public:
|
||||
struct Settings {
|
||||
float fixedDeltaTime = 1.0f / 50.0f;
|
||||
float maxFrameDeltaTime = 0.1f;
|
||||
uint32_t maxFixedStepsPerFrame = 4;
|
||||
};
|
||||
|
||||
explicit RuntimeLoop(Settings settings = {});
|
||||
|
||||
void SetSettings(const Settings& settings);
|
||||
const Settings& GetSettings() const { return m_settings; }
|
||||
|
||||
void Start(Scene* scene);
|
||||
void Stop();
|
||||
|
||||
void Tick(float deltaTime);
|
||||
void Pause();
|
||||
void Resume();
|
||||
void StepFrame();
|
||||
|
||||
bool IsRunning() const { return m_sceneRuntime.IsRunning(); }
|
||||
bool IsPaused() const { return m_paused; }
|
||||
Scene* GetScene() const { return m_sceneRuntime.GetScene(); }
|
||||
float GetFixedAccumulator() const { return m_fixedAccumulator; }
|
||||
|
||||
private:
|
||||
SceneRuntime m_sceneRuntime;
|
||||
Settings m_settings = {};
|
||||
float m_fixedAccumulator = 0.0f;
|
||||
bool m_paused = false;
|
||||
bool m_stepRequested = false;
|
||||
};
|
||||
|
||||
} // namespace Components
|
||||
} // namespace XCEngine
|
||||
100
engine/src/Scene/RuntimeLoop.cpp
Normal file
100
engine/src/Scene/RuntimeLoop.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#include "Scene/RuntimeLoop.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
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::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
|
||||
Reference in New Issue
Block a user