Explorar el Código

fix: sorting empty types (close #365)

Michele Caini hace 6 años
padre
commit
86c524dade
Se han modificado 3 ficheros con 42 adiciones y 1 borrados
  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
 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
 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
 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
 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
 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
 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
      * either `data` or `raw` gives no guarantees on the order, even though
      * `sort` has been invoked.
      * `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 Compare Type of comparison function object.
      * @tparam Sort Type of sort function object.
      * @tparam Sort Type of sort function object.
      * @tparam Args Types of arguments to forward to the 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);
         underlying_type::batch(first, last);
         return begin();
         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 */
 /*! @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) {
 TEST(Registry, ComponentsWithTypesFromStandardTemplateLibrary) {
     // see #37 - the test shouldn't crash, that's all
     // see #37 - the test shouldn't crash, that's all
     entt::registry registry;
     entt::registry registry;