Fix play mode runtime scene replacement
This commit is contained in:
@@ -72,6 +72,7 @@ void PlaySessionController::Attach(IEditorContext& context) {
|
||||
|
||||
void PlaySessionController::Detach(IEditorContext& context) {
|
||||
StopPlay(context);
|
||||
ClearRuntimeSceneSyncSubscription(context);
|
||||
|
||||
if (m_playStartRequestedHandlerId != 0) {
|
||||
context.GetEventBus().Unsubscribe<PlayModeStartRequestedEvent>(m_playStartRequestedHandlerId);
|
||||
@@ -141,6 +142,7 @@ bool PlaySessionController::StartPlay(IEditorContext& context) {
|
||||
XCEngine::Input::InputManager::Get().Shutdown();
|
||||
XCEngine::Input::InputManager::Get().Initialize(nullptr);
|
||||
m_runtimeLoop.Start(sceneManager.GetScene());
|
||||
EnsureRuntimeSceneSyncSubscription(context);
|
||||
context.GetUndoManager().ClearHistory();
|
||||
context.SetRuntimeMode(EditorRuntimeMode::Play);
|
||||
context.GetEventBus().Publish(PlayModeStartedEvent{});
|
||||
@@ -152,6 +154,7 @@ bool PlaySessionController::StopPlay(IEditorContext& context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ClearRuntimeSceneSyncSubscription(context);
|
||||
auto& sceneManager = context.GetSceneManager();
|
||||
m_runtimeLoop.Stop();
|
||||
ResetRuntimeInputBridge();
|
||||
@@ -206,6 +209,39 @@ void PlaySessionController::ResetRuntimeInputBridge() {
|
||||
m_hasPendingGameViewInput = false;
|
||||
}
|
||||
|
||||
void PlaySessionController::EnsureRuntimeSceneSyncSubscription(IEditorContext& context) {
|
||||
if (m_runtimeSceneChangedHandlerId != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_runtimeSceneChangedHandlerId = context.GetEventBus().Subscribe<SceneChangedEvent>(
|
||||
[this, &context](const SceneChangedEvent&) {
|
||||
SyncRuntimeSceneIfNeeded(context);
|
||||
});
|
||||
}
|
||||
|
||||
void PlaySessionController::ClearRuntimeSceneSyncSubscription(IEditorContext& context) {
|
||||
if (m_runtimeSceneChangedHandlerId == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
context.GetEventBus().Unsubscribe<SceneChangedEvent>(m_runtimeSceneChangedHandlerId);
|
||||
m_runtimeSceneChangedHandlerId = 0;
|
||||
}
|
||||
|
||||
void PlaySessionController::SyncRuntimeSceneIfNeeded(IEditorContext& context) {
|
||||
if (!IsEditorRuntimeActive(context.GetRuntimeMode())) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* currentScene = context.GetSceneManager().GetScene();
|
||||
if (currentScene == m_runtimeLoop.GetScene()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_runtimeLoop.ReplaceScene(currentScene);
|
||||
}
|
||||
|
||||
void PlaySessionController::ApplyGameViewInputFrame(float deltaTime) {
|
||||
using XCEngine::Input::InputManager;
|
||||
using XCEngine::Input::KeyCode;
|
||||
|
||||
@@ -28,9 +28,14 @@ public:
|
||||
bool ResumePlay(IEditorContext& context);
|
||||
bool StepPlay(IEditorContext& context);
|
||||
|
||||
::XCEngine::Components::Scene* GetRuntimeScene() const { return m_runtimeLoop.GetScene(); }
|
||||
|
||||
private:
|
||||
void ResetRuntimeInputBridge();
|
||||
void ApplyGameViewInputFrame(float deltaTime);
|
||||
void EnsureRuntimeSceneSyncSubscription(IEditorContext& context);
|
||||
void ClearRuntimeSceneSyncSubscription(IEditorContext& context);
|
||||
void SyncRuntimeSceneIfNeeded(IEditorContext& context);
|
||||
|
||||
uint64_t m_playStartRequestedHandlerId = 0;
|
||||
uint64_t m_playStopRequestedHandlerId = 0;
|
||||
@@ -38,6 +43,7 @@ private:
|
||||
uint64_t m_playResumeRequestedHandlerId = 0;
|
||||
uint64_t m_playStepRequestedHandlerId = 0;
|
||||
uint64_t m_gameViewInputFrameHandlerId = 0;
|
||||
uint64_t m_runtimeSceneChangedHandlerId = 0;
|
||||
SceneSnapshot m_editorSnapshot = {};
|
||||
GameViewInputFrameEvent m_pendingGameViewInput = {};
|
||||
GameViewInputFrameEvent m_appliedGameViewInput = {};
|
||||
|
||||
Reference in New Issue
Block a user