Преглед изворни кода

fix: sorting empty types (close #365)

Michele Caini пре 6 година
родитељ
комит
86c524dade
3 измењених фајлова са 42 додато и 1 уклоњено
  1. 9 1
      docs/md/entity.md
  2. 17 0
      src/entt/entity/storage.hpp
  3. 16 0
      test/entt/entity/registry.cpp

+ 9 - 1
docs/md/entity.md

@@ -1672,7 +1672,15 @@ only the entities to which it's assigned are made available. All the iterators
 as well as the `get` member functions of the registry, the views and the groups
 will return temporary objects. Similarly, some functions such as `try_get` or
 the raw access to the list of components aren't available for this kind of
-types.<br/>
+types. Finally, the `sort` functionality accepts only callbacks that require to
+return entities rather than components:
+
+```cpp
+registry.sort<empty_type>([](const entt::entity lhs, const entt::entity rhs) {
+    return entt::registry::entity(lhs) < entt::registry::entity(rhs);
+});
+```
+
 On the other hand, iterations are faster because only the entities to which the
 type is assigned are considered. Moreover, less memory is used, since there
 doesn't exist any instance of the component, no matter how many entities it is

+ 17 - 0
src/entt/entity/storage.hpp

@@ -431,6 +431,11 @@ public:
      * either `data` or `raw` gives no guarantees on the order, even though
      * `sort` has been invoked.
      *
+     * @warning
+     * Empty types are never instantiated. Therefore, only comparison function
+     * objects that require to return entities rather than components are
+     * accepted.
+     *
      * @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.
@@ -673,6 +678,18 @@ public:
         underlying_type::batch(first, last);
         return begin();
     }
+
+    /*! @copydoc storage::sort */
+    template<typename Compare, typename Sort = std_sort, typename... Args>
+    void sort(iterator_type first, iterator_type last, Compare compare, Sort algo = Sort{}, Args &&... args) {
+        ENTT_ASSERT(!(last < first));
+        ENTT_ASSERT(!(last > end()));
+
+        const auto from = underlying_type::begin() + std::distance(begin(), first);
+        const auto to = from + std::distance(first, last);
+
+        underlying_type::sort(from, to, std::move(compare), std::move(algo), std::forward<Args>(args)...);
+    }
 };
 
 /*! @copydoc basic_storage */

+ 16 - 0
test/entt/entity/registry.cpp

@@ -825,6 +825,22 @@ TEST(Registry, SortMulti) {
     }
 }
 
+TEST(Registry, SortEmpty) {
+    entt::registry registry;
+
+    registry.assign<empty_type>(registry.create());
+    registry.assign<empty_type>(registry.create());
+    registry.assign<empty_type>(registry.create());
+
+    ASSERT_LT(registry.data<empty_type>()[0], registry.data<empty_type>()[1]);
+    ASSERT_LT(registry.data<empty_type>()[1], registry.data<empty_type>()[2]);
+
+    registry.sort<empty_type>(std::less<entt::entity>{});
+
+    ASSERT_GT(registry.data<empty_type>()[0], registry.data<empty_type>()[1]);
+    ASSERT_GT(registry.data<empty_type>()[1], registry.data<empty_type>()[2]);
+}
+
 TEST(Registry, ComponentsWithTypesFromStandardTemplateLibrary) {
     // see #37 - the test shouldn't crash, that's all
     entt::registry registry;