diff --git a/doc/todo.md b/doc/todo.md index 49e468a..ee06833 100644 --- a/doc/todo.md +++ b/doc/todo.md @@ -31,7 +31,7 @@ - [ ] batch create/instantiate (need benchmark) - [x] lock `FilterChange` - [ ] `EntityMngr` `Query`-driven API -- [ ] `RTDCmpts` = `const EntityLocator* locator + void** cmpts` +- [x] `RTDCmptViewer` = `const EntityLocator* locator + void** cmpts` ### maybe deprecate diff --git a/include/UECS/CmptPtr.h b/include/UECS/CmptPtr.h index bbbb223..81bf991 100644 --- a/include/UECS/CmptPtr.h +++ b/include/UECS/CmptPtr.h @@ -15,6 +15,7 @@ namespace Ubpa { CmptType Type() const noexcept { return type; } void* Ptr() const noexcept { return p; } + // for static Component template Cmpt* As() const noexcept { assert(type.Is()); @@ -35,6 +36,7 @@ namespace Ubpa { CmptType Type() const noexcept { return type; } const void* Ptr() const noexcept { return p; } + // for static Component template const Cmpt* As() const noexcept { assert(type.Is()); diff --git a/include/UECS/CmptType.h b/include/UECS/CmptType.h index a217d45..10db3b7 100644 --- a/include/UECS/CmptType.h +++ b/include/UECS/CmptType.h @@ -18,6 +18,8 @@ namespace Ubpa { template static constexpr size_t HashCodeOf() noexcept { return TypeID; } + static constexpr CmptType Invalid() noexcept { return CmptType{ static_cast(-1) }; } + template bool Is() const noexcept { return hashcode == HashCodeOf(); } diff --git a/include/UECS/RTDCmptViewer.h b/include/UECS/RTDCmptViewer.h new file mode 100644 index 0000000..17de96e --- /dev/null +++ b/include/UECS/RTDCmptViewer.h @@ -0,0 +1,57 @@ +#pragma once + +#include "CmptPtr.h" +#include "CmptType.h" + +#include + +namespace Ubpa { + class EntityLocator; + class RTDCmptViewer { + public: + class Iterator /*: public std::iterator*/ { + public: + using iterator_category = std::forward_iterator_tag; + using value_type = CmptPtr; + using difference_type = std::ptrdiff_t; + using pointer = CmptPtr*; + using reference = CmptPtr&; + + Iterator(std::set::iterator typeIter = std::set::iterator{}, void** ptr_cmpt = nullptr) + : typeIter(typeIter), ptr_cmpt{ ptr_cmpt } {} + bool operator==(const Iterator& rhs) const noexcept { + return ptr_cmpt == rhs.ptr_cmpt; + } + bool operator!=(const Iterator& rhs) const noexcept { + return !this->operator==(rhs); + } + CmptPtr operator*() const noexcept { return cmptptr; } + const CmptPtr* operator->() const noexcept { + cmptptr = { *typeIter, *ptr_cmpt }; + return &cmptptr; + } + Iterator& operator++() { + typeIter++; + ptr_cmpt++; + return *this; + } + private: + std::set::iterator typeIter; + void** ptr_cmpt; + mutable CmptPtr cmptptr{ CmptType::Invalid(), nullptr }; + }; + + RTDCmptViewer(EntityLocator* locator, void** cmpts) + : locator{ locator }, cmpts{ cmpts }{} + + Iterator begin() const noexcept; + Iterator end() const noexcept; + + const std::set& CmptTypes() const noexcept; + void* const* Components() const noexcept { return cmpts; } + + private: + EntityLocator* locator; + void** cmpts; + }; +} diff --git a/include/UECS/SystemFunc.h b/include/UECS/SystemFunc.h index 7080734..44e5089 100644 --- a/include/UECS/SystemFunc.h +++ b/include/UECS/SystemFunc.h @@ -2,6 +2,7 @@ #include "EntityQuery.h" #include "Entity.h" +#include "RTDCmptViewer.h" #include @@ -33,8 +34,8 @@ namespace Ubpa { size_t HashCode() const noexcept { return hashCode; } - void operator()(Entity e, size_t entityIndexInQuery, const EntityLocator* locator, void** cmptArr) { - return func(e, entityIndexInQuery, locator, cmptArr); + void operator()(Entity e, size_t entityIndexInQuery, RTDCmptViewer rtdcmpts) { + return func(e, entityIndexInQuery, rtdcmpts); } // no arguments @@ -45,7 +46,7 @@ namespace Ubpa { template SystemFunc(Func&& func, std::string name, EntityFilter filter, ArgList); - std::function func; + std::function func; std::string name; bool isJob; diff --git a/include/UECS/detail/SystemFunc.inl b/include/UECS/detail/SystemFunc.inl index 7653b64..ae593cf 100644 --- a/include/UECS/detail/SystemFunc.inl +++ b/include/UECS/detail/SystemFunc.inl @@ -18,8 +18,8 @@ namespace Ubpa { { using ArgList = FuncTraits_ArgList; - static_assert(ContainTs_v, - "'s argument must contain const EntityLocator* and void**"); + static_assert(ContainTs_v, + "'s argument must contain RTDCmptViewer"); } template @@ -49,8 +49,8 @@ namespace Ubpa::detail::System_ { using CmptList = TypeList; template static auto run(Func&& func) noexcept { - return [func = std::forward(func)](Entity e, size_t entityIndexInQuery, const EntityLocator* locator, void** cmpt_arr) { - auto unsorted_arg_tuple = std::make_tuple(e, entityIndexInQuery, locator, cmpt_arr, reinterpret_cast(cmpt_arr[Find_v])...); + return [func = std::forward(func)](Entity e, size_t entityIndexInQuery, RTDCmptViewer rtdcmpts) { + auto unsorted_arg_tuple = std::make_tuple(e, entityIndexInQuery, rtdcmpts, reinterpret_cast(rtdcmpts.Components()[Find_v])...); func(std::get(unsorted_arg_tuple)...); }; } diff --git a/src/core/EntityMngr.cpp b/src/core/EntityMngr.cpp index 18c0459..336950a 100644 --- a/src/core/EntityMngr.cpp +++ b/src/core/EntityMngr.cpp @@ -258,7 +258,7 @@ void EntityMngr::GenJob(Job* job, SystemFunc* sys) const { size_t J = min(chunkCapacity, num - idxOffsetInChunk); for (size_t j = 0; j < J; j++) { - (*sys)(entities[j], indexOffsetInQueryChunk + j, &sys->query.locator, cmpts.data()); + (*sys)(entities[j], indexOffsetInQueryChunk + j, { &sys->query.locator, cmpts.data() }); for (size_t k = 0; k < cmpts.size(); k++) reinterpret_cast(cmpts[k]) += sizes[k]; } diff --git a/src/core/RTDCmptViewer.cpp b/src/core/RTDCmptViewer.cpp new file mode 100644 index 0000000..9dac7e6 --- /dev/null +++ b/src/core/RTDCmptViewer.cpp @@ -0,0 +1,18 @@ +#include + +#include + +using namespace Ubpa; +using namespace std; + +RTDCmptViewer::Iterator RTDCmptViewer::begin() const noexcept { + return { locator->CmptTypes().begin(), cmpts }; +} + +RTDCmptViewer::Iterator RTDCmptViewer::end() const noexcept { + return { locator->CmptTypes().end(), cmpts + locator->CmptTypes().size() }; +} + +const set& RTDCmptViewer::CmptTypes() const noexcept { + return locator->CmptTypes(); +} diff --git a/src/test/11_runtime_cmpt/main.cpp b/src/test/11_runtime_cmpt/main.cpp index ccb35f2..a53c723 100644 --- a/src/test/11_runtime_cmpt/main.cpp +++ b/src/test/11_runtime_cmpt/main.cpp @@ -19,25 +19,21 @@ struct RTDSystem { ); schedule .Register( - [](const EntityLocator* locator, void** cmpts) { - size_t i = 0; - for (auto type : locator->CmptTypes()) { - if (type == CmptType{ "LuaCmpt" }) { - double& val = *reinterpret_cast(cmpts[i]); + [](RTDCmptViewer cmpts) { + for (auto cmptptr : cmpts) { + if (cmptptr.Type() == CmptType{ "LuaCmpt" }) { + double& val = *reinterpret_cast(cmptptr.Ptr()); val = 520.; } - i++; } }, "write", locator_write) .Register( - [](const EntityLocator* locator, void** cmpts) { - size_t i = 0; - for (auto type : locator->CmptTypes()) { - if (type == CmptType{ "LuaCmpt" }) { - const double& val = *reinterpret_cast(cmpts[i]); + [](RTDCmptViewer cmpts) { + for (auto cmptptr : cmpts) { + if (cmptptr.Type() == CmptType{ "LuaCmpt" }) { + double& val = *reinterpret_cast(cmptptr.Ptr()); cout << "value : " << val << endl; } - i++; } }, "read", locator_read); }