#include #include "Core/EditorContext.h" #include "Core/EditorEvents.h" #include "Core/PlaySessionController.h" #include namespace XCEngine::Editor { namespace { class PlaySessionControllerTest : public ::testing::Test { protected: void SetUp() override { m_context.GetSceneManager().NewScene("Play Session Scene"); } EditorContext m_context; PlaySessionController m_controller; }; TEST_F(PlaySessionControllerTest, StartPlayClonesCurrentSceneAndStopRestoresEditorScene) { auto* editorEntity = m_context.GetSceneManager().CreateEntity("Persistent"); ASSERT_NE(editorEntity, nullptr); const uint64_t editorEntityId = editorEntity->GetID(); editorEntity->GetTransform()->SetLocalPosition(Math::Vector3(1.0f, 2.0f, 3.0f)); int startedCount = 0; int stoppedCount = 0; const uint64_t startedSubscription = m_context.GetEventBus().Subscribe( [&](const PlayModeStartedEvent&) { ++startedCount; }); const uint64_t stoppedSubscription = m_context.GetEventBus().Subscribe( [&](const PlayModeStoppedEvent&) { ++stoppedCount; }); ASSERT_TRUE(m_controller.StartPlay(m_context)); EXPECT_EQ(m_context.GetRuntimeMode(), EditorRuntimeMode::Play); EXPECT_EQ(startedCount, 1); auto* runtimeEntity = m_context.GetSceneManager().GetEntity(editorEntityId); ASSERT_NE(runtimeEntity, nullptr); runtimeEntity->GetTransform()->SetLocalPosition(Math::Vector3(8.0f, 9.0f, 10.0f)); auto* runtimeOnlyEntity = m_context.GetSceneManager().CreateEntity("RuntimeOnly"); ASSERT_NE(runtimeOnlyEntity, nullptr); const uint64_t runtimeOnlyId = runtimeOnlyEntity->GetID(); ASSERT_TRUE(m_controller.StopPlay(m_context)); EXPECT_EQ(m_context.GetRuntimeMode(), EditorRuntimeMode::Edit); EXPECT_EQ(stoppedCount, 1); auto* restoredEntity = m_context.GetSceneManager().GetEntity(editorEntityId); ASSERT_NE(restoredEntity, nullptr); EXPECT_EQ(m_context.GetSceneManager().GetEntity(runtimeOnlyId), nullptr); const Math::Vector3 restoredPosition = restoredEntity->GetTransform()->GetLocalPosition(); EXPECT_NEAR(restoredPosition.x, 1.0f, 1e-4f); EXPECT_NEAR(restoredPosition.y, 2.0f, 1e-4f); EXPECT_NEAR(restoredPosition.z, 3.0f, 1e-4f); m_context.GetEventBus().Unsubscribe(startedSubscription); m_context.GetEventBus().Unsubscribe(stoppedSubscription); } TEST_F(PlaySessionControllerTest, StartAndStopRequestsRouteThroughEventBus) { auto* editorEntity = m_context.GetSceneManager().CreateEntity("Persistent"); ASSERT_NE(editorEntity, nullptr); m_controller.Attach(m_context); m_context.GetEventBus().Publish(PlayModeStartRequestedEvent{}); EXPECT_EQ(m_context.GetRuntimeMode(), EditorRuntimeMode::Play); m_context.GetEventBus().Publish(PlayModeStopRequestedEvent{}); EXPECT_EQ(m_context.GetRuntimeMode(), EditorRuntimeMode::Edit); m_controller.Detach(m_context); } TEST_F(PlaySessionControllerTest, PauseResumeAndStepRequestsDrivePlayStateMachine) { auto* editorEntity = m_context.GetSceneManager().CreateEntity("Persistent"); ASSERT_NE(editorEntity, nullptr); int pausedCount = 0; int resumedCount = 0; const uint64_t pausedSubscription = m_context.GetEventBus().Subscribe( [&](const PlayModePausedEvent&) { ++pausedCount; }); const uint64_t resumedSubscription = m_context.GetEventBus().Subscribe( [&](const PlayModeResumedEvent&) { ++resumedCount; }); m_controller.Attach(m_context); m_context.GetEventBus().Publish(PlayModeStartRequestedEvent{}); EXPECT_EQ(m_context.GetRuntimeMode(), EditorRuntimeMode::Play); m_context.GetEventBus().Publish(PlayModePauseRequestedEvent{}); EXPECT_EQ(m_context.GetRuntimeMode(), EditorRuntimeMode::Paused); EXPECT_EQ(pausedCount, 1); m_context.GetEventBus().Publish(PlayModeStepRequestedEvent{}); EXPECT_EQ(m_context.GetRuntimeMode(), EditorRuntimeMode::Paused); EXPECT_EQ(pausedCount, 1); EXPECT_EQ(resumedCount, 0); m_context.GetEventBus().Publish(PlayModeResumeRequestedEvent{}); EXPECT_EQ(m_context.GetRuntimeMode(), EditorRuntimeMode::Play); EXPECT_EQ(resumedCount, 1); m_context.GetEventBus().Publish(PlayModeStopRequestedEvent{}); EXPECT_EQ(m_context.GetRuntimeMode(), EditorRuntimeMode::Edit); m_controller.Detach(m_context); m_context.GetEventBus().Unsubscribe(pausedSubscription); m_context.GetEventBus().Unsubscribe(resumedSubscription); } } // namespace } // namespace XCEngine::Editor