|
|
@@ -46,7 +46,6 @@ class basic_registry {
|
|
|
template<typename Component>
|
|
|
struct pool_handler final: storage<Entity, Component> {
|
|
|
static_assert(std::is_same_v<Component, std::decay_t<Component>>, "Invalid component type");
|
|
|
- std::size_t super{};
|
|
|
|
|
|
[[nodiscard]] auto on_construct() ENTT_NOEXCEPT {
|
|
|
return sink{construction};
|
|
|
@@ -1161,101 +1160,6 @@ public:
|
|
|
return assure<Component>().on_destroy();
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * @brief Sorts the pool of entities for the given component.
|
|
|
- *
|
|
|
- * The order of the elements in a pool is highly affected by assignments
|
|
|
- * of components to entities and deletions. Components are arranged to
|
|
|
- * maximize the performance during iterations and users should not make any
|
|
|
- * assumption on the order.<br/>
|
|
|
- * This function can be used to impose an order to the elements in the pool
|
|
|
- * of the given component. The order is kept valid until a component of the
|
|
|
- * given type is assigned or removed from an entity.
|
|
|
- *
|
|
|
- * The comparison function object must return `true` if the first element
|
|
|
- * is _less_ than the second one, `false` otherwise. The signature of the
|
|
|
- * comparison function should be equivalent to one of the following:
|
|
|
- *
|
|
|
- * @code{.cpp}
|
|
|
- * bool(const Entity, const Entity);
|
|
|
- * bool(const Component &, const Component &);
|
|
|
- * @endcode
|
|
|
- *
|
|
|
- * Moreover, the comparison function object shall induce a
|
|
|
- * _strict weak ordering_ on the values.
|
|
|
- *
|
|
|
- * The sort function oject must offer a member function template
|
|
|
- * `operator()` that accepts three arguments:
|
|
|
- *
|
|
|
- * * An iterator to the first element of the range to sort.
|
|
|
- * * An iterator past the last element of the range to sort.
|
|
|
- * * A comparison function to use to compare the elements.
|
|
|
- *
|
|
|
- * The comparison funtion object received by the sort function object hasn't
|
|
|
- * necessarily the type of the one passed along with the other parameters to
|
|
|
- * this member function.
|
|
|
- *
|
|
|
- * @warning
|
|
|
- * Pools of components owned by a group cannot be sorted.<br/>
|
|
|
- * An assertion will abort the execution at runtime in debug mode in case
|
|
|
- * the pool is owned by a group.
|
|
|
- *
|
|
|
- * @tparam Component Type of components to sort.
|
|
|
- * @tparam Compare Type of comparison function object.
|
|
|
- * @tparam Sort Type of sort function object.
|
|
|
- * @tparam Args Types of arguments to forward to the sort function object.
|
|
|
- * @param compare A valid comparison function object.
|
|
|
- * @param algo A valid sort function object.
|
|
|
- * @param args Arguments to forward to the sort function object, if any.
|
|
|
- */
|
|
|
- template<typename Component, typename Compare, typename Sort = std_sort, typename... Args>
|
|
|
- void sort(Compare compare, Sort algo = Sort{}, Args &&... args) {
|
|
|
- ENTT_ASSERT(sortable<Component>());
|
|
|
- auto &cpool = assure<Component>();
|
|
|
- cpool.sort(cpool.begin(), cpool.end(), std::move(compare), std::move(algo), std::forward<Args>(args)...);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * @brief Sorts two pools of components in the same way.
|
|
|
- *
|
|
|
- * The order of the elements in a pool is highly affected by assignments
|
|
|
- * of components to entities and deletions. Components are arranged to
|
|
|
- * maximize the performance during iterations and users should not make any
|
|
|
- * assumption on the order.
|
|
|
- *
|
|
|
- * It happens that different pools of components must be sorted the same way
|
|
|
- * because of runtime and/or performance constraints. This function can be
|
|
|
- * used to order a pool of components according to the order between the
|
|
|
- * entities in another pool of components.
|
|
|
- *
|
|
|
- * @b How @b it @b works
|
|
|
- *
|
|
|
- * Being `A` and `B` the two sets where `B` is the master (the one the order
|
|
|
- * of which rules) and `A` is the slave (the one to sort), after a call to
|
|
|
- * this function an iterator for `A` will return the entities according to
|
|
|
- * the following rules:
|
|
|
- *
|
|
|
- * * All the entities in `A` that are also in `B` are returned first
|
|
|
- * according to the order they have in `B`.
|
|
|
- * * All the entities in `A` that are not in `B` are returned in no
|
|
|
- * particular order after all the other entities.
|
|
|
- *
|
|
|
- * Any subsequent change to `B` won't affect the order in `A`.
|
|
|
- *
|
|
|
- * @warning
|
|
|
- * Pools of components owned by a group cannot be sorted.<br/>
|
|
|
- * An assertion will abort the execution at runtime in debug mode in case
|
|
|
- * the pool is owned by a group.
|
|
|
- *
|
|
|
- * @tparam To Type of components to sort.
|
|
|
- * @tparam From Type of components to use to sort.
|
|
|
- */
|
|
|
- template<typename To, typename From>
|
|
|
- void sort() {
|
|
|
- ENTT_ASSERT(sortable<To>());
|
|
|
- assure<To>().respect(assure<From>());
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* @brief Returns a view for the given components.
|
|
|
*
|
|
|
@@ -1302,14 +1206,35 @@ public:
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Checks whether the given components belong to any group.
|
|
|
- * @tparam Component Types of components in which one is interested.
|
|
|
- * @return True if the pools of the given components are sortable, false
|
|
|
- * otherwise.
|
|
|
+ * @brief Returns a runtime view for the given components.
|
|
|
+ *
|
|
|
+ * This kind of objects are created on the fly and share with the registry
|
|
|
+ * its internal data structures.<br/>
|
|
|
+ * Users should throw away the view after use. Fortunately, creating and
|
|
|
+ * destroying a runtime view is an incredibly cheap operation because they
|
|
|
+ * do not require any type of initialization.<br/>
|
|
|
+ * As a rule of thumb, storing a view should never be an option.
|
|
|
+ *
|
|
|
+ * Runtime views are to be used when users want to construct a view from
|
|
|
+ * some external inputs and don't know at compile-time what are the required
|
|
|
+ * components.<br/>
|
|
|
+ * This is particularly well suited to plugin systems and mods in general.
|
|
|
+ *
|
|
|
+ * @tparam It Type of input iterator.
|
|
|
+ * @param first An iterator to the first element of the range of components.
|
|
|
+ * @param last An iterator past the last element of the range of components.
|
|
|
+ * @return A newly created runtime view.
|
|
|
*/
|
|
|
- template<typename... Component>
|
|
|
- [[nodiscard]] bool sortable() const {
|
|
|
- return std::none_of(groups.cbegin(), groups.cend(), [](auto &&gdata) { return (gdata.owned(type_info<std::decay_t<Component>>::id()) || ...); });
|
|
|
+ template<typename It>
|
|
|
+ [[nodiscard]] entt::basic_runtime_view<Entity> runtime_view(It first, It last) const {
|
|
|
+ std::vector<const sparse_set<Entity> *> selected(std::distance(first, last));
|
|
|
+
|
|
|
+ std::transform(first, last, selected.begin(), [this](const auto ctype) {
|
|
|
+ const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&pdata) { return pdata.pool && pdata.type_id == ctype; });
|
|
|
+ return it == pools.cend() ? nullptr : it->pool.get();
|
|
|
+ });
|
|
|
+
|
|
|
+ return { std::move(selected) };
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1384,7 +1309,7 @@ public:
|
|
|
}));
|
|
|
|
|
|
const auto next = std::find_if_not(groups.cbegin(), groups.cend(), [size](const auto &gdata) {
|
|
|
- return !(0u + ... + gdata.owned(type_info<std::decay_t<Owned>>::id())) || (size > (gdata.size));
|
|
|
+ return !(0u + ... + gdata.owned(type_info<std::decay_t<Owned>>::id())) || (size > gdata.size);
|
|
|
});
|
|
|
|
|
|
const auto prev = std::find_if(std::make_reverse_iterator(next), groups.crend(), [](const auto &gdata) {
|
|
|
@@ -1396,8 +1321,6 @@ public:
|
|
|
groups.insert(next, std::move(candidate));
|
|
|
}
|
|
|
|
|
|
- ((std::get<pool_handler<std::decay_t<Owned>> &>(cpools).super = std::max(std::get<pool_handler<std::decay_t<Owned>> &>(cpools).super, size)), ...);
|
|
|
-
|
|
|
(on_construct<std::decay_t<Owned>>().before(maybe_valid_if).template connect<&handler_type::template maybe_valid_if<std::decay_t<Owned>>>(*handler), ...);
|
|
|
(on_construct<std::decay_t<Get>>().before(maybe_valid_if).template connect<&handler_type::template maybe_valid_if<std::decay_t<Get>>>(*handler), ...);
|
|
|
(on_destroy<Exclude>().before(maybe_valid_if).template connect<&handler_type::template maybe_valid_if<Exclude>>(*handler), ...);
|
|
|
@@ -1421,7 +1344,7 @@ public:
|
|
|
if constexpr(sizeof...(Owned) == 0) {
|
|
|
return { handler->current, std::get<pool_handler<std::decay_t<Get>> &>(cpools)... };
|
|
|
} else {
|
|
|
- return { std::get<0>(cpools).super, handler->current, std::get<pool_handler<std::decay_t<Owned>> &>(cpools)... , std::get<pool_handler<std::decay_t<Get>> &>(cpools)... };
|
|
|
+ return { handler->current, std::get<pool_handler<std::decay_t<Owned>> &>(cpools)... , std::get<pool_handler<std::decay_t<Get>> &>(cpools)... };
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -1471,35 +1394,124 @@ public:
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Returns a runtime view for the given components.
|
|
|
+ * @brief Checks whether the given components belong to any group.
|
|
|
+ * @tparam Component Types of components in which one is interested.
|
|
|
+ * @return True if the pools of the given components are sortable, false
|
|
|
+ * otherwise.
|
|
|
+ */
|
|
|
+ template<typename... Component>
|
|
|
+ [[nodiscard]] bool sortable() const {
|
|
|
+ return std::none_of(groups.cbegin(), groups.cend(), [](auto &&gdata) { return (gdata.owned(type_info<std::decay_t<Component>>::id()) || ...); });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Checks whether a group can be sorted.
|
|
|
+ * @tparam Owned Types of components owned by the group.
|
|
|
+ * @tparam Get Types of components observed by the group.
|
|
|
+ * @tparam Exclude Types of components used to filter the group.
|
|
|
+ * @return True if the group can be sorted, false otherwise.
|
|
|
+ */
|
|
|
+ template<typename... Owned, typename... Get, typename... Exclude>
|
|
|
+ [[nodiscard]] bool sortable(const entt::basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>, Owned...> &) ENTT_NOEXCEPT {
|
|
|
+ constexpr auto size = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude);
|
|
|
+ return std::find_if(groups.cbegin(), groups.cend(), [size](const auto &gdata) {
|
|
|
+ return (0u + ... + gdata.owned(type_info<std::decay_t<Owned>>::id())) && (size < gdata.size);
|
|
|
+ }) == groups.cend();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Sorts the pool of entities for the given component.
|
|
|
*
|
|
|
- * This kind of objects are created on the fly and share with the registry
|
|
|
- * its internal data structures.<br/>
|
|
|
- * Users should throw away the view after use. Fortunately, creating and
|
|
|
- * destroying a runtime view is an incredibly cheap operation because they
|
|
|
- * do not require any type of initialization.<br/>
|
|
|
- * As a rule of thumb, storing a view should never be an option.
|
|
|
+ * The order of the elements in a pool is highly affected by assignments
|
|
|
+ * of components to entities and deletions. Components are arranged to
|
|
|
+ * maximize the performance during iterations and users should not make any
|
|
|
+ * assumption on the order.<br/>
|
|
|
+ * This function can be used to impose an order to the elements in the pool
|
|
|
+ * of the given component. The order is kept valid until a component of the
|
|
|
+ * given type is assigned or removed from an entity.
|
|
|
*
|
|
|
- * Runtime views are to be used when users want to construct a view from
|
|
|
- * some external inputs and don't know at compile-time what are the required
|
|
|
- * components.<br/>
|
|
|
- * This is particularly well suited to plugin systems and mods in general.
|
|
|
+ * The comparison function object must return `true` if the first element
|
|
|
+ * is _less_ than the second one, `false` otherwise. The signature of the
|
|
|
+ * comparison function should be equivalent to one of the following:
|
|
|
*
|
|
|
- * @tparam It Type of input iterator.
|
|
|
- * @param first An iterator to the first element of the range of components.
|
|
|
- * @param last An iterator past the last element of the range of components.
|
|
|
- * @return A newly created runtime view.
|
|
|
+ * @code{.cpp}
|
|
|
+ * bool(const Entity, const Entity);
|
|
|
+ * bool(const Component &, const Component &);
|
|
|
+ * @endcode
|
|
|
+ *
|
|
|
+ * Moreover, the comparison function object shall induce a
|
|
|
+ * _strict weak ordering_ on the values.
|
|
|
+ *
|
|
|
+ * The sort function oject must offer a member function template
|
|
|
+ * `operator()` that accepts three arguments:
|
|
|
+ *
|
|
|
+ * * An iterator to the first element of the range to sort.
|
|
|
+ * * An iterator past the last element of the range to sort.
|
|
|
+ * * A comparison function to use to compare the elements.
|
|
|
+ *
|
|
|
+ * The comparison funtion object received by the sort function object hasn't
|
|
|
+ * necessarily the type of the one passed along with the other parameters to
|
|
|
+ * this member function.
|
|
|
+ *
|
|
|
+ * @warning
|
|
|
+ * Pools of components owned by a group cannot be sorted.<br/>
|
|
|
+ * An assertion will abort the execution at runtime in debug mode in case
|
|
|
+ * the pool is owned by a group.
|
|
|
+ *
|
|
|
+ * @tparam Component Type of components to sort.
|
|
|
+ * @tparam Compare Type of comparison function object.
|
|
|
+ * @tparam Sort Type of sort function object.
|
|
|
+ * @tparam Args Types of arguments to forward to the sort function object.
|
|
|
+ * @param compare A valid comparison function object.
|
|
|
+ * @param algo A valid sort function object.
|
|
|
+ * @param args Arguments to forward to the sort function object, if any.
|
|
|
*/
|
|
|
- template<typename It>
|
|
|
- [[nodiscard]] entt::basic_runtime_view<Entity> runtime_view(It first, It last) const {
|
|
|
- std::vector<const sparse_set<Entity> *> selected(std::distance(first, last));
|
|
|
-
|
|
|
- std::transform(first, last, selected.begin(), [this](const auto ctype) {
|
|
|
- const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&pdata) { return pdata.pool && pdata.type_id == ctype; });
|
|
|
- return it == pools.cend() ? nullptr : it->pool.get();
|
|
|
- });
|
|
|
+ template<typename Component, typename Compare, typename Sort = std_sort, typename... Args>
|
|
|
+ void sort(Compare compare, Sort algo = Sort{}, Args &&... args) {
|
|
|
+ ENTT_ASSERT(sortable<Component>());
|
|
|
+ auto &cpool = assure<Component>();
|
|
|
+ cpool.sort(cpool.begin(), cpool.end(), std::move(compare), std::move(algo), std::forward<Args>(args)...);
|
|
|
+ }
|
|
|
|
|
|
- return { std::move(selected) };
|
|
|
+ /**
|
|
|
+ * @brief Sorts two pools of components in the same way.
|
|
|
+ *
|
|
|
+ * The order of the elements in a pool is highly affected by assignments
|
|
|
+ * of components to entities and deletions. Components are arranged to
|
|
|
+ * maximize the performance during iterations and users should not make any
|
|
|
+ * assumption on the order.
|
|
|
+ *
|
|
|
+ * It happens that different pools of components must be sorted the same way
|
|
|
+ * because of runtime and/or performance constraints. This function can be
|
|
|
+ * used to order a pool of components according to the order between the
|
|
|
+ * entities in another pool of components.
|
|
|
+ *
|
|
|
+ * @b How @b it @b works
|
|
|
+ *
|
|
|
+ * Being `A` and `B` the two sets where `B` is the master (the one the order
|
|
|
+ * of which rules) and `A` is the slave (the one to sort), after a call to
|
|
|
+ * this function an iterator for `A` will return the entities according to
|
|
|
+ * the following rules:
|
|
|
+ *
|
|
|
+ * * All the entities in `A` that are also in `B` are returned first
|
|
|
+ * according to the order they have in `B`.
|
|
|
+ * * All the entities in `A` that are not in `B` are returned in no
|
|
|
+ * particular order after all the other entities.
|
|
|
+ *
|
|
|
+ * Any subsequent change to `B` won't affect the order in `A`.
|
|
|
+ *
|
|
|
+ * @warning
|
|
|
+ * Pools of components owned by a group cannot be sorted.<br/>
|
|
|
+ * An assertion will abort the execution at runtime in debug mode in case
|
|
|
+ * the pool is owned by a group.
|
|
|
+ *
|
|
|
+ * @tparam To Type of components to sort.
|
|
|
+ * @tparam From Type of components to use to sort.
|
|
|
+ */
|
|
|
+ template<typename To, typename From>
|
|
|
+ void sort() {
|
|
|
+ ENTT_ASSERT(sortable<To>());
|
|
|
+ assure<To>().respect(assure<From>());
|
|
|
}
|
|
|
|
|
|
/**
|