Files
XCEngine/docs/used/UI-Editor-GameObject缺口分析.md
ssdfasd 16e2065c6c Unified logging: Replace LogSystem with EditorConsoleSink
- Created EditorConsoleSink (implements ILogSink interface)
- EditorConsoleSink stores logs in memory buffer (max 1000 entries)
- Added to Debug::Logger in Application::Initialize()
- ConsolePanel now reads from EditorConsoleSink via static GetInstance()
- Removed separate LogSystem singleton
- Removed editor/src/Core/LogEntry.h (no longer needed)

Now Editor and Engine share the same Debug::Logger, with ConsolePanel
displaying logs via EditorConsoleSink.
2026-03-25 16:13:02 +08:00

551 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# UI-Editor GameObject 缺口分析
> **基于**XCEngine渲染引擎架构设计.md
> **目标**:识别 UI 编辑器 GameObject.h 相对于 Engine 架构设计文档的缺失功能
> **日期**2026-03-20
---
## 架构参考
XCEngine 组件系统参考 **Unity 传统架构 (GameObject-Component Pattern)**
- **GameObject**场景中的实体UI Editor 中称 `Entity`
- **Component**:挂载到 GameObject 的功能模块(变换、渲染器等)
- **TransformComponent**:每个 GameObject 都有的变换组件,管理位置/旋转/缩放
- **Scene/SceneManager**:场景管理和场景切换
---
## Engine 模块现状
| 模块 | 状态 | UI Editor 对齐情况 |
|-----|------|------------------|
| Core (Event, Types) | ✅ 已实现 | UI 编辑器已复用 `XCEngine::Core::Event<T>` |
| Debug (Logger, LogLevel, LogEntry) | ✅ 已实现 | UI 编辑器已复用 `XCEngine::Debug::LogLevel` |
| **Math (Vector3, Quaternion, Matrix4x4, Transform, Color)** | ✅ **已实现** | **可直接复用 Engine Math 类型** |
| Memory | ✅ 已实现 | |
| Threading | ✅ 已实现 | |
| Containers | ✅ 已实现 | |
| RHI / D3D12 | ✅ 已实现 | UI 编辑器自行实现(与 Engine 技术栈一致) |
| Resources | ✅ 已实现 | |
| **Components (GameObject, Component, System)** | ❌ **缺失** | UI 编辑器自行实现,待 Engine 实现后迁移 |
| **Scene (Scene, SceneManager, SceneLoader, SceneSerializer)** | ❌ **缺失** | UI 编辑器自行实现,待 Engine 实现后迁移 |
---
## 一、Component 基类缺口
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `transform()` | `TransformComponent& transform() const` | ❌ 缺失 | 返回所在实体的 TransformComponent 引用 |
| `GetScene()` | `Scene* GetScene() const` | ❌ 缺失 | 返回所属 Scene 指针 |
| `FixedUpdate()` | `virtual void FixedUpdate()` | ❌ 缺失 | 物理更新(每固定帧) |
| `LateUpdate()` | `virtual void LateUpdate(float deltaTime)` | ❌ 缺失 | 晚于 Update 执行 |
| `OnEnable()` | `virtual void OnEnable()` | ❌ 缺失 | 组件启用时调用 |
| `OnDisable()` | `virtual void OnDisable()` | ❌ 缺失 | 组件禁用时调用 |
| `friend class` | `friend class GameObject` | ⚠️ 差异 | UI Editor 是 `friend class Entity` |
**补充说明**
- UI Editor 的 `Component` 需要增加 `TransformComponent*` 获取方法以支持 Inspector 面板的变换编辑
- Engine 的 `m_gameObject` 在 UI Editor 中对应 `m_entity`
---
## 二、TransformComponent 缺口
### 2.1 World 空间方法
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `GetPosition()` | `XCEngine::Math::Vector3 GetPosition() const` | ❌ 缺失 | 获取世界坐标 |
| `SetPosition()` | `void SetPosition(const XCEngine::Math::Vector3& position)` | ❌ 缺失 | 设置世界坐标 |
| `GetRotation()` | `XCEngine::Math::Quaternion GetRotation() const` | ❌ 缺失 | 获取世界旋转 |
| `SetRotation()` | `void SetRotation(const XCEngine::Math::Quaternion& rotation)` | ❌ 缺失 | 设置世界旋转 |
| `GetScale()` | `XCEngine::Math::Vector3 GetScale() const` | ❌ 缺失 | 获取世界缩放 |
| `SetScale()` | `void SetScale(const XCEngine::Math::Vector3& scale)` | ❌ 缺失 | 设置世界缩放 |
### 2.2 方向向量
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `GetForward()` | `XCEngine::Math::Vector3 GetForward() const` | ❌ 缺失 | 获取前向向量 |
| `GetRight()` | `XCEngine::Math::Vector3 GetRight() const` | ❌ 缺失 | 获取右向量 |
| `GetUp()` | `XCEngine::Math::Vector3 GetUp() const` | ❌ 缺失 | 获取上向量 |
### 2.3 矩阵变换
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `GetLocalToWorldMatrix()` | `const XCEngine::Math::Matrix4x4& GetLocalToWorldMatrix() const` | ❌ 缺失 | 本地到世界矩阵(含缓存) |
| `GetWorldToLocalMatrix()` | `XCEngine::Math::Matrix4x4 GetWorldToLocalMatrix() const` | ❌ 缺失 | 世界到本地矩阵 |
### 2.4 父子层级
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `GetParent()` | `TransformComponent* GetParent() const` | ❌ 缺失 | 获取父变换 |
| `SetParent()` | `void SetParent(TransformComponent* parent, bool worldPositionStays = true)` | ❌ 缺失 | 设置父变换 |
| `GetChild()` | `TransformComponent* GetChild(int index) const` | ❌ 缺失 | 按索引获取子变换 |
| `Find()` | `TransformComponent* Find(const String& name) const` | ❌ 缺失 | 按名称查找子变换 |
| `DetachChildren()` | `void DetachChildren()` | ❌ 缺失 | 断开所有子节点 |
| `SetAsFirstSibling()` | `void SetAsFirstSibling()` | ❌ 缺失 | 设为第一个同级 |
| `SetAsLastSibling()` | `void SetAsLastSibling()` | ❌ 缺失 | 设为最后一个同级 |
| `GetSiblingIndex()` | `int GetSiblingIndex() const` | ❌ 缺失 | 获取同级索引 |
| `SetSiblingIndex()` | `void SetSiblingIndex(int index)` | ❌ 缺失 | 设置同级索引 |
### 2.5 变换操作
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `LookAt(target)` | `void LookAt(const XCEngine::Math::Vector3& target)` | ❌ 缺失 | 朝向目标点 |
| `LookAt(target, up)` | `void LookAt(const XCEngine::Math::Vector3& target, const XCEngine::Math::Vector3& up)` | ❌ 缺失 | 朝向目标点(指定上向量) |
| `Rotate(eulers)` | `void Rotate(const XCEngine::Math::Vector3& eulers)` | ❌ 缺失 | 欧拉角旋转 |
| `Rotate(axis, angle)` | `void Rotate(const XCEngine::Math::Vector3& axis, float angle)` | ❌ 缺失 | 轴角旋转 |
| `Translate(translation)` | `void Translate(const XCEngine::Math::Vector3& translation)` | ❌ 缺失 | 平移(世界空间) |
| `Translate(translation, relativeTo)` | `void Translate(const XCEngine::Math::Vector3& translation, Space relativeTo)` | ❌ 缺失 | 平移(指定空间) |
### 2.6 点/方向变换
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `TransformPoint()` | `XCEngine::Math::Vector3 TransformPoint(const XCEngine::Math::Vector3& point) const` | ❌ 缺失 | 变换点(含平移旋转) |
| `InverseTransformPoint()` | `XCEngine::Math::Vector3 InverseTransformPoint(const XCEngine::Math::Vector3& point) const` | ❌ 缺失 | 逆变换点 |
| `TransformDirection()` | `XCEngine::Math::Vector3 TransformDirection(const XCEngine::Math::Vector3& direction) const` | ❌ 缺失 | 变换方向(仅旋转) |
| `InverseTransformDirection()` | `XCEngine::Math::Vector3 InverseTransformDirection(const XCEngine::Math::Vector3& direction) const` | ❌ 缺失 | 逆变换方向 |
### 2.7 脏标记与缓存
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `SetDirty()` | `void SetDirty()` | ⚠️ 局部 | UI Editor 只有简单 flag缺少完整缓存机制 |
| 缓存成员 | `mutable XCEngine::Math::Matrix4x4 m_localToWorldMatrix` 等 | ❌ 缺失 | 矩阵缓存 |
| 更新方法 | `void UpdateWorldTransform() const` | ❌ 缺失 | 缓存失效时重新计算 |
**当前 UI Editor 实现**
```cpp
class TransformComponent : public Component {
public:
float position[3] = {0.0f, 0.0f, 0.0f}; // 仅有本地坐标
float rotation[3] = {0.0f, 0.0f, 0.0f}; // 欧拉角
float scale[3] = {1.0f, 1.0f, 1.0f}; // 仅有本地缩放
// 缺少世界空间方法、矩阵缓存、父子指针等
};
```
**架构设计要求**(应使用 Engine Math 类型):
```cpp
class TransformComponent : public Component {
public:
// 使用 Engine Math 类型
XCEngine::Math::Vector3 GetLocalPosition() const { return m_localPosition; }
void SetLocalPosition(const XCEngine::Math::Vector3& pos) { m_localPosition = pos; SetDirty(); }
XCEngine::Math::Quaternion GetLocalRotation() const { return m_localRotation; }
void SetLocalRotation(const XCEngine::Math::Quaternion& rot) { m_localRotation = rot; SetDirty(); }
XCEngine::Math::Vector3 GetLocalScale() const { return m_localScale; }
void SetLocalScale(const XCEngine::Math::Vector3& sc) { m_localScale = sc; SetDirty(); }
private:
XCEngine::Math::Vector3 m_localPosition = XCEngine::Math::Vector3::Zero();
XCEngine::Math::Quaternion m_localRotation = XCEngine::Math::Quaternion::Identity();
XCEngine::Math::Vector3 m_localScale = XCEngine::Math::Vector3::One();
TransformComponent* m_parent = nullptr;
std::vector<TransformComponent*> m_children;
mutable XCEngine::Math::Matrix4x4 m_localToWorldMatrix;
mutable XCEngine::Math::Matrix4x4 m_worldToLocalMatrix;
mutable XCEngine::Math::Vector3 m_worldPosition;
mutable XCEngine::Math::Quaternion m_worldRotation;
mutable XCEngine::Math::Vector3 m_worldScale;
mutable bool m_dirty = true;
void UpdateWorldTransform() const;
};
```
---
## 三、GameObject缺口
### 3.1 基础方法
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `GetTransform()` | `TransformComponent& GetTransform()` | ❌ 缺失 | 获取变换组件引用 |
| `GetScene()` | `Scene* GetScene() const` | ❌ 缺失 | 获取所属场景 |
### 3.2 组件查找
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `GetComponentInChildren<T>()` | `T* GetComponentInChildren() const` | ❌ 缺失 | 在子实体中查找组件 |
| `GetComponentsInChildren<T>()` | `std::vector<T*> GetComponentsInChildren() const` | ❌ 缺失 | 获取所有子实体中的组件 |
| `GetComponentInParent<T>()` | `T* GetComponentInParent() const` | ❌ 缺失 | 在父实体中查找组件 |
### 3.3 父子层级
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `SetParent(parent)` | `void SetParent(Entity* parent)` | ❌ 缺失 | 2参数版本含 worldPositionStays |
| `GetChildren()` | `const std::vector<Entity*>& GetChildren() const` | ❌ 缺失 | 获取子实体列表 |
| `GetChild()` | `Entity* GetChild(int index) const` | ❌ 缺失 | 按索引获取子实体 |
### 3.4 激活状态
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `active` 成员 | `bool active = true` | ❌ 缺失 | 实体激活状态 |
| `SetActive()` | `void SetActive(bool active)` | ❌ 缺失 | 设置激活状态 |
| `IsActive()` | `bool IsActive() const` | ❌ 缺失 | 检查激活状态 |
| `IsActiveInHierarchy()` | `bool IsActiveInHierarchy() const` | ❌ 缺失 | 检查层级中的激活状态 |
### 3.5 静态查找
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `Find()` | `static Entity* Find(const String& name)` | ❌ 缺失 | 按名称查找实体 |
| `FindObjectsOfType()` | `static std::vector<Entity*> FindObjectsOfType()` | ❌ 缺失 | 查找所有实体 |
| `FindGameObjectsWithTag()` | `static std::vector<Entity*> FindGameObjectsWithTag(const String& tag)` | ❌ 缺失 | 按标签查找 |
### 3.6 销毁
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `Destroy()` | `void Destroy()` | ❌ 缺失 | 实例方法销毁(通过 Scene |
---
## 四、Scene / SceneManager 缺口
### 4.1 Scene 类
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `GetName()` | `const String& GetName() const` | ❌ 缺失 | 获取场景名称 |
| `SetName()` | `void SetName(const String& name)` | ❌ 缺失 | 设置场景名称 |
| `CreateGameObject(name, parent)` | `Entity* CreateGameObject(const String& name, Entity* parent)` | ❌ 缺失 | 带父实体创建 |
| `GetRootGameObjects()` | `std::vector<Entity*> GetRootGameObjects() const` | ❌ 缺失 | 获取根实体列表 |
| `Find()` | `Entity* Find(const String& name) const` | ❌ 缺失 | 查找实体 |
| `FindGameObjectWithTag()` | `Entity* FindGameObjectWithTag(const String& tag) const` | ❌ 缺失 | 按标签查找 |
| `FindObjectsOfType<T>()` | `std::vector<T*> FindObjectsOfType() const` | ❌ 缺失 | 模板查找 |
| `FindObjectOfType<T>()` | `T* FindObjectOfType() const` | ❌ 缺失 | 查找单个 |
| `IsActive()` | `bool IsActive() const` | ❌ 缺失 | 场景激活状态 |
| `SetActive()` | `void SetActive(bool active)` | ❌ 缺失 | 设置激活状态 |
| `Load()` | `void Load(const String& filePath)` | ❌ 缺失 | 加载场景 |
| `Save()` | `void Save(const String& filePath)` | ❌ 缺失 | 保存场景 |
| `Update()` | `void Update(float deltaTime)` | ❌ 缺失 | 场景更新 |
| `FixedUpdate()` | `void FixedUpdate(float fixedDeltaTime)` | ❌ 缺失 | 物理更新 |
| `LateUpdate()` | `void LateUpdate(float deltaTime)` | ❌ 缺失 | 晚更新 |
**当前 UI Editor 缺失 Scene 概念**,所有实体都在 SceneManager 全局管理。
### 4.2 SceneManager 类
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| `CreateScene()` | `Scene* CreateScene(const String& name)` | ❌ 缺失 | 创建场景 |
| `LoadScene()` | `void LoadScene(const String& filePath)` | ❌ 缺失 | 同步加载 |
| `LoadSceneAsync()` | `void LoadSceneAsync(const String& filePath, std::function<void(Scene*)> callback)` | ❌ 缺失 | 异步加载 |
| `UnloadScene(scene)` | `void UnloadScene(Scene* scene)` | ❌ 缺失 | 卸载场景 |
| `UnloadScene(name)` | `void UnloadScene(const String& sceneName)` | ❌ 缺失 | 按名称卸载 |
| `SetActiveScene(scene)` | `void SetActiveScene(Scene* scene)` | ❌ 缺失 | 设置激活场景 |
| `SetActiveScene(name)` | `void SetActiveScene(const String& sceneName)` | ❌ 缺失 | 按名称设置 |
| `GetActiveScene()` | `Scene* GetActiveScene() const` | ❌ 缺失 | 获取激活场景 |
| `GetScene(name)` | `Scene* GetScene(const String& name) const` | ❌ 缺失 | 按名称获取场景 |
| `GetAllScenes()` | `std::vector<Scene*> GetAllScenes() const` | ❌ 缺失 | 获取所有场景 |
| `OnSceneLoaded` | `Event<Scene*>` | ⚠️ 差异 | UI Editor 是 `OnSceneChanged` |
| `OnSceneUnloaded` | `Event<Scene*>` | ❌ 缺失 | 场景卸载事件 |
| `OnActiveSceneChanged` | `Event<Scene*>` | ❌ 缺失 | 激活场景变更事件 |
### 4.3 GameObjectBuilder 类
| 架构设计接口 | 函数签名 | 状态 | 说明 |
|------------|---------|------|------|
| 完整类 | `class GameObjectBuilder` | ❌ 缺失 | 实体创建辅助类 |
---
## 五、实现优先级
### P0 - 核心缺失(必须实现)
| 模块 | 原因 | 涉及文件 |
|-----|------|---------|
| TransformComponent 世界空间方法 | Editor 变换编辑基础 | GameObject.h |
| Entity `GetTransform()` | Inspector 面板需要 | GameObject.h |
| Component `transform()` | 组件访问变换 | GameObject.h |
**依赖**Engine Math 模块 ✅ 已实现,可直接使用 `XCEngine::Math::Vector3` / `Quaternion` / `Matrix4x4`
### P1 - 功能完整(应该实现)
| 模块 | 原因 | 涉及文件 |
|-----|------|---------|
| TransformComponent 矩阵缓存 | 性能优化 | GameObject.h |
| TransformComponent 父子指针 | 层级操作 | GameObject.h |
| Entity 激活状态 | 运行时状态 | GameObject.h |
| Entity 父子层级操作 | 层级编辑 | GameObject.h |
| Scene 概念 | 多场景支持 | SceneManager.h |
| SceneManager 多场景管理 | 场景隔离 | SceneManager.h |
### P2 - 高级功能(可选实现)
| 模块 | 原因 | 涉及文件 |
|-----|------|---------|
| Scene 序列化/反序列化 | 持久化 | SceneManager.h |
| TransformComponent 点/方向变换 | Gizmos 操作 | GameObject.h |
| SceneManager 异步加载 | 体验优化 | SceneManager.h |
| Entity 静态查找 | Editor 操作 | GameObject.h |
---
## 六、数据结构对齐表
### 6.1 当前 UI Editor vs 架构设计
| 项目 | UI Editor 当前 | 架构设计 | 对齐建议 |
|-----|--------------|---------|---------|
| 实体内组件存储 | `vector<unique_ptr<Component>>` | `vector<unique_ptr<Component>>` | ✅ 已对齐 |
| 变换类型 | `float[3]` 数组 | `XCEngine::Math::Vector3` / `Quaternion` | ⚠️ **应改用 Engine Math** |
| 父子关系 | `EntityID` (uint64) | `Entity*` 指针 | ⚠️ UI 用 IDEngine 用指针 |
| 场景管理 | 全局单例 SceneManager | 多 Scene + SceneManager | ❌ 需要重构 |
### 6.2 命名差异
| UI Editor | Engine 架构设计 | 说明 |
|-----------|---------------|------|
| `Entity` | `GameObject` | UI Editor 使用 Entity 避免与 std 冲突 |
| `EntityID` | `uint64_t` | UI Editor 自定义类型别名 |
| `INVALID_ENTITY_ID` | N/A | UI Editor 自定义常量 |
| `ComponentRegistry` | `ComponentTypeRegistry` | 功能相似,命名不同 |
### 6.3 类型复用情况
| Engine 类型 | UI Editor 现状 | 建议 |
|-----------|--------------|------|
| `XCEngine::Math::Vector3` | UI Editor 用 `float[3]` | **直接复用** |
| `XCEngine::Math::Quaternion` | UI Editor 用 `float[3]` (欧拉角) | **直接复用**,但欧拉角存储可保留 |
| `XCEngine::Math::Matrix4x4` | 无 | **直接复用** |
| `XCEngine::Core::Event<T>` | ✅ 已复用 | 保持 |
| `XCEngine::Debug::LogLevel` | ✅ 已复用 | 保持 |
---
## 七、依赖关系分析
```
实现优先级 - 依赖链:
P0: TransformComponent 世界空间
├── 需要: XCEngine::Math::Vector3 ✅ 已实现
├── 需要: XCEngine::Math::Quaternion ✅ 已实现
├── 需要: XCEngine::Math::Matrix4x4 ✅ 已实现
└── 影响: Entity::GetTransform()
P0: Component::transform()
└── 依赖: Entity::GetTransform()
P1: TransformComponent 父子指针
├── 需要: TransformComponent* parent
├── 需要: vector<TransformComponent*> children
└── 影响: Entity 父子操作
P1: Entity 激活状态
├── 需要: active 成员
└── 影响: IsActiveInHierarchy()
P1: Scene 多场景
├── 需要: Scene 类
├── 需要: Scene::CreateGameObject()
└── 影响: SceneManager 重构
```
---
## 八、与 Unity 架构的对照
### Unity 传统架构 (GameObject-Component)
```
Scene
└── GameObject ("MyEntity")
├── Transform
├── MeshRenderer
└── (其他组件...)
GameObject.GetComponent<T>() → Entity.GetComponent<T>()
GameObject.transform → Entity.GetTransform()
GameObject.SetActive(bool) → 缺失
GameObject.Find("name") → 缺失
Scene.GetRootGameObjects() → 缺失
SceneManager.GetActiveScene() → 缺失
```
### UI Editor 当前实现
```
SceneManager (全局单例)
└── m_entities (unordered_map<EntityID, Entity>)
└── Entity ("MyEntity")
├── id, name, parent, children
├── components (vector<unique_ptr<Component>>)
└── selected
Entity.AddComponent<T>() → ✅ 已实现
Entity.GetComponent<T>() → ✅ 已实现
Entity.GetTransform() → ❌ 缺失
TransformComponent 世界空间方法 → ❌ 缺失
```
---
## 九、附录:当前 GameObject.h 完整内容
```cpp
// ui_editor/src/Core/GameObject.h 当前实现
#pragma once
#include <string>
#include <vector>
#include <memory>
#include <unordered_map>
#include <functional>
#include <cstdint>
#include <XCEngine/Core/Event.h>
namespace UI {
using EntityID = uint64_t;
constexpr EntityID INVALID_ENTITY_ID = 0;
class Component {
public:
virtual ~Component() = default;
virtual std::string GetName() const = 0;
virtual void Awake() {}
virtual void Start() {}
virtual void Update(float deltaTime) {}
virtual void OnDestroy() {}
class Entity* GetEntity() const { return m_entity; }
bool IsEnabled() const { return m_enabled; }
void SetEnabled(bool enabled) { m_enabled = enabled; }
protected:
class Entity* m_entity = nullptr;
bool m_enabled = true;
friend class Entity;
};
class TransformComponent : public Component {
public:
float position[3] = {0.0f, 0.0f, 0.0f};
float rotation[3] = {0.0f, 0.0f, 0.0f};
float scale[3] = {1.0f, 1.0f, 1.0f};
std::string GetName() const override { return "Transform"; }
};
class MeshRendererComponent : public Component {
public:
std::string materialName = "Default-Material";
std::string meshName = "";
std::string GetName() const override { return "Mesh Renderer"; }
};
class Entity {
public:
EntityID id = INVALID_ENTITY_ID;
std::string name;
EntityID parent = INVALID_ENTITY_ID;
std::vector<EntityID> children;
std::vector<std::unique_ptr<Component>> components;
bool selected = false;
template<typename T, typename... Args>
T* AddComponent(Args&&... args) {
auto comp = std::make_unique<T>(std::forward<Args>(args)...);
comp->m_entity = this;
T* ptr = comp.get();
components.push_back(std::move(comp));
return ptr;
}
template<typename T>
T* GetComponent() {
for (auto& comp : components) {
if (auto casted = dynamic_cast<T*>(comp.get())) {
return casted;
}
}
return nullptr;
}
template<typename T>
std::vector<T*> GetComponents() {
std::vector<T*> result;
for (auto& comp : components) {
if (auto casted = dynamic_cast<T*>(comp.get())) {
result.push_back(casted);
}
}
return result;
}
};
using ComponentInspectorFn = std::function<void(Component*)>;
struct ComponentInspectorInfo {
std::string name;
ComponentInspectorFn renderFn;
};
class ComponentRegistry {
public:
static ComponentRegistry& Get() {
static ComponentRegistry instance;
return instance;
}
template<typename T>
void RegisterComponent(const std::string& name, ComponentInspectorFn inspectorFn) {
m_inspectors[name] = {name, inspectorFn};
m_factories[name] = []() -> std::unique_ptr<Component> {
return std::make_unique<T>();
};
}
ComponentInspectorInfo* GetInspector(const std::string& name) {
auto it = m_inspectors.find(name);
if (it != m_inspectors.end()) {
return &it->second;
}
return nullptr;
}
private:
ComponentRegistry() = default;
std::unordered_map<std::string, ComponentInspectorInfo> m_inspectors;
std::unordered_map<std::string, std::function<std::unique_ptr<Component>()>> m_factories;
};
} // namespace UI
```
---
**文档结束**