diff --git a/CMakeLists.txt b/CMakeLists.txt index f984af0..0c2618a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.14 FATAL_ERROR) -project(UECS VERSION 0.14.0) +project(UECS VERSION 0.14.1) message(STATUS "[Project] ${PROJECT_NAME}") include(cmake/InitUCMake.cmake) diff --git a/doc/changelog.md b/doc/changelog.md new file mode 100644 index 0000000..4a1f0fb --- /dev/null +++ b/doc/changelog.md @@ -0,0 +1,4 @@ +# Change Log + +- 0.14.1: `CmptAccessMode` remove singleton +- 0.14.0: System Lifecycle \ No newline at end of file diff --git a/doc/todo.md b/doc/todo.md index c26e217..d8094da 100644 --- a/doc/todo.md +++ b/doc/todo.md @@ -29,7 +29,7 @@ - [x] system base -> `System` - [x] singleton - [ ] doxygen -- [ ] lock ? +- [ ] lock / random access - [x] system traits ### maybe support in future diff --git a/include/UECS/CmptTag.h b/include/UECS/CmptTag.h index 6490e70..e09827b 100644 --- a/include/UECS/CmptTag.h +++ b/include/UECS/CmptTag.h @@ -15,15 +15,8 @@ namespace Ubpa::UECS { LAST_FRAME = 0b000, // LastFrame WRITE = 0b001, // Write / Cmpt* LATEST = 0b010, // Latest / const Cmpt* - LAST_FRAME_SINGLETON = 0b100, // LastFrame> - WRITE_SINGLETON = 0b101, // Write> / Singleton - LATEST_SINGLETON = 0b110, // Latest> }; - constexpr bool AccessMode_IsSingleton(AccessMode mode) noexcept { - return (static_cast(mode) & 4) != 0; - } - template class Singleton { public: diff --git a/include/UECS/CmptType.h b/include/UECS/CmptType.h index 82556ef..292e417 100644 --- a/include/UECS/CmptType.h +++ b/include/UECS/CmptType.h @@ -51,8 +51,8 @@ namespace Ubpa::UECS { explicit constexpr CmptAccessType(CmptType type) noexcept : CmptAccessType{ type, AccessMode::LATEST } {} explicit constexpr CmptAccessType() noexcept : CmptAccessType{ Invalid() } {} - template - static constexpr CmptAccessType Of = CmptAccessType{ CmptType::Of>, AccessModeOf_default }; + template + static constexpr CmptAccessType Of = CmptAccessType{ CmptType::Of>, AccessModeOf }; // same with CmptType's HashCode constexpr size_t HashCode() const noexcept { return type.HashCode(); } @@ -61,7 +61,7 @@ namespace Ubpa::UECS { constexpr operator CmptType()const noexcept { return type; } - static constexpr CmptAccessType Invalid() noexcept { return CmptAccessType{ static_cast(-1), AccessMode::LATEST }; } + static constexpr CmptAccessType Invalid() noexcept { return CmptAccessType{ static_cast(-1), AccessMode{} }; } constexpr bool Valid() const noexcept { return type.Valid(); } // same with CmptType's operator< diff --git a/include/UECS/detail/CmptTag.inl b/include/UECS/detail/CmptTag.inl index b6e7122..6951524 100644 --- a/include/UECS/detail/CmptTag.inl +++ b/include/UECS/detail/CmptTag.inl @@ -101,21 +101,15 @@ namespace Ubpa::UECS { template static constexpr AccessMode AccessModeOf_default = - IsLastFrame_v ? AccessMode::LAST_FRAME : ( - IsWrite_v ? AccessMode::WRITE : ( - IsLatest_v ? AccessMode::LATEST : ( - IsLastFrameSingleton_v ? AccessMode::LAST_FRAME_SINGLETON : ( - IsWriteSingleton_v ? AccessMode::WRITE_SINGLETON : ( - IsLatestSingleton_v ? AccessMode::LATEST_SINGLETON : - defaultMode - ) - ) - ) + IsLastFrame_v || IsLastFrameSingleton_v ? AccessMode::LAST_FRAME : ( + IsWrite_v || IsWriteSingleton_v ? AccessMode::WRITE : ( + IsLatest_v || IsLatestSingleton_v ? AccessMode::LATEST : + defaultMode ) ); template - static constexpr AccessMode AccessModeOf = AccessModeOf_default; + static constexpr AccessMode AccessModeOf = AccessModeOf_default; template struct RemoveTag : IType {}; // default diff --git a/src/core/ArchetypeFilter.cpp b/src/core/ArchetypeFilter.cpp index 4c23bf9..f03174d 100644 --- a/src/core/ArchetypeFilter.cpp +++ b/src/core/ArchetypeFilter.cpp @@ -6,14 +6,10 @@ using namespace Ubpa::UECS; size_t ArchetypeFilter::HashCode() const noexcept { size_t rst = TypeID; - for (const auto& type : all) { - assert(!AccessMode_IsSingleton(type.GetAccessMode())); + for (const auto& type : all) rst = hash_combine(rst, type.HashCode()); - } - for (const auto& type : any) { - assert(!AccessMode_IsSingleton(type.GetAccessMode())); + for (const auto& type : any) rst = hash_combine(rst, type.HashCode()); - } for (const auto& type : none) rst = hash_combine(rst, type.HashCode()); return rst; diff --git a/src/core/CmptLocator.cpp b/src/core/CmptLocator.cpp index 96d4145..873ee6a 100644 --- a/src/core/CmptLocator.cpp +++ b/src/core/CmptLocator.cpp @@ -6,10 +6,8 @@ using namespace Ubpa::UECS; CmptLocator::CmptLocator(const CmptAccessType* types, size_t num) { assert(types || num == 0); - for (size_t i = 0; i < num; i++) { - assert(!AccessMode_IsSingleton(types[i].GetAccessMode())); + for (size_t i = 0; i < num; i++) cmptTypes.insert(types[i]); - } hashCode = GenHashCode(); } diff --git a/src/core/Schedule.cpp b/src/core/Schedule.cpp index d65d8a4..59743a4 100644 --- a/src/core/Schedule.cpp +++ b/src/core/Schedule.cpp @@ -226,13 +226,13 @@ unordered_map Schedule::GenCmptSysFuncsMap() c for (const auto& type : sysFunc->singletonLocator.SingletonTypes()) { switch (type.GetAccessMode()) { - case Ubpa::UECS::AccessMode::LAST_FRAME_SINGLETON: + case Ubpa::UECS::AccessMode::LAST_FRAME: rst[type].lastFrameSysFuncs.push_back(sysFunc); break; - case Ubpa::UECS::AccessMode::WRITE_SINGLETON: + case Ubpa::UECS::AccessMode::WRITE: rst[type].writeSysFuncs.push_back(sysFunc); break; - case Ubpa::UECS::AccessMode::LATEST_SINGLETON: + case Ubpa::UECS::AccessMode::LATEST: rst[type].latestSysFuncs.push_back(sysFunc); break; default: diff --git a/src/core/SingletonLocator.cpp b/src/core/SingletonLocator.cpp index a7ac51a..26987e9 100644 --- a/src/core/SingletonLocator.cpp +++ b/src/core/SingletonLocator.cpp @@ -6,14 +6,13 @@ using namespace std; SingletonLocator::SingletonLocator(const CmptAccessType* types, size_t num) { assert(types || num == 0); for (size_t i = 0; i < num; i++) { - assert(AccessMode_IsSingleton(types[i].GetAccessMode())); singletonTypes.insert(types[i]); } } bool SingletonLocator::HasWriteSingletonType() const noexcept { for (const auto& type : singletonTypes) { - if (type.GetAccessMode() == AccessMode::WRITE_SINGLETON) + if (type.GetAccessMode() == AccessMode::WRITE) return true; } return false; diff --git a/src/core/World.cpp b/src/core/World.cpp index cec5931..835cd68 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -142,7 +142,8 @@ UGraphviz::Graph World::GenUpdateFrameGraph() const { .RegisterGraphEdgeAttr("color", "#C785C8") .RegisterGraphEdgeAttr("arrowhead", "odot"); - unordered_set cmptTypes; + unordered_set cmptTypes; + unordered_set singletonTypes; unordered_map cmptType2idx; unordered_map sysFuncHashcode2idx; @@ -159,18 +160,21 @@ UGraphviz::Graph World::GenUpdateFrameGraph() const { for (auto cmptType : sysFunc->entityQuery.filter.any) cmptTypes.insert(cmptType); for (auto cmptType : sysFunc->entityQuery.filter.none) - cmptTypes.insert(CmptAccessType{ cmptType }); + cmptTypes.insert(cmptType); for (auto singleton : sysFunc->singletonLocator.SingletonTypes()) - cmptTypes.insert(singleton); + singletonTypes.insert(singleton); } for (const auto& cmptType : cmptTypes) { auto cmptIdx = registry.RegisterNode(queryCmptName(cmptType)); cmptType2idx.emplace(cmptType, cmptIdx); - if (AccessMode_IsSingleton(cmptType.GetAccessMode())) - subgraph_singleton.AddNode(cmptIdx); - else - subgraph_cmpt.AddNode(cmptIdx); + subgraph_cmpt.AddNode(cmptIdx); + } + + for (const auto& singletonType : singletonTypes) { + auto cmptIdx = registry.RegisterNode(queryCmptName(singletonType)); + cmptType2idx.emplace(singletonType, cmptIdx); + subgraph_singleton.AddNode(cmptIdx); } for (const auto& [hash, sysFunc] : schedule.sysFuncs) { @@ -184,15 +188,15 @@ UGraphviz::Graph World::GenUpdateFrameGraph() const { switch (cmptType.GetAccessMode()) { case AccessMode::LAST_FRAME: - edgeIdx = registry.RegisterEdge(cmptType2idx[cmptType], sysIdx); + edgeIdx = registry.RegisterEdge(cmptType2idx.at(cmptType), sysIdx); subgraph_lastframe.AddEdge(edgeIdx); break; case AccessMode::WRITE: - edgeIdx = registry.RegisterEdge(sysIdx, cmptType2idx[cmptType]); + edgeIdx = registry.RegisterEdge(sysIdx, cmptType2idx.at(cmptType)); subgraph_write.AddEdge(edgeIdx); break; case AccessMode::LATEST: - edgeIdx = registry.RegisterEdge(cmptType2idx[cmptType], sysIdx); + edgeIdx = registry.RegisterEdge(cmptType2idx.at(cmptType), sysIdx); subgraph_latest.AddEdge(edgeIdx); break; default: @@ -205,20 +209,20 @@ UGraphviz::Graph World::GenUpdateFrameGraph() const { if (sysFunc->GetMode() == SystemFunc::Mode::Chunk) { // filter's and components are treat as r/w for (const auto& cmptType : filter.all) { - auto cmptIdx = cmptType2idx[cmptType]; + auto cmptIdx = cmptType2idx.at(cmptType); size_t edgeIdx; switch (cmptType.GetAccessMode()) { case AccessMode::LAST_FRAME: - edgeIdx = registry.RegisterEdge(cmptType2idx[cmptType], sysIdx); + edgeIdx = registry.RegisterEdge(cmptType2idx.at(cmptType), sysIdx); subgraph_lastframe.AddEdge(edgeIdx); break; case AccessMode::WRITE: - edgeIdx = registry.RegisterEdge(sysIdx, cmptType2idx[cmptType]); + edgeIdx = registry.RegisterEdge(sysIdx, cmptType2idx.at(cmptType)); subgraph_write.AddEdge(edgeIdx); break; case AccessMode::LATEST: - edgeIdx = registry.RegisterEdge(cmptType2idx[cmptType], sysIdx); + edgeIdx = registry.RegisterEdge(cmptType2idx.at(cmptType), sysIdx); subgraph_latest.AddEdge(edgeIdx); break; default: @@ -227,20 +231,20 @@ UGraphviz::Graph World::GenUpdateFrameGraph() const { } } for (const auto& cmptType : filter.any) { - auto cmptIdx = cmptType2idx[cmptType]; + auto cmptIdx = cmptType2idx.at(cmptType); size_t edgeIdx; switch (cmptType.GetAccessMode()) { case AccessMode::LAST_FRAME: - edgeIdx = registry.RegisterEdge(cmptType2idx[cmptType], sysIdx); + edgeIdx = registry.RegisterEdge(cmptType2idx.at(cmptType), sysIdx); subgraph_lastframe.AddEdge(edgeIdx); break; case AccessMode::WRITE: - edgeIdx = registry.RegisterEdge(sysIdx, cmptType2idx[cmptType]); + edgeIdx = registry.RegisterEdge(sysIdx, cmptType2idx.at(cmptType)); subgraph_write.AddEdge(edgeIdx); break; case AccessMode::LATEST: - edgeIdx = registry.RegisterEdge(cmptType2idx[cmptType], sysIdx); + edgeIdx = registry.RegisterEdge(cmptType2idx.at(cmptType), sysIdx); subgraph_latest.AddEdge(edgeIdx); break; default: @@ -251,25 +255,25 @@ UGraphviz::Graph World::GenUpdateFrameGraph() const { } else { for (const auto& cmptType : filter.all) { - auto cmptIdx = cmptType2idx[cmptType]; + auto cmptIdx = cmptType2idx.at(cmptType); if (registry.IsRegisteredEdge(sysIdx, cmptIdx)) continue; - auto edgeIdx = registry.RegisterEdge(sysIdx, cmptType2idx[cmptType]); + auto edgeIdx = registry.RegisterEdge(sysIdx, cmptType2idx.at(cmptType)); subgraph_all.AddEdge(edgeIdx); } for (const auto& cmptType : filter.any) { - auto cmptIdx = cmptType2idx[cmptType]; + auto cmptIdx = cmptType2idx.at(cmptType); if (registry.IsRegisteredEdge(sysIdx, cmptIdx)) continue; - auto edgeIdx = registry.RegisterEdge(sysIdx, cmptType2idx[cmptType]); + auto edgeIdx = registry.RegisterEdge(sysIdx, cmptType2idx.at(cmptType)); subgraph_any.AddEdge(edgeIdx); } } for (const auto& cmptType : filter.none) { - auto cmptIdx = cmptType2idx[cmptType]; + auto cmptIdx = cmptType2idx.at(cmptType); if (registry.IsRegisteredEdge(sysIdx, cmptIdx)) continue; - auto edgeIdx = registry.RegisterEdge(sysIdx, cmptType2idx[cmptType]); + auto edgeIdx = registry.RegisterEdge(sysIdx, cmptType2idx.at(cmptType)); subgraph_none.AddEdge(edgeIdx); } @@ -277,16 +281,16 @@ UGraphviz::Graph World::GenUpdateFrameGraph() const { size_t edgeIdx; switch (singleton.GetAccessMode()) { - case AccessMode::LAST_FRAME_SINGLETON: - edgeIdx = registry.RegisterEdge(cmptType2idx[singleton], sysIdx); + case AccessMode::LAST_FRAME: + edgeIdx = registry.RegisterEdge(cmptType2idx.at(singleton), sysIdx); subgraph_lastframe.AddEdge(edgeIdx); break; - case AccessMode::WRITE_SINGLETON: - edgeIdx = registry.RegisterEdge(sysIdx, cmptType2idx[singleton]); + case AccessMode::WRITE: + edgeIdx = registry.RegisterEdge(sysIdx, cmptType2idx.at(singleton)); subgraph_write.AddEdge(edgeIdx); break; - case AccessMode::LATEST_SINGLETON: - edgeIdx = registry.RegisterEdge(cmptType2idx[singleton], sysIdx); + case AccessMode::LATEST: + edgeIdx = registry.RegisterEdge(cmptType2idx.at(singleton), sysIdx); subgraph_latest.AddEdge(edgeIdx); break; default: