Explorar o código

sparse set: generic bind function

Michele Caini hai 1 ano
pai
achega
9630977c2d
Modificáronse 3 ficheiros con 40 adicións e 19 borrados
  1. 6 10
      src/entt/entity/mixin.hpp
  2. 28 3
      src/entt/entity/sparse_set.hpp
  3. 6 6
      test/common/mixin.hpp

+ 6 - 10
src/entt/entity/mixin.hpp

@@ -114,6 +114,12 @@ private:
         return it;
     }
 
+    void bind_any(any value) noexcept final {
+        auto *reg = any_cast<basic_registry_type>(&value);
+        owner = reg ? reg : owner;
+        underlying_type::bind_any(std::move(value));
+    }
+
 public:
     /*! @brief Allocator type. */
     using allocator_type = typename underlying_type::allocator_type;
@@ -331,16 +337,6 @@ public:
         }
     }
 
-    /**
-     * @brief Forwards variables to derived classes, if any.
-     * @param value A variable wrapped in an opaque container.
-     */
-    void bind(any value) noexcept final {
-        auto *reg = any_cast<basic_registry_type>(&value);
-        owner = reg ? reg : owner;
-        underlying_type::bind(std::move(value));
-    }
-
 private:
     basic_registry_type *owner;
     sigh_type construction;

+ 28 - 3
src/entt/entity/sparse_set.hpp

@@ -369,6 +369,10 @@ protected:
         return --(end() - static_cast<typename iterator::difference_type>(pos));
     }
 
+    /*! @brief Forwards variables to derived classes, if any. */
+    // NOLINTNEXTLINE(performance-unnecessary-value-param)
+    virtual void bind_any(any) noexcept {}
+
 public:
     /*! @brief Allocator type. */
     using allocator_type = Allocator;
@@ -1045,9 +1049,30 @@ public:
         return *info;
     }
 
-    /*! @brief Forwards variables to derived classes, if any. */
-    // NOLINTNEXTLINE(performance-unnecessary-value-param)
-    virtual void bind(any) noexcept {}
+    /**
+     * @brief Forwards variables to derived classes, if any.
+     * @tparam Type Type of the element to forward.
+     * @param value The element to forward.
+     * @return Nothing.
+     */
+    template<typename Type>
+    [[deprecated("avoid wrapping elements with basic_any")]] std::enable_if_t<std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, basic_any<>>>
+    bind(Type &&value) noexcept {
+        // backward compatibility
+        bind_any(std::forward<Type>(value));
+    }
+
+    /**
+     * @brief Forwards variables to derived classes, if any.
+     * @tparam Type Type of the element to forward.
+     * @param value The element to forward.
+     * @return Nothing.
+     */
+    template<typename Type>
+    std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, basic_any<>>>
+    bind(Type &&value) noexcept {
+        bind_any(forward_as_any(std::forward<Type>(value)));
+    }
 
 private:
     sparse_container_type sparse;

+ 6 - 6
test/common/mixin.hpp

@@ -13,17 +13,17 @@ class assure_loop_mixin: public Type {
     using underlying_type = Type;
     using registry_type = entt::basic_registry<typename underlying_type::entity_type, typename underlying_type::base_type::allocator_type>;
 
+    void bind_any(entt::any value) noexcept override {
+        if(auto *owner = entt::any_cast<registry_type>(&value); owner) {
+            owner->template storage<int>();
+        }
+    }
+
 public:
     using allocator_type = typename underlying_type::allocator_type;
     using entity_type = typename underlying_type::entity_type;
 
     using Type::Type;
-
-    void bind(entt::any value) noexcept override {
-        if(auto *owner = entt::any_cast<registry_type>(&value); owner) {
-            owner->template storage<int>();
-        }
-    }
 };
 
 } // namespace test