Ver Fonte

meta: support extra arguments when settings meta data (work in progress)

skypjack há 2 semanas atrás
pai
commit
b96d93b181
4 ficheiros alterados com 57 adições e 32 exclusões
  1. 7 0
      TODO
  2. 10 10
      src/entt/meta/meta.hpp
  3. 1 1
      src/entt/meta/node.hpp
  4. 39 21
      src/entt/meta/utility.hpp

+ 7 - 0
TODO

@@ -32,3 +32,10 @@ TODO:
 * make meta_any buffer size configurable (propagate to any)
 * test trivially_destructible optimization
 * finish the imgui viewer/editor!
+* test meta_setter/meta_getter with meta_any*
+* test set/get with multiple values
+* document additional arguments to meta setters/getters
+* meta_data should check arity on set/get
+* refine arg and arity on meta_data
+* remove meta invoke/set/get that take meta_any *const args
+

+ 10 - 10
src/entt/meta/meta.hpp

@@ -409,10 +409,10 @@ public:
     /**
      * @brief Sets the value of a given variable.
      * @param id Unique identifier.
-     * @param value Parameter to use to set the underlying variable.
+     * @param args Parameters to use to set the underlying variable.
      * @return True in case of success, false otherwise.
      */
-    bool set(id_type id, auto &&value);
+    bool set(id_type id, auto &&...args);
 
     /**
      * @brief Gets the value of a given variable.
@@ -869,13 +869,13 @@ struct meta_data: meta_object<internal::meta_data_node> {
      * @brief Sets the value of a given variable.
      * @tparam Instance Type of instance to operate on.
      * @param instance An instance that fits the underlying type.
-     * @param value Parameter to use to set the underlying variable.
+     * @param args Parameters to use to set the underlying variable.
      * @return True in case of success, false otherwise.
      */
     template<typename Instance = meta_handle>
     // NOLINTNEXTLINE(modernize-use-nodiscard)
-    bool set(Instance &&instance, auto &&value) const {
-        return node_or_assert().set(meta_handle{*ctx, stl::forward<Instance>(instance)}, meta_any{*ctx, stl::forward<decltype(value)>(value)});
+    bool set(Instance &&instance, auto &&...args) const {
+        return (sizeof...(args) == arity()) && node_or_assert().set(meta_handle{*ctx, stl::forward<Instance>(instance)}, stl::array<meta_any, sizeof...(args)>{meta_any{*ctx, stl::forward<decltype(args)>(args)}...}.data());
     }
 
     /**
@@ -1430,14 +1430,14 @@ public:
      * @tparam Instance Type of instance to operate on.
      * @param id Unique identifier.
      * @param instance An instance that fits the underlying type.
-     * @param value Parameter to use to set the underlying variable.
+     * @param args Parameters to use to set the underlying variable.
      * @return True in case of success, false otherwise.
      */
     template<typename Instance = meta_handle>
     // NOLINTNEXTLINE(modernize-use-nodiscard)
-    bool set(const id_type id, Instance &&instance, auto &&value) const {
+    bool set(const id_type id, Instance &&instance, auto &&...args) const {
         const auto candidate = data(id);
-        return candidate && candidate.set(stl::forward<Instance>(instance), stl::forward<decltype(value)>(value));
+        return candidate && candidate.set(stl::forward<Instance>(instance), stl::forward<decltype(args)>(args)...);
     }
 
     /**
@@ -1498,8 +1498,8 @@ meta_any meta_any::invoke(const id_type id, auto &&...args) {
     return type().invoke(id, *this, stl::forward<decltype(args)>(args)...);
 }
 
-bool meta_any::set(const id_type id, auto &&value) {
-    return type().set(id, *this, stl::forward<decltype(value)>(value));
+bool meta_any::set(const id_type id, auto &&...args) {
+    return type().set(id, *this, stl::forward<decltype(args)>(args)...);
 }
 
 [[nodiscard]] inline meta_any meta_any::get(const id_type id) const {

+ 1 - 1
src/entt/meta/node.hpp

@@ -96,7 +96,7 @@ struct meta_data_node {
     size_type arity{0u};
     const meta_type_node &(*type)(const meta_context &) noexcept {};
     meta_type (*arg)(const meta_ctx &, const size_type) noexcept {};
-    bool (*set)(meta_handle, meta_any){};
+    bool (*set)(meta_handle, meta_any *const){};
     meta_any (*get)(meta_handle){};
     meta_custom_node custom{};
 };

+ 39 - 21
src/entt/meta/utility.hpp

@@ -270,40 +270,58 @@ template<typename Type>
  * @tparam Type Reflected type to which the variable is associated.
  * @tparam Data The actual variable to set.
  * @param instance An opaque instance of the underlying type, if required.
- * @param value Parameter to use to set the variable.
+ * @param args Parameters to use to set the variable.
  * @return True in case of success, false otherwise.
  */
 template<typename Type, auto Data>
-[[nodiscard]] bool meta_setter([[maybe_unused]] meta_handle instance, [[maybe_unused]] meta_any value) {
+[[nodiscard]] bool meta_setter([[maybe_unused]] meta_handle instance, [[maybe_unused]] meta_any *const args) {
     if constexpr(stl::is_member_function_pointer_v<decltype(Data)> || stl::is_function_v<stl::remove_reference_t<stl::remove_pointer_t<decltype(Data)>>>) {
         using descriptor = meta_function_helper_t<Type, decltype(Data)>;
-        using data_type = type_list_element_t<descriptor::is_static, typename descriptor::args_type>;
-
-        if(auto *const clazz = instance->try_cast<Type>(); clazz && value.allow_cast<data_type>()) {
-            stl::invoke(Data, *clazz, value.cast<data_type>());
-            return true;
-        }
-    } else if constexpr(stl::is_member_object_pointer_v<decltype(Data)>) {
-        using data_type = stl::remove_reference_t<typename meta_function_helper_t<Type, decltype(Data)>::return_type>;
 
-        if constexpr(!stl::is_array_v<data_type> && !stl::is_const_v<data_type>) {
-            if(auto *const clazz = instance->try_cast<Type>(); clazz && value.allow_cast<data_type>()) {
-                stl::invoke(Data, *clazz) = value.cast<data_type>();
+        return [&]<auto... Index>(stl::index_sequence<Index...>) {
+            if(auto *const clazz = instance->try_cast<Type>(); clazz && ((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
+                stl::invoke(Data, *clazz, (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
                 return true;
             }
-        }
-    } else if constexpr(stl::is_pointer_v<decltype(Data)>) {
-        using data_type = stl::remove_reference_t<decltype(*Data)>;
 
-        if constexpr(!stl::is_array_v<data_type> && !stl::is_const_v<data_type>) {
-            if(value.allow_cast<data_type>()) {
-                *Data = value.cast<data_type>();
-                return true;
+            return false;
+        }(stl::make_index_sequence<descriptor::args_type::size>{});
+    } else {
+        if constexpr(stl::is_member_object_pointer_v<decltype(Data)>) {
+            using data_type = stl::remove_reference_t<typename meta_function_helper_t<Type, decltype(Data)>::return_type>;
+
+            if constexpr(!stl::is_array_v<data_type> && !stl::is_const_v<data_type>) {
+                if(auto *const clazz = instance->try_cast<Type>(); clazz && args->allow_cast<data_type>()) {
+                    stl::invoke(Data, *clazz) = args->cast<data_type>();
+                    return true;
+                }
+            }
+        } else if constexpr(stl::is_pointer_v<decltype(Data)>) {
+            using data_type = stl::remove_reference_t<decltype(*Data)>;
+
+            if constexpr(!stl::is_array_v<data_type> && !stl::is_const_v<data_type>) {
+                if(args->allow_cast<data_type>()) {
+                    *Data = args->cast<data_type>();
+                    return true;
+                }
             }
         }
+
+        return false;
     }
+}
 
-    return false;
+/**
+ * @brief Sets the value of a given variable.
+ * @tparam Type Reflected type to which the variable is associated.
+ * @tparam Data The actual variable to set.
+ * @param instance An opaque instance of the underlying type, if required.
+ * @param value Parameter to use to set the variable.
+ * @return True in case of success, false otherwise.
+ */
+template<typename Type, auto Data>
+[[nodiscard]] bool meta_setter(meta_handle instance, meta_any value) {
+    return meta_setter<Type, Data>(*instance.operator->(), &value);
 }
 
 /**