sort owning groups by owned components
This commit is contained in:
@@ -1186,8 +1186,10 @@ the template parameter list and arranges their pools so as to iterate all of
|
||||
them as fast as possible.
|
||||
|
||||
Sorting owned components is no longer allowed once the group has been created.
|
||||
However, full-owning groups can be sorted by means of the `sort` member
|
||||
function, if required.
|
||||
However, full-owning groups can be sorted by means of their `sort` member
|
||||
functions, if required. Sorting a full-owning group affects all the instance of
|
||||
the same group (it means that users don't have to call `sort` on each instance
|
||||
to sort all of them because they share the underlying data structure).
|
||||
|
||||
### Partial-owning groups
|
||||
|
||||
@@ -1215,8 +1217,10 @@ them as fast as possible. The ownership of the types provided via `entt::get`
|
||||
doesn't pass to the group instead.
|
||||
|
||||
Sorting owned components is no longer allowed once the group has been created.
|
||||
However, partial-owning groups can be sorted by means of the `sort` member
|
||||
function, if required.
|
||||
However, partial-owning groups can be sorted by means of their `sort` member
|
||||
functions, if required. Sorting a partial-owning group affects all the instance
|
||||
of the same group (it means that users don't have to call `sort` on each
|
||||
instance to sort all of them because they share the underlying data structure).
|
||||
|
||||
### Non-owning groups
|
||||
|
||||
@@ -1242,8 +1246,10 @@ case. This type of groups is therefore the least performing in general, but also
|
||||
the only one that can be used in any situation to improve a performance where
|
||||
necessary.
|
||||
|
||||
Non-owning groups can be sorted by means of the `sort` member function, if
|
||||
required.
|
||||
Non-owning groups can be sorted by means of their `sort` member functions, if
|
||||
required. Sorting a non-owning group affects all the instance of the same group
|
||||
(it means that users don't have to call `sort` on each instance to sort all of
|
||||
them because they share the set of entities).
|
||||
|
||||
# Types: const, non-const and all in between
|
||||
|
||||
|
||||
@@ -395,6 +395,9 @@ private:
|
||||
* that generated them. Therefore any change to the entities and to the
|
||||
* components made by means of the registry are immediately reflected by all the
|
||||
* groups.
|
||||
* Moreover, sorting an owning group affects all the instance of the same group
|
||||
* (it means that users don't have to call `sort` on each instance to sort all
|
||||
* of them because they share the underlying data structure).
|
||||
*
|
||||
* @warning
|
||||
* Lifetime of a group must overcome the one of the registry that generated it.
|
||||
@@ -675,9 +678,10 @@ public:
|
||||
*
|
||||
* 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 the following:
|
||||
* comparison function should be equivalent to one of the following:
|
||||
*
|
||||
* @code{.cpp}
|
||||
* bool(const Owned &..., const Owned &...);
|
||||
* bool(const Entity, const Entity);
|
||||
* @endcode
|
||||
*
|
||||
@@ -712,9 +716,15 @@ public:
|
||||
std::vector<size_type> copy(*length);
|
||||
std::iota(copy.begin(), copy.end(), 0);
|
||||
|
||||
algo(copy.rbegin(), copy.rend(), [compare = std::move(compare), data = data()](const auto lhs, const auto rhs) {
|
||||
return compare(data[lhs], data[rhs]);
|
||||
}, std::forward<Args>(args)...);
|
||||
if constexpr(std::is_invocable_v<Compare, const Owned &..., const Owned &...>) {
|
||||
algo(copy.rbegin(), copy.rend(), [compare = std::move(compare), raw = std::make_tuple(std::get<pool_type<Owned> *>(pools)->raw()...)](const auto lhs, const auto rhs) {
|
||||
return compare(std::as_const(std::get<Owned *>(raw)[lhs])..., std::as_const(std::get<Owned *>(raw)[rhs])...);
|
||||
}, std::forward<Args>(args)...);
|
||||
} else {
|
||||
algo(copy.rbegin(), copy.rend(), [compare = std::move(compare), data = data()](const auto lhs, const auto rhs) {
|
||||
return compare(data[lhs], data[rhs]);
|
||||
}, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
for(size_type pos = 0, last = copy.size(); pos < last; ++pos) {
|
||||
auto curr = pos;
|
||||
|
||||
@@ -641,7 +641,7 @@ TEST(OwningGroup, SortReverse) {
|
||||
|
||||
TEST(OwningGroup, SortUnordered) {
|
||||
entt::registry registry;
|
||||
auto group = registry.group<boxed_int, char>();
|
||||
auto group = registry.group<boxed_int>(entt::get<char>);
|
||||
|
||||
entt::entity entities[7] = {
|
||||
registry.create(),
|
||||
@@ -671,8 +671,8 @@ TEST(OwningGroup, SortUnordered) {
|
||||
registry.assign<boxed_int>(entities[5], 4);
|
||||
registry.assign<boxed_int>(entities[6], 5);
|
||||
|
||||
group.sort([&group](const auto lhs, const auto rhs) {
|
||||
return group.get<boxed_int>(lhs).value < group.get<boxed_int>(rhs).value;
|
||||
group.sort([](const auto &lhs, const auto &rhs) {
|
||||
return lhs.value < rhs.value;
|
||||
});
|
||||
|
||||
ASSERT_EQ(*(group.data() + 0u), entities[4]);
|
||||
@@ -691,11 +691,11 @@ TEST(OwningGroup, SortUnordered) {
|
||||
ASSERT_EQ((group.raw<boxed_int>() + 5u)->value, 4);
|
||||
ASSERT_EQ((group.raw<boxed_int>() + 6u)->value, 5);
|
||||
|
||||
ASSERT_EQ(*(group.raw<char>() + 0u), 'e');
|
||||
ASSERT_EQ(*(group.raw<char>() + 1u), 'd');
|
||||
ASSERT_EQ(*(group.raw<char>() + 2u), 'a');
|
||||
ASSERT_EQ(*(group.raw<char>() + 3u), 'b');
|
||||
ASSERT_EQ(*(group.raw<char>() + 4u), 'c');
|
||||
ASSERT_EQ(*(group.raw<char>() + 0u), 'a');
|
||||
ASSERT_EQ(*(group.raw<char>() + 1u), 'b');
|
||||
ASSERT_EQ(*(group.raw<char>() + 2u), 'c');
|
||||
ASSERT_EQ(*(group.raw<char>() + 3u), 'd');
|
||||
ASSERT_EQ(*(group.raw<char>() + 4u), 'e');
|
||||
}
|
||||
|
||||
TEST(OwningGroup, IndexRebuiltOnDestroy) {
|
||||
|
||||
Reference in New Issue
Block a user