diff options
| author | untodesu <kirill@untode.su> | 2025-03-15 16:22:09 +0500 |
|---|---|---|
| committer | untodesu <kirill@untode.su> | 2025-03-15 16:22:09 +0500 |
| commit | 3bf42c6ff3805a0d42bbc661794a95ff31bedc26 (patch) | |
| tree | 05049955847504808d6bed2bb7b155f8b03807bb /deps/include/entt/entity/runtime_view.hpp | |
| parent | 02294547dcde0d4ad76e229106702261e9f10a51 (diff) | |
| download | voxelius-3bf42c6ff3805a0d42bbc661794a95ff31bedc26.tar.bz2 voxelius-3bf42c6ff3805a0d42bbc661794a95ff31bedc26.zip | |
Add whatever I was working on for the last month
Diffstat (limited to 'deps/include/entt/entity/runtime_view.hpp')
| -rw-r--r-- | deps/include/entt/entity/runtime_view.hpp | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/deps/include/entt/entity/runtime_view.hpp b/deps/include/entt/entity/runtime_view.hpp new file mode 100644 index 0000000..b300160 --- /dev/null +++ b/deps/include/entt/entity/runtime_view.hpp @@ -0,0 +1,318 @@ +#ifndef ENTT_ENTITY_RUNTIME_VIEW_HPP
+#define ENTT_ENTITY_RUNTIME_VIEW_HPP
+
+#include <algorithm>
+#include <cstddef>
+#include <iterator>
+#include <utility>
+#include <vector>
+#include "entity.hpp"
+#include "fwd.hpp"
+
+namespace entt {
+
+/*! @cond TURN_OFF_DOXYGEN */
+namespace internal {
+
+template<typename Set>
+class runtime_view_iterator final {
+ using iterator_type = typename Set::iterator;
+ using iterator_traits = std::iterator_traits<iterator_type>;
+
+ [[nodiscard]] bool valid() const {
+ return (!tombstone_check || *it != tombstone)
+ && std::all_of(++pools->begin(), pools->end(), [entt = *it](const auto *curr) { return curr->contains(entt); })
+ && std::none_of(filter->cbegin(), filter->cend(), [entt = *it](const auto *curr) { return curr && curr->contains(entt); });
+ }
+
+public:
+ using value_type = typename iterator_traits::value_type;
+ using pointer = typename iterator_traits::pointer;
+ using reference = typename iterator_traits::reference;
+ using difference_type = typename iterator_traits::difference_type;
+ using iterator_category = std::bidirectional_iterator_tag;
+
+ constexpr runtime_view_iterator() noexcept
+ : pools{},
+ filter{},
+ it{},
+ tombstone_check{} {}
+
+ // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
+ runtime_view_iterator(const std::vector<Set *> &cpools, const std::vector<Set *> &ignore, iterator_type curr) noexcept
+ : pools{&cpools},
+ filter{&ignore},
+ it{curr},
+ tombstone_check{pools->size() == 1u && (*pools)[0u]->policy() == deletion_policy::in_place} {
+ if(it != (*pools)[0]->end() && !valid()) {
+ ++(*this);
+ }
+ }
+
+ runtime_view_iterator &operator++() {
+ ++it;
+ for(const auto last = (*pools)[0]->end(); it != last && !valid(); ++it) {}
+ return *this;
+ }
+
+ runtime_view_iterator operator++(int) {
+ runtime_view_iterator orig = *this;
+ return ++(*this), orig;
+ }
+
+ runtime_view_iterator &operator--() {
+ --it;
+ for(const auto first = (*pools)[0]->begin(); it != first && !valid(); --it) {}
+ return *this;
+ }
+
+ runtime_view_iterator operator--(int) {
+ runtime_view_iterator orig = *this;
+ return operator--(), orig;
+ }
+
+ [[nodiscard]] pointer operator->() const noexcept {
+ return it.operator->();
+ }
+
+ [[nodiscard]] reference operator*() const noexcept {
+ return *operator->();
+ }
+
+ [[nodiscard]] constexpr bool operator==(const runtime_view_iterator &other) const noexcept {
+ return it == other.it;
+ }
+
+ [[nodiscard]] constexpr bool operator!=(const runtime_view_iterator &other) const noexcept {
+ return !(*this == other);
+ }
+
+private:
+ const std::vector<Set *> *pools;
+ const std::vector<Set *> *filter;
+ iterator_type it;
+ bool tombstone_check;
+};
+
+} // namespace internal
+/*! @endcond */
+
+/**
+ * @brief Generic runtime view.
+ *
+ * Runtime views iterate over those entities that are at least in the given
+ * storage. During initialization, a runtime view looks at the number of
+ * entities available for each element and uses the smallest set in order to get
+ * a performance boost when iterating.
+ *
+ * @b Important
+ *
+ * Iterators aren't invalidated if:
+ *
+ * * New elements are added to the storage.
+ * * The entity currently pointed is modified (for example, elements are added
+ * or removed from it).
+ * * The entity currently pointed is destroyed.
+ *
+ * In all other cases, modifying the storage iterated by the view in any way
+ * invalidates all the iterators.
+ *
+ * @tparam Type Common base type.
+ * @tparam Allocator Type of allocator used to manage memory and elements.
+ */
+template<typename Type, typename Allocator>
+class basic_runtime_view {
+ using alloc_traits = std::allocator_traits<Allocator>;
+ static_assert(std::is_same_v<typename alloc_traits::value_type, Type *>, "Invalid value type");
+ using container_type = std::vector<Type *, Allocator>;
+
+public:
+ /*! @brief Allocator type. */
+ using allocator_type = Allocator;
+ /*! @brief Underlying entity identifier. */
+ using entity_type = typename Type::entity_type;
+ /*! @brief Unsigned integer type. */
+ using size_type = std::size_t;
+ /*! @brief Common type among all storage types. */
+ using common_type = Type;
+ /*! @brief Bidirectional iterator type. */
+ using iterator = internal::runtime_view_iterator<common_type>;
+
+ /*! @brief Default constructor to use to create empty, invalid views. */
+ basic_runtime_view() noexcept
+ : basic_runtime_view{allocator_type{}} {}
+
+ /**
+ * @brief Constructs an empty, invalid view with a given allocator.
+ * @param allocator The allocator to use.
+ */
+ explicit basic_runtime_view(const allocator_type &allocator)
+ : pools{allocator},
+ filter{allocator} {}
+
+ /*! @brief Default copy constructor. */
+ basic_runtime_view(const basic_runtime_view &) = default;
+
+ /**
+ * @brief Allocator-extended copy constructor.
+ * @param other The instance to copy from.
+ * @param allocator The allocator to use.
+ */
+ basic_runtime_view(const basic_runtime_view &other, const allocator_type &allocator)
+ : pools{other.pools, allocator},
+ filter{other.filter, allocator} {}
+
+ /*! @brief Default move constructor. */
+ basic_runtime_view(basic_runtime_view &&) noexcept(std::is_nothrow_move_constructible_v<container_type>) = default;
+
+ /**
+ * @brief Allocator-extended move constructor.
+ * @param other The instance to move from.
+ * @param allocator The allocator to use.
+ */
+ basic_runtime_view(basic_runtime_view &&other, const allocator_type &allocator)
+ : pools{std::move(other.pools), allocator},
+ filter{std::move(other.filter), allocator} {}
+
+ /*! @brief Default destructor. */
+ ~basic_runtime_view() noexcept = default;
+
+ /**
+ * @brief Default copy assignment operator.
+ * @return This runtime view.
+ */
+ basic_runtime_view &operator=(const basic_runtime_view &) = default;
+
+ /**
+ * @brief Default move assignment operator.
+ * @return This runtime view.
+ */
+ basic_runtime_view &operator=(basic_runtime_view &&) noexcept(std::is_nothrow_move_assignable_v<container_type>) = default;
+
+ /**
+ * @brief Exchanges the contents with those of a given view.
+ * @param other View to exchange the content with.
+ */
+ void swap(basic_runtime_view &other) {
+ using std::swap;
+ swap(pools, other.pools);
+ swap(filter, other.filter);
+ }
+
+ /**
+ * @brief Returns the associated allocator.
+ * @return The associated allocator.
+ */
+ [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
+ return pools.get_allocator();
+ }
+
+ /*! @brief Clears the view. */
+ void clear() {
+ pools.clear();
+ filter.clear();
+ }
+
+ /**
+ * @brief Appends an opaque storage object to a runtime view.
+ * @param base An opaque reference to a storage object.
+ * @return This runtime view.
+ */
+ basic_runtime_view &iterate(common_type &base) {
+ if(pools.empty() || !(base.size() < pools[0u]->size())) {
+ pools.push_back(&base);
+ } else {
+ pools.push_back(std::exchange(pools[0u], &base));
+ }
+
+ return *this;
+ }
+
+ /**
+ * @brief Adds an opaque storage object as a filter of a runtime view.
+ * @param base An opaque reference to a storage object.
+ * @return This runtime view.
+ */
+ basic_runtime_view &exclude(common_type &base) {
+ filter.push_back(&base);
+ return *this;
+ }
+
+ /**
+ * @brief Estimates the number of entities iterated by the view.
+ * @return Estimated number of entities iterated by the view.
+ */
+ [[nodiscard]] size_type size_hint() const {
+ return pools.empty() ? size_type{} : pools.front()->size();
+ }
+
+ /**
+ * @brief Returns an iterator to the first entity that has the given
+ * elements.
+ *
+ * If the view is empty, the returned iterator will be equal to `end()`.
+ *
+ * @return An iterator to the first entity that has the given elements.
+ */
+ [[nodiscard]] iterator begin() const {
+ return pools.empty() ? iterator{} : iterator{pools, filter, pools[0]->begin()};
+ }
+
+ /**
+ * @brief Returns an iterator that is past the last entity that has the
+ * given elements.
+ * @return An iterator to the entity following the last entity that has the
+ * given elements.
+ */
+ [[nodiscard]] iterator end() const {
+ return pools.empty() ? iterator{} : iterator{pools, filter, pools[0]->end()};
+ }
+
+ /**
+ * @brief Checks whether a view is initialized or not.
+ * @return True if the view is initialized, false otherwise.
+ */
+ [[nodiscard]] explicit operator bool() const noexcept {
+ return !(pools.empty() && filter.empty());
+ }
+
+ /**
+ * @brief Checks if a view contains an entity.
+ * @param entt A valid identifier.
+ * @return True if the view contains the given entity, false otherwise.
+ */
+ [[nodiscard]] bool contains(const entity_type entt) const {
+ return !pools.empty()
+ && std::all_of(pools.cbegin(), pools.cend(), [entt](const auto *curr) { return curr->contains(entt); })
+ && std::none_of(filter.cbegin(), filter.cend(), [entt](const auto *curr) { return curr && curr->contains(entt); });
+ }
+
+ /**
+ * @brief Iterates entities and applies the given function object to them.
+ *
+ * The function object is invoked for each entity. It is provided only with
+ * the entity itself.<br/>
+ * The signature of the function should be equivalent to the following:
+ *
+ * @code{.cpp}
+ * void(const entity_type);
+ * @endcode
+ *
+ * @tparam Func Type of the function object to invoke.
+ * @param func A valid function object.
+ */
+ template<typename Func>
+ void each(Func func) const {
+ for(const auto entity: *this) {
+ func(entity);
+ }
+ }
+
+private:
+ container_type pools;
+ container_type filter;
+};
+
+} // namespace entt
+
+#endif
|
