Extra2D/include/scene/scene_manager.h

141 lines
4.7 KiB
C
Raw Normal View History

2026-02-11 19:40:26 +08:00
#pragma once
#include <core/types.h>
#include <scene/scene.h>
#include <scene/transition_scene.h>
2026-02-11 19:40:26 +08:00
#include <functional>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
namespace extra2d {
// 前向声明
struct RenderCommand;
class TransitionScene;
2026-02-11 19:40:26 +08:00
// ============================================================================
// 场景管理器 - 管理场景的生命周期和切换
// ============================================================================
class SceneManager {
public:
using TransitionCallback = std::function<void()>;
// ------------------------------------------------------------------------
// 单例访问
// ------------------------------------------------------------------------
static SceneManager &getInstance();
// ------------------------------------------------------------------------
// 场景栈操作
// ------------------------------------------------------------------------
// 运行第一个场景
void runWithScene(Ptr<Scene> scene);
// 替换当前场景
void replaceScene(Ptr<Scene> scene);
void replaceScene(Ptr<Scene> scene, TransitionType transition,
float duration = 0.5f);
// 压入新场景(当前场景暂停)
void pushScene(Ptr<Scene> scene);
void pushScene(Ptr<Scene> 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<Scene> getCurrentScene() const;
Ptr<Scene> getPreviousScene() const;
Ptr<Scene> getRootScene() const;
// 通过名称获取场景
Ptr<Scene> 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<RenderCommand> &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> scene);
void enterScene(Ptr<Scene> scene, Ptr<TransitionScene> transitionScene);
2026-02-11 19:40:26 +08:00
private:
void doSceneSwitch();
void startTransition(Ptr<Scene> from, Ptr<Scene> to, TransitionType type,
float duration, Function<void()> stackAction);
void finishTransition();
void dispatchPointerEvents(Scene &scene);
// 创建过渡场景
Ptr<TransitionScene> createTransitionScene(TransitionType type,
float duration,
Ptr<Scene> inScene);
2026-02-11 19:40:26 +08:00
std::stack<Ptr<Scene>> sceneStack_;
std::unordered_map<std::string, Ptr<Scene>> namedScenes_;
// Transition state
bool isTransitioning_ = false;
TransitionType currentTransition_ = TransitionType::None;
Ptr<TransitionScene> activeTransitionScene_;
2026-02-11 19:40:26 +08:00
Function<void()> transitionStackAction_;
TransitionCallback transitionCallback_;
// Next scene to switch to (queued during transition)
Ptr<Scene> nextScene_;
bool sendCleanupToScene_ = false;
Node *hoverTarget_ = nullptr;
Node *captureTarget_ = nullptr;
Vec2 lastPointerWorld_ = Vec2::Zero();
bool hasLastPointerWorld_ = false;
};
} // namespace extra2d