/** * @file test_scene.cpp * @brief Scene 管理单元测试 * * 测试场景的生命周期、Director 场景管理、场景转换等功能。 */ #include "test_framework.h" #include #include #include #include #include #include #include using namespace extra2d; using namespace extra2d::test; namespace { constexpr f32 EPSILON = 0.001f; bool vec2Equal(const Vec2& a, const Vec2& b, f32 eps = EPSILON) { return std::abs(a.x - b.x) < eps && std::abs(a.y - b.y) < eps; } } // --------------------------------------------------------------------------- // Scene 基本测试 // --------------------------------------------------------------------------- class TestScene : public Scene { public: TestScene() { setName("TestScene"); } void onEnter() override { enterCount++; } void onExit() override { exitCount++; } void onPause() override { pauseCount++; } void onResume() override { resumeCount++; } int enterCount = 0; int exitCount = 0; int pauseCount = 0; int resumeCount = 0; }; TEST(Scene, Create) { auto scene = ptr::make(); TEST_ASSERT_EQ("TestScene", scene->name()); TEST_ASSERT_FALSE(scene->running()); TEST_ASSERT_NOT_NULL(scene->graph()); TEST_ASSERT_NOT_NULL(scene->cam()); } TEST(Scene, SetName) { auto scene = ptr::make(); scene->setName("MyScene"); TEST_ASSERT_EQ("MyScene", scene->name()); } TEST(Scene, SetRunning) { auto scene = ptr::make(); scene->setRunning(true); TEST_ASSERT_TRUE(scene->running()); scene->setRunning(false); TEST_ASSERT_FALSE(scene->running()); } TEST(Scene, LifecycleCallbacks) { auto scene = ptr::make(); scene->onEnter(); TEST_ASSERT_EQ(1, scene->enterCount); scene->onExit(); TEST_ASSERT_EQ(1, scene->exitCount); scene->onPause(); TEST_ASSERT_EQ(1, scene->pauseCount); scene->onResume(); TEST_ASSERT_EQ(1, scene->resumeCount); } TEST(Scene, Update) { auto scene = ptr::make(); auto node = scene->graph()->create(); node->setName("TestNode"); scene->update(0.016f); Node* found = scene->graph()->find("TestNode"); TEST_ASSERT_NOT_NULL(found); } // --------------------------------------------------------------------------- // Director 基本测试 // --------------------------------------------------------------------------- TEST(Director, Create) { Director director; TEST_ASSERT_NULL(director.cur()); } TEST(Director, RunScene) { Director director; auto scene = ptr::make(); director.run(scene); TEST_ASSERT_EQ(scene.get(), director.cur()); TEST_ASSERT_TRUE(scene->running()); TEST_ASSERT_EQ(1, scene->enterCount); } TEST(Director, ReplaceScene) { Director director; auto scene1 = ptr::make(); scene1->setName("Scene1"); director.run(scene1); auto scene2 = ptr::make(); scene2->setName("Scene2"); director.replace(scene2); TEST_ASSERT_EQ(scene2.get(), director.cur()); TEST_ASSERT_EQ(1, scene1->exitCount); TEST_ASSERT_EQ(1, scene2->enterCount); } TEST(Director, PushPopScene) { Director director; auto scene1 = ptr::make(); scene1->setName("Scene1"); director.run(scene1); auto scene2 = ptr::make(); scene2->setName("Scene2"); director.push(scene2); TEST_ASSERT_EQ(scene2.get(), director.cur()); TEST_ASSERT_EQ(1, scene1->pauseCount); TEST_ASSERT_EQ(1, scene2->enterCount); director.pop(); TEST_ASSERT_EQ(scene1.get(), director.cur()); TEST_ASSERT_EQ(1, scene2->exitCount); TEST_ASSERT_EQ(1, scene1->resumeCount); } TEST(Director, Update) { Director director; auto scene = ptr::make(); director.run(scene); auto node = scene->graph()->create(); node->setPos(0, 0); node->run(new MoveTo(1.0f, Vec2(100, 0))); director.update(0.5f); TEST_ASSERT_TRUE(vec2Equal(node->pos, Vec2(50, 0))); } TEST(Director, SceneStack) { Director director; auto scene1 = ptr::make(); scene1->setName("Scene1"); director.run(scene1); auto scene2 = ptr::make(); scene2->setName("Scene2"); director.push(scene2); auto scene3 = ptr::make(); scene3->setName("Scene3"); director.push(scene3); TEST_ASSERT_EQ(scene3.get(), director.cur()); director.pop(); TEST_ASSERT_EQ(scene2.get(), director.cur()); director.pop(); TEST_ASSERT_EQ(scene1.get(), director.cur()); director.pop(); TEST_ASSERT_NULL(director.cur()); } // --------------------------------------------------------------------------- // Trans 场景转换测试 // --------------------------------------------------------------------------- TEST(TransFade, Create) { auto scene1 = ptr::make(); auto scene2 = ptr::make(); TransFade trans; trans.init(1.0f, scene1, scene2); TEST_ASSERT_TRUE(std::abs(trans.duration() - 1.0f) < EPSILON); } TEST(TransFade, Progress) { auto scene1 = ptr::make(); auto scene2 = ptr::make(); TransFade trans; trans.init(2.0f, scene1, scene2); trans.update(1.0f); TEST_ASSERT_TRUE(std::abs(trans.progress() - 0.5f) < EPSILON); } // --------------------------------------------------------------------------- // 场景图集成测试 // --------------------------------------------------------------------------- TEST(Scene, GraphIntegration) { auto scene = ptr::make(); auto parent = scene->graph()->create(); parent->setName("Parent"); parent->setPos(100, 100); auto child = ptr::make(); child->setName("Child"); child->setPos(50, 50); parent->addChild(child); Vec2 worldPos = child->worldPos(); TEST_ASSERT_TRUE(vec2Equal(worldPos, Vec2(150, 150))); } TEST(Scene, CameraIntegration) { auto scene = ptr::make(); auto cam = dynamic_cast(scene->cam()); TEST_ASSERT_NOT_NULL(cam); cam->setOrthoFromSize(1280, 720); cam->setPosition(Vec2(0, 0)); } // --------------------------------------------------------------------------- // 多场景测试 // --------------------------------------------------------------------------- TEST(Director, MultipleSceneSwitches) { Director director; auto scene1 = ptr::make(); scene1->setName("Scene1"); director.run(scene1); std::vector> scenes; scenes.push_back(scene1); for (int i = 0; i < 5; ++i) { auto newScene = ptr::make(); newScene->setName("Scene" + std::to_string(i + 2)); director.replace(newScene); scenes.push_back(newScene); } TEST_ASSERT_EQ(1, scenes[0]->exitCount); TEST_ASSERT_EQ(1, scenes[1]->exitCount); TEST_ASSERT_EQ(1, scenes[2]->exitCount); TEST_ASSERT_EQ(1, scenes[3]->exitCount); TEST_ASSERT_EQ(1, scenes[4]->exitCount); TEST_ASSERT_EQ(0, scenes[5]->exitCount); } // --------------------------------------------------------------------------- // 场景渲染测试 // --------------------------------------------------------------------------- class RenderTestScene : public Scene { public: RenderTestScene() { setName("RenderTestScene"); } void render(RenderCmdBuffer& cmdBuffer) override { renderCalled = true; } bool renderCalled = false; }; TEST(Scene, RenderCallback) { auto scene = ptr::make(); RenderCmdBuffer cmdBuffer; scene->render(cmdBuffer); TEST_ASSERT_TRUE(scene->renderCalled); } // --------------------------------------------------------------------------- // 边界情况测试 // --------------------------------------------------------------------------- TEST(Director, ReplaceWhenNoRunning) { Director director; auto scene = ptr::make(); director.replace(scene); TEST_ASSERT_EQ(scene.get(), director.cur()); } TEST(Director, PopWhenEmpty) { Director director; director.pop(); TEST_ASSERT_NULL(director.cur()); } TEST(Director, PushWhenNoRunning) { Director director; auto scene = ptr::make(); director.push(scene); TEST_ASSERT_EQ(scene.get(), director.cur()); }