- 新增 EntityHandle:e.AddComponent<T>() / e.GetComponent<T>() / e.Destroy() / e.GetUUID(),转发 entt registry,零存储开销 - Scene::CreateEntity 返回 EntityHandle;Scene 层组件接口保留 (给渲染器/系统批量遍历用) - 语义分层:应用层"实体管组件"(句柄表皮), 数据层组件存储仍集中在 registry(ECS 性能根基)
65 lines
1.8 KiB
C++
65 lines
1.8 KiB
C++
//
|
|
// Created by atdunbg on 2026/9/22.
|
|
//
|
|
|
|
#include <Engine/ECS/Scene.h>
|
|
#include <Engine/ECS/EntityHandle.h>
|
|
#include <Engine/Core/Log.h>
|
|
|
|
namespace Engine::ECS {
|
|
|
|
EntityHandle Scene::CreateEntity(std::string name)
|
|
{
|
|
Entity e = m_Registry.create();
|
|
// IdComponent 自动挂载:每个实体出生即有稳定 UUID
|
|
m_Registry.emplace<IdComponent>(e, IdComponent{UUID::New()});
|
|
if (!name.empty()) {
|
|
m_Registry.emplace<NameComponent>(e, NameComponent{std::move(name)});
|
|
}
|
|
return EntityHandle{this, e};
|
|
}
|
|
|
|
Entity Scene::FindEntityByUUID(UUID uuid)
|
|
{
|
|
if (!uuid.Valid()) return entt::null;
|
|
|
|
Entity found = entt::null;
|
|
m_Registry.view<IdComponent>().each([&](Entity e, IdComponent& id) {
|
|
if (found == entt::null && id.uuid == uuid) found = e;
|
|
});
|
|
return found;
|
|
}
|
|
|
|
void Scene::DestroyEntity(Entity e)
|
|
{
|
|
if (!m_Registry.valid(e)) {
|
|
ENGINE_FATAL("Scene::DestroyEntity: stale entity ({})",
|
|
static_cast<u32>(e));
|
|
}
|
|
// 延迟到帧尾,保证遍历期间池结构不变
|
|
m_PendingDestroy.push_back(e);
|
|
}
|
|
|
|
void Scene::FlushDestroyQueue()
|
|
{
|
|
if (m_PendingDestroy.empty()) return;
|
|
|
|
for (Entity e : m_PendingDestroy) {
|
|
if (m_Registry.valid(e)) {
|
|
m_Registry.destroy(e); // entt 自动回收槽位并递增版本号
|
|
}
|
|
}
|
|
m_PendingDestroy.clear();
|
|
}
|
|
|
|
CameraComponent* Scene::GetPrimaryCamera()
|
|
{
|
|
CameraComponent* found = nullptr;
|
|
m_Registry.view<CameraComponent>().each([&](Entity, CameraComponent& cc) {
|
|
if (!found && cc.primary) found = &cc;
|
|
});
|
|
return found;
|
|
}
|
|
|
|
} // namespace Engine::ECS
|