diff --git a/include/UECS/Entity.h b/include/UECS/Entity.h index 2a5ea70..0e055c8 100644 --- a/include/UECS/Entity.h +++ b/include/UECS/Entity.h @@ -11,7 +11,7 @@ namespace Ubpa::UECS { constexpr size_t Idx() const noexcept { return idx; } constexpr size_t Version() const noexcept { return version; } static constexpr Entity Invalid() noexcept { return { size_t_invalid,size_t_invalid }; } - constexpr bool IsValid() const noexcept { return idx == size_t_invalid; } + constexpr bool Valid() const noexcept { return idx != size_t_invalid; } constexpr bool operator==(const Entity& rhs) const noexcept { return idx == rhs.idx && version == rhs.version; } diff --git a/include/UECS/RTDCmptTraits.h b/include/UECS/RTDCmptTraits.h index 74256d8..09288b3 100644 --- a/include/UECS/RTDCmptTraits.h +++ b/include/UECS/RTDCmptTraits.h @@ -46,6 +46,15 @@ namespace Ubpa::UECS { // optional RTDCmptTraits& RegisterName(CmptType, std::string name); + const auto& GetSizeofs() const noexcept { return sizeofs; } + const auto& GetAlignments() const noexcept { return alignments; }; + const auto& GetDefaultConstructors() const noexcept { return default_constructors; } + const auto& GetCopyConstructors() const noexcept { return copy_constructors; } + const auto& GetMoveConstructors() const noexcept { return move_constructors; } + const auto& GetMoveAssignments() const noexcept { return move_assignments; } + const auto& GetDestructors() const noexcept { return destructors; } + const auto& GetNames() const noexcept { return names; } + size_t Sizeof(CmptType) const; size_t Alignof(CmptType) const; void DefaultConstruct(CmptType, void* cmpt) const; @@ -64,18 +73,12 @@ namespace Ubpa::UECS { void Deregister(); private: - friend class RTSCmptTraits; - friend class Archetype; - friend class EntityMngr; - friend class World; - - RTDCmptTraits() = default; - // register all for Cmpt // static_assert // - is_default_constructible_v // - is_copy_constructible_v // - is_move_constructible_v + // - is_move_assignable_v // - is_destructible_v template void RegisterOne(); diff --git a/include/UECS/World.h b/include/UECS/World.h index 5609594..7ce0233 100644 --- a/include/UECS/World.h +++ b/include/UECS/World.h @@ -26,6 +26,8 @@ namespace Ubpa::UECS { // 4. run commands in main thread void Update(); + void AddCommand(std::function command); + // after running Update // you can use graphviz to vistualize the graph std::string DumpUpdateJobGraph() const; @@ -36,7 +38,8 @@ namespace Ubpa::UECS { void Accept(IListener*) const; - void AddCommand(std::function command); + // you can't run several parallel jobs in parallel because there is only an executor + // you can't run parallel jobs in runing job graph // Func's argument list: // World* @@ -79,6 +82,8 @@ namespace Ubpa::UECS { ); private: + bool inRunningJobGraph{ false }; + mutable JobExecutor executor; Schedule schedule; diff --git a/include/UECS/detail/RTSCmptTraits.h b/include/UECS/detail/RTSCmptTraits.h index ff27e54..04d4171 100644 --- a/include/UECS/detail/RTSCmptTraits.h +++ b/include/UECS/detail/RTSCmptTraits.h @@ -10,22 +10,21 @@ namespace Ubpa::UECS { // run-time static component traits class RTSCmptTraits { public: - size_t Sizeof(CmptType type) const; - size_t Alignof(CmptType type) const; - void CopyConstruct(CmptType type, void* dst, void* src) const; - void MoveConstruct(CmptType type, void* dst, void* src) const; - void MoveAssign(CmptType type, void* dst, void* src) const; - void Destruct(CmptType type, void* cmpt) const; + size_t Sizeof(CmptType) const; + size_t Alignof(CmptType) const; + void CopyConstruct(CmptType, void* dst, void* src) const; + void MoveConstruct(CmptType, void* dst, void* src) const; + void MoveAssign(CmptType, void* dst, void* src) const; + void Destruct(CmptType, void* cmpt) const; template void Register(); - // use RTDCmptTraits - void Register(const RTDCmptTraits& rtdCmptTraits, CmptType type); + void Register(const RTDCmptTraits&, CmptType); template void Deregister(); - void Deregister(CmptType type) noexcept; + void Deregister(CmptType) noexcept; private: friend class Archetype; diff --git a/include/UECS/detail/RTSCmptTraits.inl b/include/UECS/detail/RTSCmptTraits.inl index e974d94..dde503b 100644 --- a/include/UECS/detail/RTSCmptTraits.inl +++ b/include/UECS/detail/RTSCmptTraits.inl @@ -99,29 +99,29 @@ namespace Ubpa::UECS { } inline void RTSCmptTraits::Register(const RTDCmptTraits& rtdct, CmptType type) { - auto size_target = rtdct.sizeofs.find(type); - if (size_target == rtdct.sizeofs.end()) + auto size_target = rtdct.GetSizeofs().find(type); + if (size_target == rtdct.GetSizeofs().end()) throw std::logic_error("RTSCmptTraits::Register: RTDCmptTraits hasn't registered "); sizeofs[type] = size_target->second; - auto alignment_target = rtdct.alignments.find(type); - if (alignment_target == rtdct.alignments.end()) + auto alignment_target = rtdct.GetAlignments().find(type); + if (alignment_target == rtdct.GetAlignments().end()) alignments[type] = RTDCmptTraits::default_alignment; else alignments[type] = alignment_target->second; - auto destructor_target = rtdct.destructors.find(type); - auto copy_constructor_target = rtdct.copy_constructors.find(type); - auto move_constructor_target = rtdct.move_constructors.find(type); - auto move_assignments_target = rtdct.move_assignments.find(type); + auto destructor_target = rtdct.GetDestructors().find(type); + auto copy_constructor_target = rtdct.GetCopyConstructors().find(type); + auto move_constructor_target = rtdct.GetMoveConstructors().find(type); + auto move_assignments_target = rtdct.GetMoveAssignments().find(type); - if (destructor_target != rtdct.destructors.end()) + if (destructor_target != rtdct.GetDestructors().end()) destructors.emplace(type, destructor_target->second); - if (copy_constructor_target != rtdct.copy_constructors.end()) + if (copy_constructor_target != rtdct.GetCopyConstructors().end()) copy_constructors.emplace(type, copy_constructor_target->second); - if (move_constructor_target != rtdct.move_constructors.end()) + if (move_constructor_target != rtdct.GetMoveConstructors().end()) move_constructors.emplace(type, move_constructor_target->second); - if (move_assignments_target != rtdct.move_assignments.end()) + if (move_assignments_target != rtdct.GetMoveAssignments().end()) move_assignments.emplace(type, move_assignments_target->second); } diff --git a/src/app/CmptHashCode/CMakeLists.txt b/src/app/CmptHashCode/CMakeLists.txt new file mode 100644 index 0000000..4dc3240 --- /dev/null +++ b/src/app/CmptHashCode/CMakeLists.txt @@ -0,0 +1,6 @@ +Ubpa_GetTargetName(core "${PROJECT_SOURCE_DIR}/src/core") +Ubpa_AddTarget( + MODE EXE + INC_PRIVATE + "${PROJECT_SOURCE_DIR}/include" +) diff --git a/src/app/CmptHashCode/main.cpp b/src/app/CmptHashCode/main.cpp new file mode 100644 index 0000000..b3bcf38 --- /dev/null +++ b/src/app/CmptHashCode/main.cpp @@ -0,0 +1,14 @@ +#include + +#include + +using namespace std; + +int main(int argc, char** argv) { + if (argc != 2) + return 1; + + std::cout << Ubpa::UECS::CmptType(argv[1]).HashCode() << std::endl; + + return 0; +} diff --git a/src/core/Archetype.cpp b/src/core/Archetype.cpp index f27769a..f885950 100644 --- a/src/core/Archetype.cpp +++ b/src/core/Archetype.cpp @@ -145,8 +145,8 @@ size_t Archetype::Create(Entity e) { memcpy(buffer + offset + idxInChunk * size, &e, size); } else { - auto target = rtdct.default_constructors.find(type); - if (target == rtdct.default_constructors.end()) + auto target = rtdct.GetDefaultConstructors().find(type); + if (target == rtdct.GetDefaultConstructors().end()) continue; const auto& ctor = target->second; size_t size = cmptTraits.Sizeof(type); diff --git a/src/core/EntityMngr.cpp b/src/core/EntityMngr.cpp index e2b49f4..8b0c3c5 100644 --- a/src/core/EntityMngr.cpp +++ b/src/core/EntityMngr.cpp @@ -52,12 +52,7 @@ void EntityMngr::Swap(EntityMngr& rhs) noexcept { swap(entityTableFreeEntry, rhs.entityTableFreeEntry); swap(entityTable, rhs.entityTable); swap(queryCache, rhs.queryCache); - - auto pool = std::move(sharedChunkPool); - sharedChunkPool.~Pool(); - new(&sharedChunkPool)Pool(std::move(rhs.sharedChunkPool)); - rhs.sharedChunkPool.~Pool(); - new(&rhs.sharedChunkPool)Pool(std::move(pool)); + swap(sharedChunkPool, rhs.sharedChunkPool); } void EntityMngr::RecycleEntityEntry(Entity e) { @@ -158,8 +153,8 @@ void EntityMngr::Attach(Entity e, const CmptType* types, size_t num) { if (origArchetype->GetCmptTypeSet().Contains(type)) continue; - auto target = world->cmptTraits.default_constructors.find(type); - if (target == world->cmptTraits.default_constructors.end()) + auto target = world->cmptTraits.GetDefaultConstructors().find(type); + if (target == world->cmptTraits.GetDefaultConstructors().end()) continue; target->second(info.archetype->At(type, info.idxInArchetype)); diff --git a/src/core/World.cpp b/src/core/World.cpp index d39cc01..7e6c0ef 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -9,6 +9,8 @@ using namespace std; World::World() : systemMngr{ this }, entityMngr{ this } {} void World::Update() { + inRunningJobGraph = true; + schedule.Clear(); for (auto job : jobs) jobPool.Recycle(job); @@ -36,6 +38,7 @@ void World::Update() { } executor.run(jobGraph).wait(); + inRunningJobGraph = false; RunCommands(); } @@ -46,8 +49,8 @@ string World::DumpUpdateJobGraph() const { void World::Run(SystemFunc* sys) { if (sys->IsParallel()) { + assert(!inRunningJobGraph); Job job; - JobExecutor executor; entityMngr.AutoGen(this, &job, sys); executor.run(job).wait(); } @@ -285,6 +288,7 @@ void World::Accept(IListener* listener) const { } void World::AddCommand(std::function command) { + assert(inRunningJobGraph); std::lock_guard guard(commandBufferMutex); commandBuffer.push_back(std::move(command)); }