diff --git a/CMakeLists.txt b/CMakeLists.txt index a8940d1..912b136 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.14 FATAL_ERROR) -project(UECS VERSION 0.9.3) +project(UECS VERSION 0.9.4) message(STATUS "[Project] ${PROJECT_NAME}") include(FetchContent) diff --git a/doc/todo.md b/doc/todo.md index ee06833..daa94f3 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 -- [x] `RTDCmptViewer` = `const EntityLocator* locator + void** cmpts` +- [x] `RTDCmptsView` = `const EntityLocator* locator + void** cmpts` ### maybe deprecate diff --git a/include/UECS/RTDCmptViewer.h b/include/UECS/RTDCmptViewer.h deleted file mode 100644 index 26f1006..0000000 --- a/include/UECS/RTDCmptViewer.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include "CmptPtr.h" -#include "CmptType.h" - -#include - -namespace Ubpa { - class EntityLocator; - - // use RTDCmptViewer::Iterator to read CmptPtr - // no read/write control - class RTDCmptViewer { - public: - // forward - 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* const* 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* const* 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* const* cmpts; - }; -} diff --git a/include/UECS/RTDCmptsView.h b/include/UECS/RTDCmptsView.h new file mode 100644 index 0000000..d2a066f --- /dev/null +++ b/include/UECS/RTDCmptsView.h @@ -0,0 +1,101 @@ +#pragma once + +#include "CmptPtr.h" +#include "CmptType.h" + +#include + +namespace Ubpa { + class EntityLocator; + + // use RTDCmptsView::Iterator to read CmptPtr + // use CmptHandle for read/write control + // use begin() and end() to iterate + class RTDCmptsView { + public: + // for read/write control + class CmptHandle { + public: + enum class Mode { + INVALID, + LAST_FRAME, + WRITE, + LATEST + }; + + CmptHandle(CmptType type, void* cmpt, Mode mode) + : type{ type }, cmpt{ cmpt }, mode{ mode }{} + + CmptType GetCmptType() const noexcept { return type; } + Mode GetMode() const noexcept { return mode; } + + CmptCPtr AsLastFrame() const noexcept { + assert(mode == Mode::LAST_FRAME); + return { type, cmpt }; + } + CmptPtr AsWrite() const noexcept { + assert(mode == Mode::WRITE); + return { type, cmpt }; + } + CmptCPtr AsLatest() const noexcept { + assert(mode == Mode::LATEST); + return { type, cmpt }; + } + private: + CmptType type; + void* cmpt; + Mode mode; + }; + + // forward + 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(EntityLocator* locator, std::set::iterator typeIter = std::set::iterator{}, void* const* ptr_cmpt = nullptr) + : locator{ locator }, 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 ptr_cmpt != rhs.ptr_cmpt; + } + CmptHandle operator*() const { + return { *typeIter, *ptr_cmpt, GetMode() }; + } + const CmptHandle* operator->() const noexcept { + handle = { *typeIter, *ptr_cmpt, GetMode() }; + return &handle; + } + Iterator& operator++() { + typeIter++; + ptr_cmpt++; + return *this; + } + private: + CmptHandle::Mode GetMode() const; + + EntityLocator* locator; + std::set::iterator typeIter; + void* const* ptr_cmpt; + mutable CmptHandle handle{ CmptType::Invalid(), nullptr, CmptHandle::Mode::INVALID }; + }; + + RTDCmptsView(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* const* cmpts; + }; +} diff --git a/include/UECS/SystemFunc.h b/include/UECS/SystemFunc.h index 44e5089..de061d7 100644 --- a/include/UECS/SystemFunc.h +++ b/include/UECS/SystemFunc.h @@ -2,7 +2,7 @@ #include "EntityQuery.h" #include "Entity.h" -#include "RTDCmptViewer.h" +#include "RTDCmptsView.h" #include @@ -34,7 +34,7 @@ namespace Ubpa { size_t HashCode() const noexcept { return hashCode; } - void operator()(Entity e, size_t entityIndexInQuery, RTDCmptViewer rtdcmpts) { + void operator()(Entity e, size_t entityIndexInQuery, RTDCmptsView rtdcmpts) { return func(e, entityIndexInQuery, rtdcmpts); } @@ -46,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 ae593cf..5055baf 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 RTDCmptViewer"); + static_assert(ContainTs_v, + "'s argument must contain RTDCmptsView"); } template @@ -49,7 +49,7 @@ namespace Ubpa::detail::System_ { using CmptList = TypeList; template static auto run(Func&& func) noexcept { - return [func = std::forward(func)](Entity e, size_t entityIndexInQuery, RTDCmptViewer rtdcmpts) { + return [func = std::forward(func)](Entity e, size_t entityIndexInQuery, RTDCmptsView 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/RTDCmptViewer.cpp b/src/core/RTDCmptViewer.cpp deleted file mode 100644 index 9dac7e6..0000000 --- a/src/core/RTDCmptViewer.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#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/core/RTDCmptsView.cpp b/src/core/RTDCmptsView.cpp new file mode 100644 index 0000000..c023983 --- /dev/null +++ b/src/core/RTDCmptsView.cpp @@ -0,0 +1,30 @@ +#include + +#include + +using namespace Ubpa; +using namespace std; + +RTDCmptsView::CmptHandle::Mode RTDCmptsView::Iterator::GetMode() const { + auto type = *typeIter; + if (locator->LastFrameCmptTypes().find(type) != locator->LastFrameCmptTypes().end()) + return CmptHandle::Mode::LAST_FRAME; + else if (locator->WriteCmptTypes().find(type) != locator->WriteCmptTypes().end()) + return CmptHandle::Mode::WRITE; + else if (locator->LatestCmptTypes().find(type) != locator->LatestCmptTypes().end()) + return CmptHandle::Mode::LATEST; + else + return CmptHandle::Mode::INVALID; +} + +RTDCmptsView::Iterator RTDCmptsView::begin() const noexcept { + return { locator, locator->CmptTypes().begin(), cmpts }; +} + +RTDCmptsView::Iterator RTDCmptsView::end() const noexcept { + return { locator, locator->CmptTypes().end(), cmpts + locator->CmptTypes().size() }; +} + +const set& RTDCmptsView::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 a53c723..ec69bbe 100644 --- a/src/test/11_runtime_cmpt/main.cpp +++ b/src/test/11_runtime_cmpt/main.cpp @@ -19,19 +19,19 @@ struct RTDSystem { ); schedule .Register( - [](RTDCmptViewer cmpts) { - for (auto cmptptr : cmpts) { - if (cmptptr.Type() == CmptType{ "LuaCmpt" }) { - double& val = *reinterpret_cast(cmptptr.Ptr()); + [](RTDCmptsView cmpts) { + for (auto handle : cmpts) { + if (handle.GetCmptType() == CmptType{ "LuaCmpt" }) { + double& val = *reinterpret_cast(handle.AsWrite().Ptr()); val = 520.; } } }, "write", locator_write) .Register( - [](RTDCmptViewer cmpts) { - for (auto cmptptr : cmpts) { - if (cmptptr.Type() == CmptType{ "LuaCmpt" }) { - double& val = *reinterpret_cast(cmptptr.Ptr()); + [](RTDCmptsView cmpts) { + for (auto handle : cmpts) { + if (handle.GetCmptType() == CmptType{ "LuaCmpt" }) { + const double& val = *reinterpret_cast(handle.AsLatest().Ptr()); cout << "value : " << val << endl; } }