Browse Source

registry/storage: ::insert supports all types of iterators

Michele Caini 6 years ago
parent
commit
709fd34264

+ 2 - 0
TODO

@@ -17,6 +17,8 @@
   - get -> all, exclude -> none
 
 Next:
+* registry::assure: open addressing or whatever to get rid of static variables and avoid reindexing in worst cases
+* meta, make it possible to reset nodes from meta types
 * replace observer class with observer functions
 * get(cmp, entity) -> void *, set(cmp, entity, void *)
 * review multi component views to reduce instantiations once empty types are gone...

+ 12 - 11
src/entt/entity/registry.hpp

@@ -71,9 +71,9 @@ class basic_registry {
             }
         }
 
-        template<typename It, typename Value>
-        void insert(basic_registry &owner, It first, It last, Value &&value) {
-            storage<entity_type, Component>::insert(first, last, std::forward<Value>(value));
+        template<typename It, typename... Args>
+        void insert(basic_registry &owner, It first, It last, Args &&... args) {
+            storage<entity_type, Component>::insert(first, last, std::forward<Args>(args)...);
 
             if(!construction.empty()) {
                 while(first != last) { construction.publish(owner, *(first++)); }
@@ -648,14 +648,14 @@ public:
      *
      * @sa emplace
      *
-     * @tparam It Type of input iterator.
      * @tparam Component Type of component to create.
+     * @tparam It Type of input iterator.
      * @param first An iterator to the first element of the range of entities.
      * @param last An iterator past the last element of the range of entities.
      * @param value An instance of the component to assign.
      */
-    template<typename It, typename Component>
-    void insert(It first, It last, const Component &value) {
+    template<typename Component, typename It>
+    void insert(It first, It last, const Component &value = {}) {
         ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }));
         assure<Component>().insert(*this, first, last, value);
     }
@@ -664,7 +664,7 @@ public:
     template<typename Component, typename It>
     [[deprecated("use ::insert instead")]]
     std::enable_if_t<std::is_same_v<typename std::iterator_traits<It>::value_type, entity_type>, void>
-    assign(It first, It last, const Component &value) {
+    assign(It first, It last, const Component &value = {}) {
         return insert(std::move(first), std::move(last), value);
     }
 
@@ -678,13 +678,14 @@ public:
      * @tparam CIt Type of input iterator.
      * @param first An iterator to the first element of the range of entities.
      * @param last An iterator past the last element of the range of entities.
-     * @param value An iterator to the first element of the range of components.
+     * @param from An iterator to the first element of the range of components.
+     * @param to An iterator past the last element of the range of components.
      */
     template<typename Component, typename EIt, typename CIt>
-    void insert(EIt first, EIt last, CIt value) {
+    void insert(EIt first, EIt last, CIt from, CIt to) {
         static_assert(std::is_constructible_v<Component, typename std::iterator_traits<CIt>::value_type>);
         ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }));
-        assure<Component>().insert(*this, first, last, value);
+        assure<Component>().insert(*this, first, last, from, to);
     }
 
     /*! @copydoc insert */
@@ -692,7 +693,7 @@ public:
     [[deprecated("use ::insert instead")]]
     std::enable_if_t<std::is_same_v<typename std::iterator_traits<EIt>::value_type, entity_type>, void>
     assign(EIt first, EIt last, CIt value) {
-        return insert<Component>(std::move(first), std::move(last), std::move(value));
+        return insert<Component>(std::move(first), std::move(last), value, value + std::distance(first, last));
     }
 
     /**

+ 8 - 7
src/entt/entity/storage.hpp

@@ -351,7 +351,7 @@ public:
      * @param value An instance of the object to construct.
      */
     template<typename It>
-    void insert(It first, It last, const object_type &value) {
+    void insert(It first, It last, const object_type &value = {}) {
         instances.insert(instances.end(), std::distance(first, last), value);
         // entities go after components in case constructors throw
         underlying_type::insert(first, last);
@@ -361,7 +361,7 @@ public:
     template<typename It>
     [[deprecated("use ::insert instead")]]
     std::enable_if_t<std::is_same_v<typename std::iterator_traits<It>::value_type, entity_type>, void>
-    construct(It first, It last, const object_type &value) {
+    construct(It first, It last, const object_type &value = {}) {
         insert(std::move(first), std::move(last), value);
     }
 
@@ -375,11 +375,12 @@ public:
      * @tparam CIt Type of input iterator.
      * @param first An iterator to the first element of the range of entities.
      * @param last An iterator past the last element of the range of entities.
-     * @param value An iterator to the first element of the range of objects.
+     * @param from An iterator to the first element of the range of objects.
+     * @param to An iterator past the last element of the range of objects.
      */
     template<typename EIt, typename CIt>
-    void insert(EIt first, EIt last, CIt value) {
-        instances.insert(instances.end(), value, value + std::distance(first, last));
+    void insert(EIt first, EIt last, CIt from, CIt to) {
+        instances.insert(instances.end(), from, to);
         // entities go after components in case constructors throw
         underlying_type::insert(first, last);
     }
@@ -558,7 +559,7 @@ public:
      * @param last An iterator past the last element of the range of entities.
      */
     template<typename It>
-    void insert(It first, It last, const object_type &) {
+    void insert(It first, It last, const object_type & = {}) {
         underlying_type::insert(first, last);
     }
 
@@ -569,7 +570,7 @@ public:
     template<typename It>
     [[deprecated("use ::insert instead")]]
     std::enable_if_t<std::is_same_v<typename std::iterator_traits<It>::value_type, entity_type>, void>
-    construct(It first, It last, const object_type &value) {
+    construct(It first, It last, const object_type &value = {}) {
         insert(std::move(first), std::move(last), value);
     }
 };

+ 2 - 2
test/benchmark/benchmark.cpp

@@ -115,8 +115,8 @@ TEST(Benchmark, ConstructManyWithComponents) {
 
     timer timer;
     registry.create(entities.begin(), entities.end());
-    registry.assign(entities.begin(), entities.end(), position{});
-    registry.assign(entities.begin(), entities.end(), velocity{});
+    registry.assign<position>(entities.begin(), entities.end());
+    registry.assign<velocity>(entities.begin(), entities.end());
     timer.elapsed();
 }
 

+ 3 - 3
test/entt/entity/registry.cpp

@@ -362,7 +362,7 @@ TEST(Registry, CreateManyEntitiesAtOnceWithListener) {
     registry.on_construct<empty_type>().connect<&listener::incr<empty_type>>(listener);
     registry.create(std::begin(entities), std::end(entities));
     registry.assign(std::begin(entities), std::end(entities), 'a');
-    registry.assign(std::begin(entities), std::end(entities), empty_type{});
+    registry.assign<empty_type>(std::begin(entities), std::end(entities));
 
     ASSERT_TRUE(registry.has<empty_type>(entities[0]));
     ASSERT_EQ(registry.get<char>(entities[2]), 'a');
@@ -815,8 +815,8 @@ TEST(Registry, NestedGroups) {
     entt::entity entities[10];
 
     registry.create(std::begin(entities), std::end(entities));
-    registry.assign(std::begin(entities), std::end(entities), int{});
-    registry.assign(std::begin(entities), std::end(entities), char{});
+    registry.assign<int>(std::begin(entities), std::end(entities));
+    registry.assign<char>(std::begin(entities), std::end(entities));
     const auto g1 = registry.group<int>(entt::get<char>, entt::exclude<double>);
 
     ASSERT_TRUE(g1.sortable());

+ 1 - 1
test/entt/entity/storage.cpp

@@ -111,7 +111,7 @@ TEST(Storage, BatchAddEmptyType) {
     entities[0] = entt::entity{3};
     entities[1] = entt::entity{42};
 
-    pool.construct(std::begin(entities), std::end(entities), {});
+    pool.construct(std::begin(entities), std::end(entities));
 
     ASSERT_TRUE(pool.has(entities[0]));
     ASSERT_TRUE(pool.has(entities[1]));