docs: expand scene manager API docs

This commit is contained in:
2026-04-03 13:32:30 +08:00
parent cbc653fc97
commit 4016b35214
33 changed files with 1288 additions and 32 deletions

View File

@@ -0,0 +1,44 @@
# ISceneManager Clipboard And Duplicate Operations
**命名空间**: `XCEngine::Editor`
**类型**: `interface methods`
**源文件**: `editor/src/Core/ISceneManager.h`
## 签名
```cpp
virtual void CopyEntity(::XCEngine::Components::GameObject::ID id) = 0;
virtual ::XCEngine::Components::GameObject::ID PasteEntity(
::XCEngine::Components::GameObject::ID parent = 0) = 0;
virtual ::XCEngine::Components::GameObject::ID DuplicateEntity(
::XCEngine::Components::GameObject::ID id) = 0;
virtual bool HasClipboardData() const = 0;
```
## 作用
定义编辑器进程内实体复制、粘贴、复制副本与剪贴板可用性查询接口。
## 契约语义
- `CopyEntity(...)`
- 把指定实体子树复制到编辑器剪贴板。
- `PasteEntity(...)`
- 从当前剪贴板恢复一棵实体子树。
- 可选指定目标父节点;`0` 通常表示粘贴到 root。
- `DuplicateEntity(...)`
- 复制并立即粘贴一个实体子树。
- `HasClipboardData()`
- 查询当前是否存在可粘贴内容。
## 当前实现对应关系
默认实现 [SceneManager](../../Managers/SceneManager/SceneManager.md) 当前使用的是进程内 `ClipboardData` 树,而不是系统剪贴板。
## 相关文档
- [ISceneManager](ISceneManager.md)
- [Entity Tree Operations](Entity-Tree-Operations.md)
- [SceneManager](../../Managers/SceneManager/SceneManager.md)

View File

@@ -0,0 +1,46 @@
# ISceneManager Dirty State And Snapshot
**命名空间**: `XCEngine::Editor`
**类型**: `interface methods`
**源文件**: `editor/src/Core/ISceneManager.h`
## 签名
```cpp
virtual bool IsSceneDirty() const = 0;
virtual void MarkSceneDirty() = 0;
virtual void SetSceneDocumentDirtyTrackingEnabled(bool enabled) = 0;
virtual bool IsSceneDocumentDirtyTrackingEnabled() const = 0;
virtual SceneSnapshot CaptureSceneSnapshot() const = 0;
virtual bool RestoreSceneSnapshot(const SceneSnapshot& snapshot) = 0;
```
## 作用
定义场景 dirty 状态管理,以及 play mode 前后编辑态恢复所需的快照接口。
## 契约语义
- `IsSceneDirty()`
- 查询当前场景是否被视为未保存。
- `MarkSceneDirty()`
- 把当前编辑态标记为 dirty。
- `SetSceneDocumentDirtyTrackingEnabled(...)`
- 控制实体编辑是否自动触发 dirty。
- `CaptureSceneSnapshot()`
- 抓取可恢复的编辑态快照。
- `RestoreSceneSnapshot(...)`
- 从快照恢复编辑态场景。
## 设计含义
- 这组接口让 `ISceneManager` 不只是“场景树服务”,还承担 play mode 进出的一部分状态恢复职责。
- 因此它和 [SceneSnapshot](../SceneSnapshot/SceneSnapshot.md)、[PlaySessionController](../PlaySessionController/PlaySessionController.md) 有直接协作关系。
## 相关文档
- [ISceneManager](ISceneManager.md)
- [Scene Lifecycle](Scene-Lifecycle.md)
- [SceneSnapshot](../SceneSnapshot/SceneSnapshot.md)

View File

@@ -0,0 +1,57 @@
# ISceneManager Entity Tree Operations
**命名空间**: `XCEngine::Editor`
**类型**: `interface methods`
**源文件**: `editor/src/Core/ISceneManager.h`
## 签名
```cpp
virtual ::XCEngine::Components::GameObject* CreateEntity(
const std::string& name,
::XCEngine::Components::GameObject* parent = nullptr) = 0;
virtual void DeleteEntity(::XCEngine::Components::GameObject::ID id) = 0;
virtual void RenameEntity(
::XCEngine::Components::GameObject::ID id,
const std::string& newName) = 0;
virtual ::XCEngine::Components::GameObject* GetEntity(
::XCEngine::Components::GameObject::ID id) = 0;
virtual const std::vector<::XCEngine::Components::GameObject*>& GetRootEntities() const = 0;
virtual void MoveEntity(
::XCEngine::Components::GameObject::ID id,
::XCEngine::Components::GameObject::ID newParent) = 0;
```
## 作用
定义编辑器实体树最基础的创建、查询、重命名、删除和层级移动能力。
## 契约语义
- `CreateEntity(...)`
- 在当前编辑态场景里创建一个实体。
- 可选挂到指定父节点下。
- `DeleteEntity(...)`
- 删除指定实体。
- 默认实现通常会递归处理其子节点。
- `RenameEntity(...)`
- 修改实体显示名。
- `GetEntity(...)`
-`entityId` 查询实体。
- `GetRootEntities()`
- 返回当前场景 root 节点集合。
- `MoveEntity(...)`
- 调整实体父级关系。
## 设计含义
- 这组接口定义的是“编辑器层级树服务”,不只是底层 `Scene` 容器访问。
- 面板、命令和 action router 通常都通过这组接口改动层级,而不是直接操作 `Scene`
## 相关文档
- [ISceneManager](ISceneManager.md)
- [Clipboard And Duplicate Operations](Clipboard-And-Duplicate-Operations.md)
- [SceneManager](../../Managers/SceneManager/SceneManager.md)

View File

@@ -20,19 +20,36 @@
## 核心接口
| 方法 | 作用 |
|------|------|
| `CreateEntity()` / `DeleteEntity()` / `RenameEntity()` | 实体生命周期管理。 |
| `GetEntity()` / `GetRootEntities()` | 查询当前实体树。 |
| `CopyEntity()` / `PasteEntity()` / `DuplicateEntity()` / `MoveEntity()` | 编辑器层级编辑操作。 |
| `HasClipboardData()` | 查询是否有可粘贴内容。 |
| `NewScene()` / `LoadScene()` / `SaveScene()` / `SaveSceneAs()` / `LoadStartupScene()` | 场景文件生命周期。 |
| `HasActiveScene()` / `IsSceneDirty()` / `MarkSceneDirty()` | 当前场景状态。 |
| `GetCurrentScenePath()` / `GetCurrentSceneName()` | 当前场景元信息。 |
| `CreateDemoScene()` | 创建内置示例场景。 |
### 实体树操作
- [Entity Tree Operations](Entity-Tree-Operations.md)
### 剪贴板与复制副本
- [Clipboard And Duplicate Operations](Clipboard-And-Duplicate-Operations.md)
### 场景文件生命周期
- [Scene Lifecycle](Scene-Lifecycle.md)
### dirty 状态与快照
- [Dirty State And Snapshot](Dirty-State-And-Snapshot.md)
## 当前实现关注点
当前默认实现 [SceneManager](../../Managers/SceneManager/SceneManager.md) 已经把接口从“实体树服务”扩展成了更完整的编辑态场景工作流服务,尤其包括:
- 进程内实体剪贴板
- dirty tracking 开关
- 启动场景回退
- `SceneSnapshot` 抓取与恢复
如果你要理解这些接口在当前产品里的真实行为,优先看 `SceneManager` 的对应方法页,而不是只按接口命名做推断。
## 相关文档
- [Core](../Core.md)
- [SceneManager](../../Managers/SceneManager/SceneManager.md)
- [SceneSnapshot](../SceneSnapshot/SceneSnapshot.md)
- [SceneCommands](../../Commands/SceneCommands/SceneCommands.md)

View File

@@ -0,0 +1,56 @@
# ISceneManager Scene Lifecycle
**命名空间**: `XCEngine::Editor`
**类型**: `interface methods`
**源文件**: `editor/src/Core/ISceneManager.h`
## 签名
```cpp
virtual void NewScene(const std::string& name = "Untitled Scene") = 0;
virtual bool LoadScene(const std::string& filePath) = 0;
virtual bool SaveScene() = 0;
virtual bool SaveSceneAs(const std::string& filePath) = 0;
virtual bool LoadStartupScene(const std::string& projectPath) = 0;
virtual bool HasActiveScene() const = 0;
virtual const std::string& GetCurrentScenePath() const = 0;
virtual const std::string& GetCurrentSceneName() const = 0;
virtual ::XCEngine::Components::Scene* GetScene() = 0;
virtual const ::XCEngine::Components::Scene* GetScene() const = 0;
virtual void CreateDemoScene() = 0;
```
## 作用
定义编辑态场景的创建、加载、保存、启动场景解析与当前场景查询接口。
## 契约语义
- `NewScene(...)`
- 创建新的编辑态场景。
- `LoadScene(...)`
- 从磁盘载入场景文件。
- `SaveScene()` / `SaveSceneAs(...)`
- 把当前编辑态写回磁盘。
- `LoadStartupScene(...)`
- 按项目配置或默认规则解析启动场景。
- `HasActiveScene()`
- 查询当前是否有活动场景。
- `GetCurrentScenePath()` / `GetCurrentSceneName()`
- 返回当前场景元信息。
- `GetScene()`
- 返回当前编辑态 `Scene` 指针。
- `CreateDemoScene()`
- 创建最小可用示例场景。
## 当前实现对应关系
默认实现 [SceneManager](../../Managers/SceneManager/SceneManager.md) 当前还负责启动场景缺失时的 demo scene 回退。
## 相关文档
- [ISceneManager](ISceneManager.md)
- [Dirty State And Snapshot](Dirty-State-And-Snapshot.md)
- [SceneManager](../../Managers/SceneManager/SceneManager.md)

View File

@@ -0,0 +1,33 @@
# SceneManager::CaptureSceneSnapshot
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
SceneSnapshot CaptureSceneSnapshot() const override;
```
## 作用
抓取当前编辑态场景的可恢复快照。
## 当前实现行为
- 当前没有活动场景时,会返回一个空 `SceneSnapshot`
- 否则会填充:
- `hasScene = true`
- `sceneData = m_scene->SerializeToString()`
- `scenePath = m_currentScenePath`
- `dirty = m_isSceneDirty`
- 该快照是当前 play mode 恢复编辑态的重要基础。
## 相关文档
- [SceneManager](SceneManager.md)
- [RestoreSceneSnapshot](RestoreSceneSnapshot.md)
- [SceneSnapshot](../../Core/SceneSnapshot/SceneSnapshot.md)

View File

@@ -0,0 +1,32 @@
# SceneManager::SceneManager
**命名空间**: `XCEngine::Editor`
**类型**: `constructor`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
explicit SceneManager(EventBus* eventBus = nullptr);
```
## 作用
构造一个场景管理器,并可选绑定 Editor 事件总线。
## 当前实现行为
- 当前实现只把传入的 `eventBus` 指针保存到 `m_eventBus`
- 构造阶段不会自动创建场景、不会发布事件,也不会预建 demo scene。
- 其余状态字段继续使用类内默认初始值:
- `m_currentSceneName = "Untitled Scene"`
- `m_isSceneDirty = false`
- `m_sceneDocumentDirtyTrackingEnabled = true`
## 相关文档
- [SceneManager](SceneManager.md)
- [CreateEntity](CreateEntity.md)
- [NewScene](NewScene.md)

View File

@@ -0,0 +1,34 @@
# SceneManager::CopyEntity
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
void CopyEntity(::XCEngine::Components::GameObject::ID id);
```
## 作用
把指定实体子树复制到 `SceneManager` 的进程内剪贴板。
## 当前实现行为
- 当前没有场景或找不到目标实体时直接返回。
- 成功时会调用内部 `CopyEntityRecursive(...)` 生成 `ClipboardData` 树。
- 当前复制内容包括:
- 实体名
- 本地 position / rotation / scale
- 所有非 transform 组件的序列化结果
- 全部子节点的递归副本
- 复制结果保存在 `m_clipboard`,不会触发场景 dirty也不会发布事件。
## 相关文档
- [SceneManager](SceneManager.md)
- [PasteEntity](PasteEntity.md)
- [DuplicateEntity](DuplicateEntity.md)

View File

@@ -0,0 +1,33 @@
# SceneManager::CreateDemoScene
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
void CreateDemoScene() override;
```
## 作用
创建当前内置的最小演示场景,作为启动场景缺失时的回退内容。
## 当前实现行为
- 会创建一个名为 `"Main Scene"` 的新场景。
- 清空根节点缓存、剪贴板和当前场景路径。
- 把当前场景名更新为新场景名,并把 dirty 标记设为 `true`
- 随后创建两个 root 实体:
- `"Main Camera"`,附加 `CameraComponent`
- `"Directional Light"`,附加 `LightComponent`
- 末尾会再次 `SyncRootEntities()`,并触发 `OnSceneChanged` 与可选的 `SceneChangedEvent`
## 相关文档
- [SceneManager](SceneManager.md)
- [LoadStartupScene](LoadStartupScene.md)
- [NewScene](NewScene.md)

View File

@@ -0,0 +1,42 @@
# SceneManager::CreateEntity
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
::XCEngine::Components::GameObject* CreateEntity(
const std::string& name,
::XCEngine::Components::GameObject* parent = nullptr);
```
## 作用
在当前场景里创建一个新实体并同步更新层级缓存、dirty 状态与事件通知。
## 当前实现行为
- 如果当前还没有场景,会先隐式创建一个名为 `"EditorScene"` 的临时场景。
- 随后调用 `m_scene->CreateGameObject(name, parent)` 创建实体。
- 创建成功后会依次:
- `SyncRootEntities()`
- `MarkSceneDirty()`
- `OnEntityCreated.Invoke(entityId)`
- `OnSceneChanged.Invoke()`
- 如果存在 `EventBus`,还会同步发布:
- `EntityCreatedEvent`
- `SceneChangedEvent`
## 返回值
- 返回新创建的 `GameObject*`
## 相关文档
- [SceneManager](SceneManager.md)
- [DeleteEntity](DeleteEntity.md)
- [MarkSceneDirty](MarkSceneDirty.md)

View File

@@ -0,0 +1,36 @@
# SceneManager::DeleteEntity
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
void DeleteEntity(::XCEngine::Components::GameObject::ID id);
```
## 作用
递归删除一个实体及其所有子节点。
## 当前实现行为
- 当前没有活动场景时直接返回。
- 找不到目标实体时直接返回。
- 删除前会先复制一份 `children` 数组,再递归调用 `DeleteEntity(childId)` 删除全部子节点。
- 最后调用 `m_scene->DestroyGameObject(entity)` 删除当前节点。
- 删除完成后会:
- `SyncRootEntities()`
- `MarkSceneDirty()`
- `OnEntityDeleted.Invoke(entityId)`
- `OnSceneChanged.Invoke()`
- 如果存在 `EventBus`,还会发布 `EntityDeletedEvent``SceneChangedEvent`
## 相关文档
- [SceneManager](SceneManager.md)
- [CreateEntity](CreateEntity.md)
- [MoveEntity](MoveEntity.md)

View File

@@ -0,0 +1,33 @@
# SceneManager::DuplicateEntity
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
::XCEngine::Components::GameObject::ID DuplicateEntity(
::XCEngine::Components::GameObject::ID id);
```
## 作用
复制一个实体子树,并把副本挂到与原对象相同的父节点下。
## 当前实现行为
- 当前没有场景或找不到目标实体时返回 `0`
- 实现本身没有独立复制路径,而是直接复用:
- `CopyEntity(id)`
- `PasteEntity(parentId)`
- 如果目标实体有父节点,会把原父节点 id 作为 `PasteEntity(...)` 的参数。
- 如果目标实体本来是 root则副本也会作为 root 创建。
## 相关文档
- [SceneManager](SceneManager.md)
- [CopyEntity](CopyEntity.md)
- [PasteEntity](PasteEntity.md)

View File

@@ -0,0 +1,30 @@
# SceneManager::GetCurrentSceneName
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
const std::string& GetCurrentSceneName() const override;
```
## 作用
返回当前场景的显示名称。
## 当前实现行为
- 这是头文件内联访问器,直接返回 `m_currentSceneName` 的常量引用。
- 新建但未保存时,名称可能来自 [NewScene](NewScene.md) 传入值。
- 加载或恢复场景后,名称通常会重新从 `Scene` 对象同步。
## 相关文档
- [SceneManager](SceneManager.md)
- [GetCurrentScenePath](GetCurrentScenePath.md)
- [NewScene](NewScene.md)
- [LoadScene](LoadScene.md)

View File

@@ -0,0 +1,29 @@
# SceneManager::GetCurrentScenePath
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
const std::string& GetCurrentScenePath() const override;
```
## 作用
返回当前活动场景的路径字符串。
## 当前实现行为
- 这是头文件内联访问器,直接返回 `m_currentScenePath` 的常量引用。
- 对新建但尚未保存的场景,这个字符串可能为空。
- 路径通常由 [LoadScene](LoadScene.md)、[SaveScene](SaveScene.md)、[SaveSceneAs](SaveSceneAs.md) 和 [RestoreSceneSnapshot](RestoreSceneSnapshot.md) 维护。
## 相关文档
- [SceneManager](SceneManager.md)
- [GetCurrentSceneName](GetCurrentSceneName.md)
- [SaveSceneAs](SaveSceneAs.md)

View File

@@ -0,0 +1,31 @@
# SceneManager::GetEntity
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
::XCEngine::Components::GameObject* GetEntity(::XCEngine::Components::GameObject::ID id);
const ::XCEngine::Components::GameObject* GetEntity(::XCEngine::Components::GameObject::ID id) const;
```
## 作用
通过实体 ID 在当前活动场景中查找 `GameObject`
## 当前实现行为
- 这是定义在头文件中的内联访问器。
-`m_scene == nullptr`,直接返回 `nullptr`
- 否则转发到 `m_scene->FindByID(id)`
- `const` 与非 `const` 重载只是在返回类型和可变性上不同,查找语义一致。
## 相关文档
- [SceneManager](SceneManager.md)
- [GetScene](GetScene.md)
- [GetRootEntities](GetRootEntities.md)

View File

@@ -0,0 +1,30 @@
# SceneManager::GetRootEntities
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
const std::vector<::XCEngine::Components::GameObject*>& GetRootEntities() const;
```
## 作用
返回当前场景 root game object 的缓存数组。
## 当前实现行为
- 这是头文件内联访问器,直接返回 `m_rootEntities` 的常量引用。
- 该数组不是实时查询 `Scene` 的临时结果,而是由 `SyncRootEntities()` 在场景切换、创建、删除、粘贴和移动层级后同步刷新。
- 因此调用方通常可以把它视为 `HierarchyPanel` 等 UI 的稳定只读输入。
## 相关文档
- [SceneManager](SceneManager.md)
- [GetEntity](GetEntity.md)
- [CreateEntity](CreateEntity.md)
- [MoveEntity](MoveEntity.md)

View File

@@ -0,0 +1,30 @@
# SceneManager::GetScene
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
::XCEngine::Components::Scene* GetScene() override;
const ::XCEngine::Components::Scene* GetScene() const override;
```
## 作用
返回当前活动场景对象指针。
## 当前实现行为
- 这是头文件内联访问器,直接返回 `m_scene.get()`
- 若当前没有活动场景,则返回 `nullptr`
- `const` 与非 `const` 重载只在返回可变性上不同。
## 相关文档
- [SceneManager](SceneManager.md)
- [HasActiveScene](HasActiveScene.md)
- [GetEntity](GetEntity.md)

View File

@@ -0,0 +1,29 @@
# SceneManager::HasActiveScene
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
bool HasActiveScene() const override;
```
## 作用
判断当前是否存在活动场景。
## 当前实现行为
- 这是头文件内联访问器。
- 当前实现等价于 `m_scene != nullptr`
- 它不检查场景是否已保存、是否 dirty也不检查 root 数量。
## 相关文档
- [SceneManager](SceneManager.md)
- [GetScene](GetScene.md)
- [IsSceneDirty](IsSceneDirty.md)

View File

@@ -0,0 +1,29 @@
# SceneManager::HasClipboardData
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
bool HasClipboardData() const;
```
## 作用
判断当前进程内实体剪贴板是否已有可粘贴的子树数据。
## 当前实现行为
- 这是头文件内联访问器。
- 当前实现等价于 `m_clipboard.has_value()`
- 该剪贴板只由 [CopyEntity](CopyEntity.md)、[PasteEntity](PasteEntity.md)、[DuplicateEntity](DuplicateEntity.md) 和场景切换/恢复流程维护,不是系统剪贴板。
## 相关文档
- [SceneManager](SceneManager.md)
- [CopyEntity](CopyEntity.md)
- [PasteEntity](PasteEntity.md)

View File

@@ -0,0 +1,29 @@
# SceneManager::IsSceneDirty
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
bool IsSceneDirty() const override;
```
## 作用
返回当前场景的 dirty 标记。
## 当前实现行为
- 这是头文件内联访问器,直接返回 `m_isSceneDirty`
- 该标记通常由 [MarkSceneDirty](MarkSceneDirty.md)、加载/保存流程和快照恢复流程维护。
- 它本身不会重新计算场景是否有差异,只是读取当前缓存状态。
## 相关文档
- [SceneManager](SceneManager.md)
- [MarkSceneDirty](MarkSceneDirty.md)
- [SetSceneDocumentDirtyTrackingEnabled](SetSceneDocumentDirtyTrackingEnabled.md)

View File

@@ -0,0 +1,28 @@
# SceneManager::IsSceneDocumentDirtyTrackingEnabled
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
bool IsSceneDocumentDirtyTrackingEnabled() const override;
```
## 作用
查询当前是否允许实体编辑自动把场景标记为 dirty。
## 当前实现行为
- 这是头文件内联访问器,直接返回 `m_sceneDocumentDirtyTrackingEnabled`
- 当它为 `false` 时,[MarkSceneDirty](MarkSceneDirty.md) 会提前返回。
## 相关文档
- [SceneManager](SceneManager.md)
- [SetSceneDocumentDirtyTrackingEnabled](SetSceneDocumentDirtyTrackingEnabled.md)
- [MarkSceneDirty](MarkSceneDirty.md)

View File

@@ -0,0 +1,41 @@
# SceneManager::LoadScene
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
bool LoadScene(const std::string& filePath) override;
```
## 作用
从磁盘加载场景文件,并把当前编辑态切换到该场景。
## 当前实现行为
- 会先验证 `filePath` 是否存在且是常规文件。
- 成功后创建新的 `Scene` 实例,并在 `ResourceManager::ScopedDeferredSceneLoad` 作用域内调用 `scene->Load(filePath)`
- 加载完成后会:
- 用新场景替换 `m_scene`
- 清空 `m_clipboard`
- `SyncRootEntities()`
- 记录 `m_currentScenePath`
- 根据场景对象更新 `m_currentSceneName`
- 清除 dirty 标记
- 最后触发 `OnSceneChanged`,并在存在 `EventBus` 时发布 `SceneChangedEvent`
## 返回值
- `true`: 成功完成加载。
- `false`: 文件不存在、路径无效或加载前置检查失败。
## 相关文档
- [SceneManager](SceneManager.md)
- [SaveScene](SaveScene.md)
- [RestoreSceneSnapshot](RestoreSceneSnapshot.md)

View File

@@ -0,0 +1,36 @@
# SceneManager::LoadStartupScene
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
bool LoadStartupScene(const std::string& projectPath) override;
```
## 作用
解析项目启动场景,并在找不到可用场景时自动回退到 demo scene。
## 当前实现行为
- 会先调用 `ResolveDefaultScenePath(projectPath)` 推导默认场景路径。
- 如果该路径可用,且 `LoadScene(defaultScenePath)` 成功,则直接返回 `true`
- 否则会执行回退路径:
- `CreateDemoScene()`
- `SaveSceneAs(defaultScenePath)`
- 因此该接口既负责“加载”,也负责“首次可用场景初始化”。
## 返回值
- 返回最终 `LoadScene(...)``SaveSceneAs(...)` 的结果。
## 相关文档
- [SceneManager](SceneManager.md)
- [LoadScene](LoadScene.md)
- [CreateDemoScene](CreateDemoScene.md)

View File

@@ -0,0 +1,29 @@
# SceneManager::MarkSceneDirty
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
void MarkSceneDirty() override;
```
## 作用
在允许 dirty tracking 时,把当前场景标记为 dirty。
## 当前实现行为
- 如果 `m_sceneDocumentDirtyTrackingEnabled == false`,会直接返回,不修改任何状态。
- 否则调用内部 `SetSceneDirty(true)`
- 该方法本身不发布事件,也不刷新根节点缓存。
## 相关文档
- [SceneManager](SceneManager.md)
- [CreateEntity](CreateEntity.md)
- [CaptureSceneSnapshot](CaptureSceneSnapshot.md)

View File

@@ -0,0 +1,41 @@
# SceneManager::MoveEntity
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
void MoveEntity(
::XCEngine::Components::GameObject::ID id,
::XCEngine::Components::GameObject::ID newParent);
```
## 作用
修改实体父级,并同步刷新层级缓存和事件。
## 当前实现行为
- 当前没有场景或找不到目标实体时直接返回。
- 会先记录旧父节点 id。
- `newParent != 0` 时会查找新的父节点对象;传入 `0` 表示移动到 root。
- 之后调用 `obj->SetParent(newParent)` 修改层级关系。
- 成功后会:
- `SyncRootEntities()`
- `MarkSceneDirty()`
- `OnEntityChanged.Invoke(id)`
- `OnSceneChanged.Invoke()`
- 如果存在 `EventBus`,还会额外发布:
- `EntityParentChangedEvent`
- `EntityChangedEvent`
- `SceneChangedEvent`
## 相关文档
- [SceneManager](SceneManager.md)
- [CreateEntity](CreateEntity.md)
- [DeleteEntity](DeleteEntity.md)

View File

@@ -0,0 +1,35 @@
# SceneManager::NewScene
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
void NewScene(const std::string& name = "Untitled Scene") override;
```
## 作用
创建一个新的空编辑态场景,并重置与旧场景相关的路径和剪贴板状态。
## 当前实现行为
- 直接创建 `std::make_unique<Scene>(name)` 替换当前场景。
- 清空:
- `m_rootEntities`
- `m_clipboard`
- `m_currentScenePath`
- 同步设置:
- `m_currentSceneName = name`
- `dirty = true`
- 最后触发 `OnSceneChanged`,并在存在 `EventBus` 时发布 `SceneChangedEvent`
## 相关文档
- [SceneManager](SceneManager.md)
- [LoadScene](LoadScene.md)
- [CreateDemoScene](CreateDemoScene.md)

View File

@@ -0,0 +1,45 @@
# SceneManager::PasteEntity
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
::XCEngine::Components::GameObject::ID PasteEntity(
::XCEngine::Components::GameObject::ID parent = 0);
```
## 作用
从进程内剪贴板重建一棵实体子树,并可选挂到指定父节点下。
## 当前实现行为
-`m_clipboard` 为空或当前没有场景时,直接返回 `0`
- 内部通过 `PasteEntityRecursive(...)` 重建实体树:
- 创建新实体
- 恢复本地变换
- 通过 `ComponentFactoryRegistry` 创建组件
- 用组件自己的 `Deserialize(...)` 还原组件数据
- 递归粘贴全部子节点
- 成功后会:
- `SyncRootEntities()`
- `MarkSceneDirty()`
- `OnEntityCreated.Invoke(newEntityId)`
- `OnSceneChanged.Invoke()`
- 如果存在 `EventBus`,还会发布 `EntityCreatedEvent``SceneChangedEvent`
## 返回值
- 返回新建根节点的实体 id。
- 失败时返回 `0`
## 相关文档
- [SceneManager](SceneManager.md)
- [CopyEntity](CopyEntity.md)
- [DuplicateEntity](DuplicateEntity.md)

View File

@@ -0,0 +1,40 @@
# SceneManager::RenameEntity
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
void RenameEntity(
::XCEngine::Components::GameObject::ID id,
const std::string& newName);
```
## 作用
修改指定实体的显示名称。
## 当前实现行为
- 当前没有场景时直接返回。
- 找不到目标实体时直接返回。
- 成功时会调用 `obj->SetName(newName)`
- 随后会:
- `MarkSceneDirty()`
- `OnEntityChanged.Invoke(id)`
- 如果存在 `EventBus`,还会发布 `EntityChangedEvent`
## 当前实现边界
- 当前不会单独触发 `OnSceneChanged`
- 当前不会刷新 root 缓存,因为重命名不改变层级关系。
## 相关文档
- [SceneManager](SceneManager.md)
- [MoveEntity](MoveEntity.md)
- [MarkSceneDirty](MarkSceneDirty.md)

View File

@@ -0,0 +1,49 @@
# SceneManager::RestoreSceneSnapshot
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
bool RestoreSceneSnapshot(const SceneSnapshot& snapshot) override;
```
## 作用
`SceneSnapshot` 恢复编辑态场景。
## 当前实现行为
### 快照不包含场景时
- 会清空当前场景、根节点缓存、剪贴板和当前场景路径。
- 把场景名恢复成 `"Untitled Scene"`
- 把 dirty 标记恢复为 `snapshot.dirty`
- 然后触发 `OnSceneChanged`,并在存在 `EventBus` 时发布 `SceneChangedEvent`
### 快照包含场景时
- 会先创建新的 `Scene`
-`ResourceManager::ScopedDeferredSceneLoad` 作用域内调用 `DeserializeFromString(snapshot.sceneData)`
- 成功后会:
- 用新场景替换 `m_scene`
- 清空 `m_clipboard`
- `SyncRootEntities()`
- 恢复 `m_currentScenePath`
- 从场景对象恢复 `m_currentSceneName`
- 恢复 dirty 标记
- 最后同样会触发 `OnSceneChanged` 并发布 `SceneChangedEvent`
## 返回值
- 当前实现成功走完上述流程后始终返回 `true`
## 相关文档
- [SceneManager](SceneManager.md)
- [CaptureSceneSnapshot](CaptureSceneSnapshot.md)
- [LoadScene](LoadScene.md)

View File

@@ -0,0 +1,39 @@
# SceneManager::SaveScene
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
bool SaveScene() override;
```
## 作用
把当前场景保存到 `m_currentScenePath` 指向的位置。
## 当前实现行为
- 当前没有场景时返回 `false`
- 当前场景路径为空时返回 `false`
- 保存前会强制把目标扩展名改写成 `.xc`
- 会自动创建目标目录。
- 然后调用 `m_scene->Save(savePath.string())` 写盘。
- 保存成功后会:
- 更新 `m_currentScenePath`
- 清除 dirty 标记
## 返回值
- `true`: 保存成功。
- `false`: 当前没有可保存场景或当前场景路径为空。
## 相关文档
- [SceneManager](SceneManager.md)
- [SaveSceneAs](SaveSceneAs.md)
- [LoadScene](LoadScene.md)

View File

@@ -0,0 +1,34 @@
# SceneManager::SaveSceneAs
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
bool SaveSceneAs(const std::string& filePath) override;
```
## 作用
把当前场景保存到新的目标路径,并更新当前场景路径与场景名元数据。
## 当前实现行为
- 当前没有场景或 `filePath` 为空时返回 `false`
- 保存时同样会把扩展名规范化成 `.xc`
- 会自动创建目标目录。
- 随后调用 `m_scene->Save(savePath.string())`
- 成功后会:
- 更新 `m_currentScenePath`
-`m_scene->GetName()` 更新 `m_currentSceneName`
- 清除 dirty 标记
## 相关文档
- [SceneManager](SceneManager.md)
- [SaveScene](SaveScene.md)
- [LoadStartupScene](LoadStartupScene.md)

View File

@@ -6,41 +6,150 @@
**源文件**: `editor/src/Managers/SceneManager.h`
**描述**: `ISceneManager` 的默认实现,负责编辑器场景对象树、复制粘贴、场景文件加载保存、脏状态快照恢复。
**描述**: `ISceneManager` 的默认实现,负责编辑器场景对象树、复制粘贴、场景文件加载保存、脏状态、启动场景回退以及场景快照恢复。
## 概述
`SceneManager` 是当前编辑器里最重的服务之一。
`SceneManager` 是当前 Editor 里最核心的状态服务之一。
它不只是“提供一个当前场景指针”,而是把下面几条工作流集中到同一个实现里:
它当前同时负责:
- 实体树的创建、删除、重命名、复制、粘贴、复制副本和层级移动
- 场景新建、加载、保存、另存为与启动场景加载
- 脏状态与 dirty tracking 开关
- play mode 使用的 `SceneSnapshot` 抓取与恢复
- 本地 `Core::Event``EventBus` 的同步通知
- `Scene` 与根实体列表
- 实体新建/删除/重命名
- 复制/粘贴/复制快照
- 层级移动
- 场景文件新建、加载、保存
- 场景脏状态
- 场景快照抓取与恢复
-`EventBus` 和本地 `Core::Event` 发布事件
## 当前内部状态
## 当前实现说明
当前主要状态字段包括:
- 内部持有 `std::unique_ptr<Components::Scene>`
- `CreateEntity()` 会在没有场景时自动创建 `"EditorScene"`
- 删除实体时会递归删除全部子节点。
- 剪贴板数据是自定义 `ClipboardData` 树,不是系统剪贴板
- `CaptureSceneSnapshot()` / `RestoreSceneSnapshot()` 是当前 undo 的基础。
- `m_scene`
当前活动 `Scene`
- `m_rootEntities`
root game object 缓存,供层级面板直接读取
- `m_clipboard`
编辑器进程内的实体复制树,不是系统剪贴板。
- `m_currentScenePath`
当前场景路径。
- `m_currentSceneName`
当前场景名。
- `m_isSceneDirty`
当前场景是否被标记为 dirty。
- `m_sceneDocumentDirtyTrackingEnabled`
是否允许实体编辑自动把场景标记为 dirty。
## 主要职责分组
### 1. 实体树编辑
- [CreateEntity](CreateEntity.md)
- [DeleteEntity](DeleteEntity.md)
- [RenameEntity](RenameEntity.md)
- [CopyEntity](CopyEntity.md)
- [PasteEntity](PasteEntity.md)
- [DuplicateEntity](DuplicateEntity.md)
- [MoveEntity](MoveEntity.md)
这些接口会直接改动当前 `Scene`,并在需要时:
- `SyncRootEntities()`
- `MarkSceneDirty()`
- 发布实体和场景变化事件
### 2. 场景文件生命周期
- [NewScene](NewScene.md)
- [LoadScene](LoadScene.md)
- [SaveScene](SaveScene.md)
- [SaveSceneAs](SaveSceneAs.md)
- [LoadStartupScene](LoadStartupScene.md)
- [CreateDemoScene](CreateDemoScene.md)
当前 `SceneManager` 既负责把 `.xc` 文件装进内存,也负责在项目首次启动或默认场景缺失时创建最小可用场景。
### 3. 快照与 play mode 恢复
- [CaptureSceneSnapshot](CaptureSceneSnapshot.md)
- [RestoreSceneSnapshot](RestoreSceneSnapshot.md)
这组接口是当前 play mode “进入前保存编辑态 / 退出后恢复编辑态”的底层基础。
### 4. 状态查询与访问器
- [GetEntity](GetEntity.md)
- [GetRootEntities](GetRootEntities.md)
- [HasActiveScene](HasActiveScene.md)
- [IsSceneDirty](IsSceneDirty.md)
- [SetSceneDocumentDirtyTrackingEnabled](SetSceneDocumentDirtyTrackingEnabled.md)
- [IsSceneDocumentDirtyTrackingEnabled](IsSceneDocumentDirtyTrackingEnabled.md)
- [GetCurrentScenePath](GetCurrentScenePath.md)
- [GetCurrentSceneName](GetCurrentSceneName.md)
- [GetScene](GetScene.md)
- [HasClipboardData](HasClipboardData.md)
这组接口主要暴露当前活动场景、root 缓存、脏状态和进程内剪贴板状态,供面板、命令层和 play mode 管理器读取。
## 当前事件语义
`SceneManager` 同时维护两套通知出口:
- 本地 `Core::Event`
- `OnEntityCreated`
- `OnEntityDeleted`
- `OnEntityChanged`
- `OnSceneChanged`
- `EventBus`
- `EntityCreatedEvent`
- `EntityDeletedEvent`
- `EntityChangedEvent`
- `EntityParentChangedEvent`
- `SceneChangedEvent`
当前实现里,这些通知都是同步触发,不做延迟队列。
## 当前实现边界
- 事件通知是同步的
- 复制粘贴依赖 `ComponentFactoryRegistry` 和组件自己的 `Serialize/Deserialize`
- 当前没有更高级的 prefab、variant 或 scene diff 机制
- `HasClipboardData()` 和 clipboard 生命周期都只在当前进程内有效
- 当前复制粘贴依赖 `ComponentFactoryRegistry` 和组件自己的 `Serialize/Deserialize`,不是 prefab 系统
- 剪贴板只在当前 Editor 进程内有效,关闭进程后不会保留
- `MarkSceneDirty()` 会受 `m_sceneDocumentDirtyTrackingEnabled` 门控
- 场景反序列化当前包在 `ResourceManager::ScopedDeferredSceneLoad` 范围内,避免场景加载期间立刻把所有资源同步兑现
## 公开方法
| 方法 | 说明 |
|------|------|
| [Constructor](Constructor.md) | 绑定可选 `EventBus` 的场景管理器构造函数。 |
| [CreateEntity](CreateEntity.md) | 在当前场景里创建实体,并在必要时隐式创建编辑器场景。 |
| [DeleteEntity](DeleteEntity.md) | 递归删除实体及其全部子节点。 |
| [RenameEntity](RenameEntity.md) | 修改实体显示名并触发实体变更通知。 |
| [CopyEntity](CopyEntity.md) | 把实体子树序列化到进程内剪贴板。 |
| [PasteEntity](PasteEntity.md) | 从进程内剪贴板重建一棵实体子树。 |
| [DuplicateEntity](DuplicateEntity.md) | 通过 copy + paste 复制一个实体子树。 |
| [MoveEntity](MoveEntity.md) | 修改实体父级并同步层级与事件。 |
| [NewScene](NewScene.md) | 创建一个新的空编辑态场景。 |
| [LoadScene](LoadScene.md) | 从磁盘加载场景文件。 |
| [SaveScene](SaveScene.md) | 保存到当前场景路径。 |
| [SaveSceneAs](SaveSceneAs.md) | 保存到新的目标路径。 |
| [LoadStartupScene](LoadStartupScene.md) | 解析项目启动场景并在必要时回退创建 demo scene。 |
| [MarkSceneDirty](MarkSceneDirty.md) | 在 dirty tracking 开启时把场景标记为 dirty。 |
| [CaptureSceneSnapshot](CaptureSceneSnapshot.md) | 抓取当前场景、路径和脏状态快照。 |
| [RestoreSceneSnapshot](RestoreSceneSnapshot.md) | 从快照恢复编辑态场景。 |
| [CreateDemoScene](CreateDemoScene.md) | 创建当前内置的最小示例场景。 |
| [GetEntity](GetEntity.md) | 通过实体 ID 查找当前场景对象。 |
| [GetRootEntities](GetRootEntities.md) | 返回 root game object 缓存。 |
| [HasActiveScene](HasActiveScene.md) | 判断当前是否存在活动场景。 |
| [IsSceneDirty](IsSceneDirty.md) | 判断当前场景是否被标记为 dirty。 |
| [SetSceneDocumentDirtyTrackingEnabled](SetSceneDocumentDirtyTrackingEnabled.md) | 开启或关闭自动 dirty tracking。 |
| [IsSceneDocumentDirtyTrackingEnabled](IsSceneDocumentDirtyTrackingEnabled.md) | 查询 dirty tracking 开关状态。 |
| [GetCurrentScenePath](GetCurrentScenePath.md) | 返回当前场景路径。 |
| [GetCurrentSceneName](GetCurrentSceneName.md) | 返回当前场景名。 |
| [GetScene](GetScene.md) | 返回当前活动 `Scene` 指针。 |
| [HasClipboardData](HasClipboardData.md) | 判断进程内实体剪贴板是否有内容。 |
## 相关文档
- [Managers](../Managers.md)
- [ISceneManager](../../Core/ISceneManager/ISceneManager.md)
- [UndoManager](../../Core/UndoManager/UndoManager.md)
- [PlaySessionController](../../Core/PlaySessionController/PlaySessionController.md)
- [SceneSnapshot](../../Core/SceneSnapshot/SceneSnapshot.md)
- [Scene](../../../Scene/Scene.md)

View File

@@ -0,0 +1,30 @@
# SceneManager::SetSceneDocumentDirtyTrackingEnabled
**命名空间**: `XCEngine::Editor`
**类型**: `method`
**源文件**: `editor/src/Managers/SceneManager.h`
## 签名
```cpp
void SetSceneDocumentDirtyTrackingEnabled(bool enabled) override;
```
## 作用
开启或关闭“场景编辑自动标记 dirty”的门控开关。
## 当前实现行为
- 这是头文件内联 setter直接把 `enabled` 写入 `m_sceneDocumentDirtyTrackingEnabled`
- 它不会立即改写 `m_isSceneDirty` 当前值。
- 当前主要用途是让 play mode 等流程临时关闭编辑文档 dirty tracking避免运行态修改把编辑态场景误标脏。
## 相关文档
- [SceneManager](SceneManager.md)
- [IsSceneDocumentDirtyTrackingEnabled](IsSceneDocumentDirtyTrackingEnabled.md)
- [MarkSceneDirty](MarkSceneDirty.md)
- [PlaySessionController](../../Core/PlaySessionController/PlaySessionController.md)