feat: add runtime play tick and play-mode scene editing semantics
This commit is contained in:
122
editor/src/Core/PlaySessionController.cpp
Normal file
122
editor/src/Core/PlaySessionController.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
#include "Core/PlaySessionController.h"
|
||||
|
||||
#include "Core/EditorEvents.h"
|
||||
#include "Core/EventBus.h"
|
||||
#include "Core/IEditorContext.h"
|
||||
#include "Core/ISceneManager.h"
|
||||
#include "Core/IUndoManager.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
void PlaySessionController::Attach(IEditorContext& context) {
|
||||
if (m_playStartRequestedHandlerId == 0) {
|
||||
m_playStartRequestedHandlerId = context.GetEventBus().Subscribe<PlayModeStartRequestedEvent>(
|
||||
[this, &context](const PlayModeStartRequestedEvent&) {
|
||||
StartPlay(context);
|
||||
});
|
||||
}
|
||||
|
||||
if (m_playStopRequestedHandlerId == 0) {
|
||||
m_playStopRequestedHandlerId = context.GetEventBus().Subscribe<PlayModeStopRequestedEvent>(
|
||||
[this, &context](const PlayModeStopRequestedEvent&) {
|
||||
StopPlay(context);
|
||||
});
|
||||
}
|
||||
|
||||
if (m_playPauseRequestedHandlerId == 0) {
|
||||
m_playPauseRequestedHandlerId = context.GetEventBus().Subscribe<PlayModePauseRequestedEvent>(
|
||||
[this, &context](const PlayModePauseRequestedEvent&) {
|
||||
PausePlay(context);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void PlaySessionController::Detach(IEditorContext& context) {
|
||||
StopPlay(context);
|
||||
|
||||
if (m_playStartRequestedHandlerId != 0) {
|
||||
context.GetEventBus().Unsubscribe<PlayModeStartRequestedEvent>(m_playStartRequestedHandlerId);
|
||||
m_playStartRequestedHandlerId = 0;
|
||||
}
|
||||
|
||||
if (m_playStopRequestedHandlerId != 0) {
|
||||
context.GetEventBus().Unsubscribe<PlayModeStopRequestedEvent>(m_playStopRequestedHandlerId);
|
||||
m_playStopRequestedHandlerId = 0;
|
||||
}
|
||||
|
||||
if (m_playPauseRequestedHandlerId != 0) {
|
||||
context.GetEventBus().Unsubscribe<PlayModePauseRequestedEvent>(m_playPauseRequestedHandlerId);
|
||||
m_playPauseRequestedHandlerId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void PlaySessionController::Update(IEditorContext& context, float deltaTime) {
|
||||
(void)context;
|
||||
if (!m_runtimeLoop.IsRunning()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_runtimeLoop.Tick(deltaTime);
|
||||
}
|
||||
|
||||
bool PlaySessionController::StartPlay(IEditorContext& context) {
|
||||
if (context.GetRuntimeMode() != EditorRuntimeMode::Edit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& sceneManager = context.GetSceneManager();
|
||||
if (!sceneManager.HasActiveScene()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_editorSnapshot = sceneManager.CaptureSceneSnapshot();
|
||||
if (!m_editorSnapshot.hasScene) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sceneManager.RestoreSceneSnapshot(m_editorSnapshot)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sceneManager.SetSceneDocumentDirtyTrackingEnabled(false);
|
||||
m_runtimeLoop.Start(sceneManager.GetScene());
|
||||
context.GetUndoManager().ClearHistory();
|
||||
context.SetRuntimeMode(EditorRuntimeMode::Play);
|
||||
context.GetEventBus().Publish(PlayModeStartedEvent{});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlaySessionController::StopPlay(IEditorContext& context) {
|
||||
if (!IsEditorRuntimeActive(context.GetRuntimeMode())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& sceneManager = context.GetSceneManager();
|
||||
m_runtimeLoop.Stop();
|
||||
sceneManager.SetSceneDocumentDirtyTrackingEnabled(true);
|
||||
|
||||
if (!sceneManager.RestoreSceneSnapshot(m_editorSnapshot)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
context.GetUndoManager().ClearHistory();
|
||||
context.SetRuntimeMode(EditorRuntimeMode::Edit);
|
||||
context.GetEventBus().Publish(PlayModeStoppedEvent{});
|
||||
m_editorSnapshot = {};
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlaySessionController::PausePlay(IEditorContext& context) {
|
||||
if (context.GetRuntimeMode() != EditorRuntimeMode::Play || !m_runtimeLoop.IsRunning()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_runtimeLoop.Pause();
|
||||
context.SetRuntimeMode(EditorRuntimeMode::Paused);
|
||||
context.GetEventBus().Publish(PlayModePausedEvent{});
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Editor
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user