2026-04-02 19:37:35 +08:00
|
|
|
#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);
|
|
|
|
|
});
|
|
|
|
|
}
|
2026-04-02 19:56:07 +08:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
});
|
|
|
|
|
}
|
2026-04-02 19:37:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
2026-04-02 19:56:07 +08:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
2026-04-02 19:37:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-02 19:56:07 +08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-02 19:37:35 +08:00
|
|
|
} // namespace Editor
|
|
|
|
|
} // namespace XCEngine
|