diff --git a/doc/changelog.md b/doc/changelog.md index b7024e2..2563c39 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -4,6 +4,7 @@ - remove none-parallel - support change filter - multiple sysc points (layer) + - world resource - 0.15.1 - support MacOS GCC 10.2 - 0.15.0 diff --git a/include/UECS/CmptTraits.hpp b/include/UECS/CmptTraits.hpp index 564933b..c1dbd32 100644 --- a/include/UECS/CmptTraits.hpp +++ b/include/UECS/CmptTraits.hpp @@ -9,6 +9,8 @@ #include namespace Ubpa::UECS { + class EntityMngr; + // run-time dynamic component traits // size (> 0) is neccessary // optional @@ -23,20 +25,14 @@ namespace Ubpa::UECS { public: static constexpr std::size_t default_alignment = alignof(std::max_align_t); - CmptTraits(); - CmptTraits(const CmptTraits& other); - CmptTraits(CmptTraits&& other) noexcept = default; - CmptTraits& operator=(const CmptTraits & other); - CmptTraits& operator=(CmptTraits&& other) noexcept = default; - CmptTraits& Clear(); CmptTraits& RegisterName(Type); CmptTraits& RegisterTrivial(TypeID); CmptTraits& RegisterSize(TypeID, std::size_t size); CmptTraits& RegisterAlignment(TypeID, std::size_t alignment); - CmptTraits& RegisterDefaultConstructor(TypeID, std::function); - CmptTraits& RegisterCopyConstructor(TypeID, std::function); + CmptTraits& RegisterDefaultConstructor(TypeID, std::function); + CmptTraits& RegisterCopyConstructor(TypeID, std::function); CmptTraits& RegisterMoveConstructor(TypeID, std::function); CmptTraits& RegisterMoveAssignment(TypeID, std::function); CmptTraits& RegisterDestructor(TypeID, std::function); @@ -54,7 +50,7 @@ namespace Ubpa::UECS { std::size_t Sizeof(TypeID) const; std::size_t Alignof(TypeID) const; void DefaultConstruct(TypeID, void* cmpt) const; - void CopyConstruct(TypeID, void* dst, void* src) const; + void CopyConstruct(TypeID, void* dst, const void* src) const; void MoveConstruct(TypeID, void* dst, void* src) const; void MoveAssign(TypeID, void* dst, void* src) const; void Destruct(TypeID, void* cmpt) const; @@ -72,6 +68,11 @@ namespace Ubpa::UECS { void Deregister(); private: + friend class EntityMngr; + CmptTraits(std::pmr::memory_resource* world_rsrc); + CmptTraits(const CmptTraits& other, std::pmr::memory_resource* world_rsrc); + CmptTraits(CmptTraits&& other) noexcept; + // register all for Cmpt // static_assert // - is_default_constructible_v @@ -90,11 +91,13 @@ namespace Ubpa::UECS { std::unordered_map names; std::unordered_map sizeofs; std::unordered_map alignments; - std::unordered_map> default_constructors; // dst <- src - std::unordered_map> copy_constructors; // dst <- src - std::unordered_map> move_constructors; // dst <- src - std::unordered_map> move_assignments; // dst <- src + std::unordered_map> default_constructors; // dst <- src + std::unordered_map> copy_constructors; // dst <- src + std::unordered_map> move_constructors; // dst <- src + std::unordered_map> move_assignments; // dst <- src std::unordered_map> destructors; + + std::pmr::memory_resource* world_rsrc; }; } diff --git a/include/UECS/EntityMngr.hpp b/include/UECS/EntityMngr.hpp index d80d3f8..9357603 100644 --- a/include/UECS/EntityMngr.hpp +++ b/include/UECS/EntityMngr.hpp @@ -30,11 +30,6 @@ namespace Ubpa::UECS { // - when free entries is empty, use new entity entry (version is 0) class EntityMngr { public: - EntityMngr(); - EntityMngr(const EntityMngr& em); - EntityMngr(EntityMngr&&) noexcept; - ~EntityMngr(); - CmptTraits cmptTraits; Entity Create(std::span types = {}); @@ -87,6 +82,11 @@ namespace Ubpa::UECS { void Clear(); private: + EntityMngr(std::pmr::memory_resource* world_rsrc); + EntityMngr(const EntityMngr& em, std::pmr::memory_resource* world_rsrc); + EntityMngr(EntityMngr&&) noexcept; + ~EntityMngr(); + friend class World; friend class Archetype; @@ -110,6 +110,7 @@ namespace Ubpa::UECS { bool AutoGen(World*, Job*, SystemFunc*, int layer) const; std::uint64_t version{ 0 }; + std::pmr::memory_resource* world_rsrc; struct EntityInfo { Archetype* archetype{ nullptr }; diff --git a/include/UECS/Schedule.hpp b/include/UECS/Schedule.hpp index 9987df6..2ae92f2 100644 --- a/include/UECS/Schedule.hpp +++ b/include/UECS/Schedule.hpp @@ -124,6 +124,9 @@ namespace Ubpa::UECS { T* CreateFrameObject(Args&&... args) const; std::string_view RegisterFrameString(std::string_view str); + + Schedule& operator=(Schedule&&) noexcept = delete; + Schedule& operator=(const Schedule&) = delete; private: Schedule(); Schedule(const Schedule&); diff --git a/include/UECS/World.hpp b/include/UECS/World.hpp index 1405325..46598d8 100644 --- a/include/UECS/World.hpp +++ b/include/UECS/World.hpp @@ -15,6 +15,8 @@ namespace Ubpa::UECS { // SystemMngr + EntityMngr class World { + std::unique_ptr world_rsrc; // init before entityMngr + public: World(); World(const World&); @@ -24,10 +26,10 @@ namespace Ubpa::UECS { SystemMngr systemMngr; EntityMngr entityMngr; - // 1. schedule: run registered System's static OnUpdate(Schedule&) - // 2. gen job graph: schedule -> graph - // 3. run job graph in worker threads - // 4. run commands in main thread + // 1. update schedule + // 2. run job graph for several layers + // 3. update version + // 4. clear frame resource void Update(); void AddCommand(std::function command, int layer); @@ -116,6 +118,8 @@ namespace Ubpa::UECS { template T* SyncCreateFrameObject(Args&&... args); + std::pmr::synchronized_pool_resource* GetSyncResource() { return world_rsrc.get(); } + std::uint64_t Version() const noexcept { return version; } private: bool inRunningJobGraph{ false }; @@ -126,7 +130,7 @@ namespace Ubpa::UECS { Job jobGraph; std::vector jobs; - std::unique_ptr jobRsrc; + std::unique_ptr jobRsrc; // command std::map lcommandBuffer; diff --git a/include/UECS/details/CmptTraits.inl b/include/UECS/details/CmptTraits.inl index 36ae6a2..d96df85 100644 --- a/include/UECS/details/CmptTraits.inl +++ b/include/UECS/details/CmptTraits.inl @@ -2,6 +2,24 @@ #include "../CmptTraits.hpp" +namespace Ubpa::UECS::details { + template + concept ContainPmrAlloc = requires() { + typename T::allocator_type; + std::is_constructible_v; + }; + + template + concept DefaultCtorWithAlloc = ContainPmrAlloc && requires(const typename T::allocator_type & alloc) { + new T(alloc); + }; + + template + concept CopyCtorWithAlloc = ContainPmrAlloc && + (requires(const T & other, const typename T::allocator_type & alloc) { new T(other, alloc); } + || requires(const T & other, const typename T::allocator_type & alloc) { new T(std::allocator_arg_t{}, alloc, other); }); +} + namespace Ubpa::UECS { template void CmptTraits::Register() { @@ -23,9 +41,16 @@ namespace Ubpa::UECS { alignments.emplace(type.GetID(), alignof(Cmpt)); names.emplace(type.GetID(), type.GetName()); - if constexpr (std::is_default_constructible_v) { - default_constructors.emplace(type.GetID(), [](void* cmpt) { - new(cmpt)Cmpt{}; + if constexpr (details::DefaultCtorWithAlloc) { + default_constructors.emplace(type.GetID(), [](void* cmpt, std::pmr::memory_resource* world_rsrc) { + using Alloc = typename Cmpt::allocator_type; + Alloc alloc(world_rsrc); + std::allocator_traits::template construct(alloc, reinterpret_cast(cmpt)); + }); + } + else if constexpr (std::is_default_constructible_v) { + default_constructors.emplace(type.GetID(), [](void* cmpt, std::pmr::memory_resource*) { + new(cmpt)Cmpt(); }); } @@ -46,9 +71,17 @@ namespace Ubpa::UECS { *static_cast(dst) = std::move(*static_cast(src)); }); } - if constexpr (std::is_copy_constructible_v && !std::is_trivially_copy_constructible_v) { - copy_constructors.emplace(type.GetID(), [](void* dst, void* src) { - new(dst)Cmpt(*static_cast(src)); + + if constexpr (details::CopyCtorWithAlloc) { + copy_constructors.emplace(type.GetID(), [](void* dst, const void* src, std::pmr::memory_resource* world_rsrc) { + using Alloc = typename Cmpt::allocator_type; + Alloc alloc(world_rsrc); + std::allocator_traits::template construct(alloc, reinterpret_cast(dst), *static_cast(src)); + }); + } + else if constexpr (std::is_copy_constructible_v && !std::is_trivially_copy_constructible_v) { + copy_constructors.emplace(type.GetID(), [](void* dst, const void* src, std::pmr::memory_resource*) { + new(dst)Cmpt(*static_cast(src)); }); } } @@ -56,8 +89,8 @@ namespace Ubpa::UECS { template void CmptTraits::RegisterOne() { static_assert(!IsTaggedCmpt_v, " should not be tagged"); - static_assert(std::is_default_constructible_v, " must be default-constructible"); - static_assert(std::is_copy_constructible_v, " must be copy-constructible"); + static_assert(std::is_default_constructible_v || details::DefaultCtorWithAlloc, " must be default-constructible or with alloc"); + static_assert(std::is_copy_constructible_v || details::CopyCtorWithAlloc, " must be copy-constructible or with alloc"); static_assert(std::is_move_constructible_v, " must be move-constructible"); static_assert(std::is_move_assignable_v, " must be move-assignable"); static_assert(std::is_destructible_v, " must be destructible"); diff --git a/src/core/Archetype.cpp b/src/core/Archetype.cpp index c028bbe..afa6ee8 100644 --- a/src/core/Archetype.cpp +++ b/src/core/Archetype.cpp @@ -3,6 +3,11 @@ using namespace Ubpa::UECS; using namespace std; +Archetype::Archetype(std::pmr::memory_resource* rsrc, std::pmr::memory_resource* world_rsrc, std::uint64_t version) noexcept : + chunkAllocator{ rsrc }, + version{ version }, + world_rsrc{ world_rsrc }{} + Archetype::~Archetype() { if (cmptTraits.IsTrivial()) return; @@ -26,8 +31,9 @@ Archetype::~Archetype() { // entityMngr->sharedChunkPool.Recycle(chunk); } -Archetype::Archetype(std::pmr::memory_resource* rsrc, const Archetype& src) - : chunkAllocator{ rsrc } +Archetype::Archetype(std::pmr::memory_resource* rsrc, std::pmr::memory_resource* world_rsrc, const Archetype& src) : + chunkAllocator{ rsrc }, + world_rsrc{ world_rsrc } { cmptTraits = src.cmptTraits; entityNum = src.entityNum; @@ -61,7 +67,7 @@ Archetype::Archetype(std::pmr::memory_resource* rsrc, const Archetype& src) if (trait.copy_ctor) { for (std::size_t j = 0; j < num; j++) { auto offset_j = j * trait.size; - trait.copy_ctor(dstBegin + offset_j, srcBegin + offset_j); + trait.copy_ctor(dstBegin + offset_j, srcBegin + offset_j, world_rsrc); } } else @@ -83,7 +89,7 @@ Archetype::Archetype(std::pmr::memory_resource* rsrc, const Archetype& src) auto* cursor_dst = dstChunk->data + offsets[j]; if (trait.copy_ctor) { for (std::size_t k = 0; k < num; k++) { - trait.copy_ctor(cursor_dst, cursor_src); + trait.copy_ctor(cursor_dst, cursor_src, world_rsrc); cursor_src += trait.size; cursor_dst += trait.size; } @@ -129,10 +135,16 @@ void Archetype::SetLayout() { } } -Archetype* Archetype::New(CmptTraits& rtdCmptTraits, std::pmr::memory_resource* rsrc, std::span types, std::uint64_t version) { +Archetype* Archetype::New( + CmptTraits& rtdCmptTraits, + std::pmr::memory_resource* rsrc, + std::pmr::memory_resource* world_rsrc, + std::span types, + std::uint64_t version) +{ assert(std::find(types.begin(), types.end(), TypeID_of) == types.end()); - auto* rst = new Archetype{ rsrc, version }; + auto* rst = new Archetype{ rsrc, world_rsrc, version }; rst->cmptTraits.Register(rtdCmptTraits, TypeID_of); for (const auto& type : types) @@ -147,7 +159,7 @@ Archetype* Archetype::Add(CmptTraits& rtdCmptTraits, const Archetype* from, std: assert(std::find(types.begin(), types.end(), TypeID_of) == types.end()); assert(std::find_if_not(types.begin(), types.end(), [&](const auto& type) { return from->cmptTraits.GetTypes().contains(type); }) != types.end()); - auto* rst = new Archetype{ from->chunkAllocator.resource(), from->version }; + auto* rst = new Archetype{ from->chunkAllocator.resource(), from->world_rsrc, from->version }; rst->cmptTraits = from->cmptTraits; for (const auto& type : types) @@ -162,7 +174,7 @@ Archetype* Archetype::Remove(const Archetype* from, std::span type assert(std::find(types.begin(), types.end(), TypeID_of) == types.end()); assert(std::find_if(types.begin(), types.end(), [&](const auto& type) { return from->cmptTraits.GetTypes().contains(type); }) != types.end()); - auto* rst = new Archetype{ from->chunkAllocator.resource(), from->version }; + auto* rst = new Archetype{ from->chunkAllocator.resource(), from->world_rsrc, from->version }; rst->cmptTraits = from->cmptTraits; @@ -190,7 +202,7 @@ std::size_t Archetype::Create(Entity e) { } else { std::uint8_t* dst = buffer + offset + idxInChunk * trait.size; - trait.DefaultConstruct(dst); + trait.DefaultConstruct(dst, world_rsrc); } } chunk->GetHead()->UpdateVersion(version); @@ -261,7 +273,7 @@ std::size_t Archetype::Instantiate(Entity e, std::size_t srcIdx) { std::uint8_t* dst = dstBuffer + offset + dstIdxInChunk * size; std::uint8_t* src = srcBuffer + offset + srcIdxInChunk * size; - trait.CopyConstruct(dst, src); + trait.CopyConstruct(dst, src, world_rsrc); } } diff --git a/src/core/Archetype.hpp b/src/core/Archetype.hpp index 0289c17..a4d368e 100644 --- a/src/core/Archetype.hpp +++ b/src/core/Archetype.hpp @@ -16,16 +16,16 @@ namespace Ubpa::UECS { // type of Entity + Components is Archetype's type class Archetype { public: - Archetype(std::pmr::memory_resource* rsrc, std::uint64_t version) noexcept : chunkAllocator{ rsrc }, version{ version } {} + Archetype(std::pmr::memory_resource* rsrc, std::pmr::memory_resource* world_rsrc, std::uint64_t version) noexcept; // copy - Archetype(std::pmr::memory_resource* rsrc, const Archetype&); + Archetype(std::pmr::memory_resource* rsrc, std::pmr::memory_resource* world_rsrc, const Archetype&); Archetype(const Archetype&) = delete; ~Archetype(); // auto add Entity - static Archetype* New(CmptTraits&, std::pmr::memory_resource* rsrc, std::span types, std::uint64_t version); + static Archetype* New(CmptTraits&, std::pmr::memory_resource* rsrc, std::pmr::memory_resource* world_rsrc, std::span types, std::uint64_t version); static Archetype* Add(CmptTraits&, const Archetype* from, std::span types); @@ -91,6 +91,7 @@ namespace Ubpa::UECS { ArchetypeCmptTraits cmptTraits; // Entity + Components std::uint64_t version; + std::pmr::memory_resource* world_rsrc; // chunk infomations std::pmr::polymorphic_allocator chunkAllocator; diff --git a/src/core/ArchetypeCmptTraits.cpp b/src/core/ArchetypeCmptTraits.cpp index 61f62af..eddab3d 100644 --- a/src/core/ArchetypeCmptTraits.cpp +++ b/src/core/ArchetypeCmptTraits.cpp @@ -10,14 +10,14 @@ using namespace Ubpa::UECS; -void ArchetypeCmptTraits::CmptTrait::DefaultConstruct(void* cmpt) const { +void ArchetypeCmptTraits::CmptTrait::DefaultConstruct(void* cmpt, std::pmr::memory_resource* world_rsrc) const { if(default_ctor) - default_ctor(cmpt); + default_ctor(cmpt, world_rsrc); } -void ArchetypeCmptTraits::CmptTrait::CopyConstruct(void* dst, void* src) const { +void ArchetypeCmptTraits::CmptTrait::CopyConstruct(void* dst, const void* src, std::pmr::memory_resource* world_rsrc) const { if (copy_ctor) - copy_ctor(dst, src); + copy_ctor(dst, src, world_rsrc); else std::memcpy(dst, src, size); } @@ -25,8 +25,6 @@ void ArchetypeCmptTraits::CmptTrait::CopyConstruct(void* dst, void* src) const { void ArchetypeCmptTraits::CmptTrait::MoveConstruct(void* dst, void* src) const { if (move_ctor) move_ctor(dst, src); - else if (copy_ctor) - copy_ctor(dst, src); else std::memcpy(dst, src, size); } diff --git a/src/core/ArchetypeCmptTraits.hpp b/src/core/ArchetypeCmptTraits.hpp index ebab3de..03de749 100644 --- a/src/core/ArchetypeCmptTraits.hpp +++ b/src/core/ArchetypeCmptTraits.hpp @@ -6,6 +6,7 @@ #include #include +#include namespace Ubpa::UECS { class CmptTraits; @@ -19,14 +20,14 @@ namespace Ubpa::UECS { std::size_t size; std::size_t alignment; - std::function default_ctor; - std::function copy_ctor; // dst <- src + std::function default_ctor; + std::function copy_ctor; // dst <- src std::function move_ctor; // dst <- src std::function move_assign; // dst <- src std::function dtor; - void DefaultConstruct(void* cmpt) const; - void CopyConstruct(void* dst, void* src) const; + void DefaultConstruct(void* cmpt, std::pmr::memory_resource* world_rsrc) const; + void CopyConstruct(void* dst, const void* src, std::pmr::memory_resource* world_rsrc) const; void MoveConstruct(void* dst, void* src) const; void MoveAssign(void* dst, void* src) const; void Destruct(void* cmpt) const; diff --git a/src/core/CmptTraits.cpp b/src/core/CmptTraits.cpp index 240c3b7..644dbd1 100644 --- a/src/core/CmptTraits.cpp +++ b/src/core/CmptTraits.cpp @@ -3,12 +3,12 @@ using namespace Ubpa; using namespace Ubpa::UECS; -CmptTraits::CmptTraits() : rsrc {std::make_unique()} -{ - Register(); -} +CmptTraits::CmptTraits(std::pmr::memory_resource* world_rsrc) : + rsrc{ std::make_unique() }, + world_rsrc{ world_rsrc } +{ Register(); } -CmptTraits::CmptTraits(const CmptTraits& other) : +CmptTraits::CmptTraits(const CmptTraits& other, std::pmr::memory_resource* world_rsrc) : rsrc{ std::make_unique() }, sizeofs{other.sizeofs}, trivials{other.trivials}, @@ -17,7 +17,8 @@ CmptTraits::CmptTraits(const CmptTraits& other) : copy_constructors{other.copy_constructors }, move_constructors{other.move_constructors }, move_assignments{ other.move_assignments }, - destructors{ other.destructors } + destructors{ other.destructors }, + world_rsrc{ world_rsrc } { for (const auto& [id, name] : other.names) { char* buffer = (char*)rsrc->allocate((name.size() + 1) * sizeof(char), alignof(char)); @@ -28,26 +29,17 @@ CmptTraits::CmptTraits(const CmptTraits& other) : } } -CmptTraits& CmptTraits::operator=(const CmptTraits& rhs) { - sizeofs = rhs.sizeofs; - trivials = rhs.trivials; - alignments = rhs.alignments; - default_constructors = rhs.default_constructors; - copy_constructors = rhs.copy_constructors; - move_constructors = rhs.move_constructors; - move_assignments = rhs.move_assignments; - destructors = rhs.destructors; - - for (const auto& [id, name] : rhs.names) { - char* buffer = (char*)rsrc->allocate((name.size() + 1) * sizeof(char), alignof(char)); - std::memcpy(buffer, name.data(), name.size() * sizeof(char)); - buffer[name.size()] = 0; - names.emplace(id, std::string_view{ buffer, name.size() }); - buffer += name.size() + 1; - } - return *this; -} - +CmptTraits::CmptTraits(CmptTraits&& other) noexcept : + rsrc{ std::move(other.rsrc) }, + sizeofs{ std::move(other.sizeofs) }, + trivials{ std::move(other.trivials) }, + alignments{ std::move(other.alignments) }, + default_constructors{ std::move(other.default_constructors) }, + copy_constructors{ std::move(other.copy_constructors) }, + move_constructors{ std::move(other.move_constructors) }, + move_assignments{ std::move(other.move_assignments) }, + destructors{ std::move(other.destructors) }, + world_rsrc{ other.world_rsrc } { other.world_rsrc = nullptr; } bool CmptTraits::IsTrivial(TypeID type) const { return trivials.contains(type); @@ -69,14 +61,14 @@ void CmptTraits::DefaultConstruct(TypeID type, void* cmpt) const { auto target = default_constructors.find(type); if (target != default_constructors.end()) - target->second(cmpt); + target->second(cmpt, world_rsrc); } -void CmptTraits::CopyConstruct(TypeID type, void* dst, void* src) const { +void CmptTraits::CopyConstruct(TypeID type, void* dst, const void* src) const { auto target = copy_constructors.find(type); if (target != copy_constructors.end()) - target->second(dst, src); + target->second(dst, src, world_rsrc); else memcpy(dst, src, Sizeof(type)); } @@ -123,12 +115,12 @@ CmptTraits& CmptTraits::RegisterAlignment(TypeID type, std::size_t alignment) { return *this; } -CmptTraits& CmptTraits::RegisterDefaultConstructor(TypeID type, std::function f) { +CmptTraits& CmptTraits::RegisterDefaultConstructor(TypeID type, std::function f) { default_constructors.emplace(type, std::move(f)); return *this; } -CmptTraits& CmptTraits::RegisterCopyConstructor(TypeID type, std::function f) { +CmptTraits& CmptTraits::RegisterCopyConstructor(TypeID type, std::function f) { copy_constructors.emplace(type, std::move(f)); return *this; } diff --git a/src/core/EntityMngr.cpp b/src/core/EntityMngr.cpp index 2ddcd70..6afea16 100644 --- a/src/core/EntityMngr.cpp +++ b/src/core/EntityMngr.cpp @@ -9,19 +9,33 @@ using namespace Ubpa::UECS; using namespace std; -EntityMngr::EntityMngr() : - rsrc{ std::make_unique() } {} - -EntityMngr::EntityMngr(EntityMngr&&) noexcept = default; +EntityMngr::EntityMngr(std::pmr::memory_resource* world_rsrc) : + cmptTraits{ world_rsrc }, + rsrc{ std::make_unique() }, + world_rsrc{ world_rsrc }{} + +EntityMngr::EntityMngr(EntityMngr&& other) noexcept : + cmptTraits{ std::move(other.cmptTraits) }, + queryCache{std::move(other.queryCache)}, + version{other.version}, + world_rsrc{other.world_rsrc}, + entityTable{std::move(other.entityTable)}, + entityTableFreeEntry{std::move(other.entityTableFreeEntry)}, + rsrc{std::move(other.rsrc)}, + ts2a{std::move(other.ts2a)} +{ + other.version = 0; + other.world_rsrc = nullptr; +} -EntityMngr::EntityMngr(const EntityMngr& em) : - cmptTraits{ em.cmptTraits }, +EntityMngr::EntityMngr(const EntityMngr& em, std::pmr::memory_resource* world_rsrc) : + cmptTraits{ em.cmptTraits, world_rsrc }, rsrc{ std::make_unique() }, - version{em.version} + version{ em.version } { ts2a.reserve(em.ts2a.size()); for (const auto& [ts, a] : em.ts2a) - ts2a.try_emplace(ts, std::make_unique(rsrc.get(), *a)); + ts2a.try_emplace(ts, std::make_unique(rsrc.get(), world_rsrc, *a)); entityTableFreeEntry = em.entityTableFreeEntry; entityTable.resize(em.entityTable.size()); for (std::size_t i = 0; i < em.entityTable.size(); i++) { @@ -104,7 +118,7 @@ Archetype* EntityMngr::GetOrCreateArchetypeOf(std::span types) { if (target != ts2a.end()) return target->second.get(); - auto* archetype = Archetype::New(cmptTraits, rsrc.get(), types, version); + auto* archetype = Archetype::New(cmptTraits, rsrc.get(), world_rsrc, types, version); ts2a.emplace(std::move(typeset), std::unique_ptr{ archetype }); for (auto& [query, archetypes] : queryCache) { @@ -177,7 +191,7 @@ void EntityMngr::Attach(Entity e, std::span types) { auto target = dstArchetype->GetCmptTraits().GetTypes().find(type); assert(target != dstArchetype->GetCmptTraits().GetTypes().end()); auto idx = static_cast(std::distance(dstArchetype->GetCmptTraits().GetTypes().begin(), target)); - dstArchetype->GetCmptTraits().GetTraits()[idx].DefaultConstruct(info.archetype->WriteAt(type, info.idxInArchetype).Ptr()); + dstArchetype->GetCmptTraits().GetTraits()[idx].DefaultConstruct(info.archetype->WriteAt(type, info.idxInArchetype).Ptr(), world_rsrc); } } diff --git a/src/core/World.cpp b/src/core/World.cpp index b8bac6a..b9109d0 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -9,20 +9,24 @@ using namespace Ubpa; using namespace std; World::World() : - jobRsrc{ std::make_unique() }, - systemMngr{ this } {} + world_rsrc{ std::make_unique() }, + jobRsrc{ std::make_unique() }, + systemMngr{ this }, + entityMngr{ world_rsrc.get() }{} World::World(const World& w) : - jobRsrc{ std::make_unique() }, + world_rsrc{ std::make_unique() }, + jobRsrc{ std::make_unique() }, systemMngr{ w.systemMngr, this }, - entityMngr{ w.entityMngr }, - schedule{ w.schedule } {} + entityMngr{ w.entityMngr, world_rsrc.get() }, + schedule{ w.schedule } { assert(!w.inRunningJobGraph); } World::World(World&& w) noexcept : - jobRsrc{ std::make_unique() }, + world_rsrc{ std::move(w.world_rsrc) }, + jobRsrc{ std::make_unique() }, systemMngr{ std::move(w.systemMngr), this }, entityMngr{ std::move(w.entityMngr) }, - schedule{ std::move(w.schedule) }{} + schedule{ std::move(w.schedule) } { assert(!w.inRunningJobGraph); } World::~World() { schedule.Clear(); @@ -67,8 +71,9 @@ void World::Update() { for (auto* job : jobs) { job->~Taskflow(); - jobRsrc->deallocate(job, sizeof(Job), alignof(Job)); + //jobRsrc->deallocate(job, sizeof(Job), alignof(Job)); } + jobRsrc->release(); jobs.clear(); jobGraph.clear(); } diff --git a/src/test/11_runtime_cmpt/main.cpp b/src/test/11_runtime_cmpt/main.cpp index fceae0c..7d9ba69 100644 --- a/src/test/11_runtime_cmpt/main.cpp +++ b/src/test/11_runtime_cmpt/main.cpp @@ -53,7 +53,7 @@ int main() { w.systemMngr.RegisterAndActivate(); w.entityMngr.cmptTraits .RegisterSize(type, 8) - .RegisterDefaultConstructor(type, [](void*) { cout << "construct" << endl; }) + .RegisterDefaultConstructor(type, [](void*, std::pmr::memory_resource*) { cout << "construct" << endl; }) .RegisterDestructor(type, [](void*) { cout << "destruct" << endl; }); auto e = w.entityMngr.Create(Ubpa::TempTypeIDs{ type }); diff --git a/src/test/24_world_rsrc/CMakeLists.txt b/src/test/24_world_rsrc/CMakeLists.txt new file mode 100644 index 0000000..9c1502e --- /dev/null +++ b/src/test/24_world_rsrc/CMakeLists.txt @@ -0,0 +1,8 @@ +Ubpa_AddTarget( + TEST + RET_TARGET_NAME tname + MODE EXE + LIB + Ubpa::UECS_core +) +target_precompile_headers(${tname} REUSE_FROM UECS_core) diff --git a/src/test/24_world_rsrc/main.cpp b/src/test/24_world_rsrc/main.cpp new file mode 100644 index 0000000..2140a4d --- /dev/null +++ b/src/test/24_world_rsrc/main.cpp @@ -0,0 +1,42 @@ +#include + +using namespace Ubpa; +using namespace Ubpa::UECS; + +struct Buffer { + using allocator_type = std::pmr::vector::allocator_type; + Buffer(const Buffer& other, const allocator_type& alloc) + : value(alloc) {} + Buffer(const allocator_type& alloc) + : value(alloc) {} + allocator_type get_allocator() const noexcept { return value.get_allocator(); } + std::pmr::vector value; +}; + +struct PrintSystem { + static void OnUpdate(Schedule& schedule) { + schedule.RegisterEntityJob( + [](World* w, const Buffer* buffer) { + std::cout << w->GetSyncResource() << std::endl; + std::cout << buffer->get_allocator().resource() << std::endl; + }, + "Print" + ); + } +}; + +int main() { + World w; + w.entityMngr.cmptTraits.Register(); + w.systemMngr.RegisterAndCreate(); + w.systemMngr.Activate(); + + w.entityMngr.Create(TypeIDs_of); // use w's resource + w.Update(); + + World w2(w); // buffer use w2's resource + w.Update(); + w2.Update(); + + return 0; +}