#pragma once #include #include #include #include #include #include #include namespace easy2d { // 前向声明 struct RenderCommand; class Transition; // ============================================================================ // 场景切换特效类型 // ============================================================================ enum class TransitionType { None, Fade, SlideLeft, SlideRight, SlideUp, SlideDown, Scale, Flip }; // ============================================================================ // 场景管理器 - 管理场景的生命周期和切换 // ============================================================================ class SceneManager { public: using TransitionCallback = std::function; // ------------------------------------------------------------------------ // 单例访问 // ------------------------------------------------------------------------ static SceneManager& getInstance(); // ------------------------------------------------------------------------ // 场景栈操作 // ------------------------------------------------------------------------ // 运行第一个场景 void runWithScene(Ptr scene); // 替换当前场景 void replaceScene(Ptr scene); void replaceScene(Ptr scene, TransitionType transition, float duration = 0.5f); // 压入新场景(当前场景暂停) void pushScene(Ptr scene); void pushScene(Ptr scene, TransitionType transition, float duration = 0.5f); // 弹出当前场景(恢复上一个场景) void popScene(); void popScene(TransitionType transition, float duration = 0.5f); // 弹出到根场景 void popToRootScene(); void popToRootScene(TransitionType transition, float duration = 0.5f); // 弹出到指定场景 void popToScene(const std::string& name); void popToScene(const std::string& name, TransitionType transition, float duration = 0.5f); // ------------------------------------------------------------------------ // 获取场景 // ------------------------------------------------------------------------ Ptr getCurrentScene() const; Ptr getPreviousScene() const; Ptr getRootScene() const; // 通过名称获取场景 Ptr getSceneByName(const std::string& name) const; // ------------------------------------------------------------------------ // 查询 // ------------------------------------------------------------------------ size_t getSceneCount() const { return sceneStack_.size(); } bool isEmpty() const { return sceneStack_.empty(); } bool hasScene(const std::string& name) const; // ------------------------------------------------------------------------ // 更新和渲染 // ------------------------------------------------------------------------ void update(float dt); void render(RenderBackend& renderer); void collectRenderCommands(std::vector& commands); // ------------------------------------------------------------------------ // 过渡控制 // ------------------------------------------------------------------------ bool isTransitioning() const { return isTransitioning_; } void setTransitionCallback(TransitionCallback callback) { transitionCallback_ = callback; } // ------------------------------------------------------------------------ // 清理 // ------------------------------------------------------------------------ void end(); void purgeCachedScenes(); public: SceneManager() = default; ~SceneManager() = default; SceneManager(const SceneManager&) = delete; SceneManager& operator=(const SceneManager&) = delete; // 场景切换(供 Application 使用) void enterScene(Ptr scene); void enterScene(Ptr scene, Ptr transition); private: void doSceneSwitch(); void startTransition(Ptr from, Ptr to, TransitionType type, float duration, Function stackAction); void updateTransition(float dt); void finishTransition(); void dispatchPointerEvents(Scene& scene); std::stack> sceneStack_; std::unordered_map> namedScenes_; // Transition state bool isTransitioning_ = false; TransitionType currentTransition_ = TransitionType::None; float transitionDuration_ = 0.0f; float transitionElapsed_ = 0.0f; Ptr outgoingScene_; Ptr incomingScene_; Ptr activeTransition_; Function transitionStackAction_; TransitionCallback transitionCallback_; // Next scene to switch to (queued during transition) Ptr nextScene_; bool sendCleanupToScene_ = false; Node* hoverTarget_ = nullptr; Node* captureTarget_ = nullptr; Vec2 lastPointerWorld_ = Vec2::Zero(); bool hasLastPointerWorld_ = false; }; } // namespace easy2d