Files
XCEngine/editor/src/Core/PlaySessionController.cpp

167 lines
5.2 KiB
C++

#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);
});
}
if (m_playResumeRequestedHandlerId == 0) {
m_playResumeRequestedHandlerId = context.GetEventBus().Subscribe<PlayModeResumeRequestedEvent>(
[this, &context](const PlayModeResumeRequestedEvent&) {
ResumePlay(context);
});
}
if (m_playStepRequestedHandlerId == 0) {
m_playStepRequestedHandlerId = context.GetEventBus().Subscribe<PlayModeStepRequestedEvent>(
[this, &context](const PlayModeStepRequestedEvent&) {
StepPlay(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;
}
if (m_playResumeRequestedHandlerId != 0) {
context.GetEventBus().Unsubscribe<PlayModeResumeRequestedEvent>(m_playResumeRequestedHandlerId);
m_playResumeRequestedHandlerId = 0;
}
if (m_playStepRequestedHandlerId != 0) {
context.GetEventBus().Unsubscribe<PlayModeStepRequestedEvent>(m_playStepRequestedHandlerId);
m_playStepRequestedHandlerId = 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;
}
bool PlaySessionController::ResumePlay(IEditorContext& context) {
if (context.GetRuntimeMode() != EditorRuntimeMode::Paused || !m_runtimeLoop.IsRunning()) {
return false;
}
m_runtimeLoop.Resume();
context.SetRuntimeMode(EditorRuntimeMode::Play);
context.GetEventBus().Publish(PlayModeResumedEvent{});
return true;
}
bool PlaySessionController::StepPlay(IEditorContext& context) {
if (context.GetRuntimeMode() != EditorRuntimeMode::Paused || !m_runtimeLoop.IsRunning()) {
return false;
}
m_runtimeLoop.StepFrame();
return true;
}
} // namespace Editor
} // namespace XCEngine