From 49f80df42ffad6e09719394c8c1fb7209e8a92e0 Mon Sep 17 00:00:00 2001 From: Ubpa <641614112@qq.com> Date: Thu, 20 Aug 2020 17:05:29 +0800 Subject: [PATCH] EntityMngr += Get...Array --- CMakeLists.txt | 2 +- include/UECS/EntityMngr.h | 10 ++++- include/UECS/detail/EntityMngr.inl | 33 ++++++++++++++++ src/core/EntityMngr.cpp | 61 ++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c1696c0..c47c1f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.14 FATAL_ERROR) -project(UECS VERSION 0.11.6) +project(UECS VERSION 0.11.7) message(STATUS "[Project] ${PROJECT_NAME}") include(cmake/InitUCMake.cmake) diff --git a/include/UECS/EntityMngr.h b/include/UECS/EntityMngr.h index 3156d75..b0d78ca 100644 --- a/include/UECS/EntityMngr.h +++ b/include/UECS/EntityMngr.h @@ -76,6 +76,12 @@ namespace Ubpa::UECS { template Cmpt* GetSingleton() const { return GetSingleton(CmptType::Of).As(); } + // filter's all contains cmpt + template + std::vector GetCmptArray(const ArchetypeFilter&) const; + std::vector GetCmptArray(const ArchetypeFilter&, CmptType) const; + std::vector GetEntityArray(const ArchetypeFilter&) const; + void Accept(IListener* listener) const; private: @@ -98,7 +104,7 @@ namespace Ubpa::UECS { Archetype* AttachWithoutInit(Entity); Archetype* AttachWithoutInit(Entity, const CmptType* types, size_t num); - const std::set& QueryArchetypes(const EntityQuery& query) const; + const std::set& QueryArchetypes(const EntityQuery&) const; mutable std::unordered_map> queryCache; void GenEntityJob(World*, Job*, SystemFunc*) const; @@ -113,7 +119,7 @@ namespace Ubpa::UECS { std::vector entityTable; std::vector entityTableFreeEntry; size_t RequestEntityFreeEntry(); - void RecycleEntityEntry(Entity e); + void RecycleEntityEntry(Entity); std::unordered_map> ts2a; // archetype's CmptTypeSet to archetype }; diff --git a/include/UECS/detail/EntityMngr.inl b/include/UECS/detail/EntityMngr.inl index 4f7d5e4..d836b44 100644 --- a/include/UECS/detail/EntityMngr.inl +++ b/include/UECS/detail/EntityMngr.inl @@ -135,4 +135,37 @@ namespace Ubpa::UECS { inline bool EntityMngr::Exist(Entity e) const { return e.Idx() < entityTable.size() && e.Version() == entityTable[e.Idx()].version; } + + template + std::vector EntityMngr::GetCmptArray(const ArchetypeFilter& filter) const { + constexpr auto type = CmptType::Of; + assert(filter.all.find(type) != filter.all.end()); + + std::vector rst; + + const auto& archetypes = QueryArchetypes(filter); + size_t num = 0; + for (const auto& archetype : archetypes) + num += archetype->EntityNum(); + + rst.resize(num); + size_t idx = 0; + for (auto archetype : archetypes) { + /*for (size_t i = 0; i < archetype->EntityNum(); i++) + rst[idx++] = archetype->At(i);*/ + + // speed up + + size_t offset = archetype->Offsetof(type); + for (size_t c = 0; c < archetype->chunks.size(); c++) { + auto buffer = archetype->chunks[c]->Data(); + auto beg = buffer + offset; + size_t chunkSize = archetype->EntityNumOfChunk(c); + for (size_t i = 0; i < chunkSize; i++) + rst[idx++] = reinterpret_cast(beg + i * sizeof(Cmpt)); + } + } + + return rst; + } } diff --git a/src/core/EntityMngr.cpp b/src/core/EntityMngr.cpp index b1317ca..79034c5 100644 --- a/src/core/EntityMngr.cpp +++ b/src/core/EntityMngr.cpp @@ -386,3 +386,64 @@ CmptPtr EntityMngr::GetSingleton(CmptType t) const { return { t, archetype->At(t, 0) }; } + +std::vector EntityMngr::GetCmptArray(const ArchetypeFilter& filter, CmptType type) const { + assert(filter.all.find(type) != filter.all.end()); + + std::vector rst; + + const auto& archetypes = QueryArchetypes(filter); + + size_t num = 0; + for (const auto& archetype : archetypes) + num += archetype->EntityNum(); + + rst.reserve(num); + for (auto archetype : archetypes) { + /*for (size_t i = 0; i < archetype->EntityNum(); i++) + rst[idx++] = *archetype->At(type, i);*/ + + // speed up + + size_t size = archetype->cmptTraits.Sizeof(type); + size_t offset = archetype->Offsetof(type); + for (size_t c = 0; c < archetype->chunks.size(); c++) { + auto buffer = archetype->chunks[c]->Data(); + auto beg = buffer + offset; + size_t chunkSize = archetype->EntityNumOfChunk(c); + for (size_t i = 0; i < chunkSize; i++) + rst.emplace_back(type, beg + i * size); + } + } + + return rst; +} + +std::vector EntityMngr::GetEntityArray(const ArchetypeFilter& filter) const { + std::vector rst; + + const auto& archetypes = QueryArchetypes(filter); + + size_t num = 0; + for (const auto& archetype : archetypes) + num += archetype->EntityNum(); + + rst.reserve(num); + for (auto archetype : archetypes) { + /*for (size_t i = 0; i < archetype->EntityNum(); i++) + rst[idx++] = *archetype->At(i);*/ + + // speed up + + size_t offset = archetype->Offsetof(CmptType::Of); + for (size_t c = 0; c < archetype->chunks.size(); c++) { + auto buffer = archetype->chunks[c]->Data(); + auto beg = buffer + offset; + size_t chunkSize = archetype->EntityNumOfChunk(c); + for (size_t i = 0; i < chunkSize; i++) + rst.push_back(*reinterpret_cast(beg + i * sizeof(Entity))); + } + } + + return rst; +}