Просмотр исходного кода

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

skypjack 2 недель назад
Родитель
Сommit
b5f07153b7
3 измененных файлов с 55 добавлено и 40 удалено
  1. 13 10
      src/entt/meta/meta.hpp
  2. 1 1
      src/entt/meta/node.hpp
  3. 41 29
      src/entt/meta/utility.hpp

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

@@ -417,12 +417,13 @@ public:
     /**
     /**
      * @brief Gets the value of a given variable.
      * @brief Gets the value of a given variable.
      * @param id Unique identifier.
      * @param id Unique identifier.
+     * @param args Parameters to use to set the underlying variable, if any.
      * @return A wrapper containing the value of the underlying variable.
      * @return A wrapper containing the value of the underlying variable.
      */
      */
-    [[nodiscard]] meta_any get(id_type id) const;
+    [[nodiscard]] meta_any get(id_type id, auto &&...args) const;
 
 
     /*! @copydoc get */
     /*! @copydoc get */
-    [[nodiscard]] meta_any get(id_type id);
+    [[nodiscard]] meta_any get(id_type id, auto &&...args);
 
 
     /**
     /**
      * @brief Tries to cast an instance to a given type.
      * @brief Tries to cast an instance to a given type.
@@ -882,11 +883,12 @@ struct meta_data: meta_object<internal::meta_data_node> {
      * @brief Gets the value of a given variable.
      * @brief Gets the value of a given variable.
      * @tparam Instance Type of instance to operate on.
      * @tparam Instance Type of instance to operate on.
      * @param instance An instance that fits the underlying type.
      * @param instance An instance that fits the underlying type.
+     * @param args Parameters to use to get the underlying variable, if any.
      * @return A wrapper containing the value of the underlying variable.
      * @return A wrapper containing the value of the underlying variable.
      */
      */
     template<typename Instance = meta_handle>
     template<typename Instance = meta_handle>
-    [[nodiscard]] meta_any get(Instance &&instance) const {
-        return node_or_assert().get(meta_handle{*ctx, stl::forward<Instance>(instance)});
+    [[nodiscard]] meta_any get(Instance &&instance, auto &&...args) const {
+        return node_or_assert().get(meta_handle{*ctx, stl::forward<Instance>(instance)}, stl::array<meta_any, sizeof...(args)>{meta_any{*ctx, stl::forward<decltype(args)>(args)}...}.data());
     }
     }
 
 
     /**
     /**
@@ -1445,12 +1447,13 @@ public:
      * @tparam Instance Type of instance to operate on.
      * @tparam Instance Type of instance to operate on.
      * @param id Unique identifier.
      * @param id Unique identifier.
      * @param instance An instance that fits the underlying type.
      * @param instance An instance that fits the underlying type.
+     * @param args Parameters to use to set the underlying variable, if any.
      * @return A wrapper containing the value of the underlying variable.
      * @return A wrapper containing the value of the underlying variable.
      */
      */
     template<typename Instance = meta_handle>
     template<typename Instance = meta_handle>
-    [[nodiscard]] meta_any get(const id_type id, Instance &&instance) const {
+    [[nodiscard]] meta_any get(const id_type id, Instance &&instance, auto &&...args) const {
         const auto candidate = data(id);
         const auto candidate = data(id);
-        return candidate ? candidate.get(stl::forward<Instance>(instance)) : meta_any{meta_ctx_arg, *ctx};
+        return candidate ? candidate.get(stl::forward<Instance>(instance), stl::forward<decltype(args)>(args)...) : meta_any{meta_ctx_arg, *ctx};
     }
     }
 
 
     /*! @copydoc meta_data::traits */
     /*! @copydoc meta_data::traits */
@@ -1502,12 +1505,12 @@ bool meta_any::set(const id_type id, auto &&...args) {
     return type().set(id, *this, stl::forward<decltype(args)>(args)...);
     return type().set(id, *this, stl::forward<decltype(args)>(args)...);
 }
 }
 
 
-[[nodiscard]] inline meta_any meta_any::get(const id_type id) const {
-    return type().get(id, *this);
+[[nodiscard]] inline meta_any meta_any::get(const id_type id, auto &&...args) const {
+    return type().get(id, *this, stl::forward<decltype(args)>(args)...);
 }
 }
 
 
-[[nodiscard]] inline meta_any meta_any::get(const id_type id) {
-    return type().get(id, *this);
+[[nodiscard]] inline meta_any meta_any::get(const id_type id, auto &&...args) {
+    return type().get(id, *this, stl::forward<decltype(args)>(args)...);
 }
 }
 
 
 [[nodiscard]] inline meta_any meta_any::allow_cast(const meta_type &type) const {
 [[nodiscard]] inline meta_any meta_any::allow_cast(const meta_type &type) const {

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

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

+ 41 - 29
src/entt/meta/utility.hpp

@@ -277,27 +277,29 @@ template<typename Type, auto Data>
 [[nodiscard]] bool meta_setter([[maybe_unused]] meta_handle instance, [[maybe_unused]] meta_any *const args) {
 [[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)>>>) {
     if constexpr(stl::is_member_function_pointer_v<decltype(Data)> || stl::is_function_v<stl::remove_reference_t<stl::remove_pointer_t<decltype(Data)>>>) {
         return static_cast<bool>(internal::meta_invoke<Type, as_void_t>(*instance.operator->(), Data, args, stl::make_index_sequence<meta_function_helper_t<Type, decltype(Data)>::args_type::size>{}));
         return static_cast<bool>(internal::meta_invoke<Type, as_void_t>(*instance.operator->(), Data, args, stl::make_index_sequence<meta_function_helper_t<Type, decltype(Data)>::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_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;
+    } 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;
+    } else {
         return false;
         return false;
     }
     }
 }
 }
@@ -321,22 +323,19 @@ template<typename Type, auto Data>
  * @tparam Data The actual variable to get.
  * @tparam Data The actual variable to get.
  * @tparam Policy Optional policy (no policy set by default).
  * @tparam Policy Optional policy (no policy set by default).
  * @param instance An opaque instance of the underlying type, if required.
  * @param instance An opaque instance of the underlying type, if required.
+ * @param args Parameters to use to set the variable.
  * @return A meta any containing the value of the underlying variable.
  * @return A meta any containing the value of the underlying variable.
  */
  */
 template<typename Type, auto Data, meta_policy Policy = as_value_t>
 template<typename Type, auto Data, meta_policy Policy = as_value_t>
-[[nodiscard]] meta_any meta_getter(meta_handle instance) {
-    if constexpr(stl::is_member_pointer_v<decltype(Data)> || stl::is_function_v<stl::remove_reference_t<stl::remove_pointer_t<decltype(Data)>>>) {
+[[nodiscard]] meta_any meta_getter(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)>>>) {
+        return internal::meta_invoke<Type, Policy>(*instance.operator->(), Data, args, stl::make_index_sequence<meta_function_helper_t<Type, decltype(Data)>::args_type::size>{});
+    } else if constexpr(stl::is_member_object_pointer_v<decltype(Data)>) {
         if constexpr(!stl::is_array_v<stl::remove_cvref_t<stl::invoke_result_t<decltype(Data), Type &>>>) {
         if constexpr(!stl::is_array_v<stl::remove_cvref_t<stl::invoke_result_t<decltype(Data), Type &>>>) {
-            if constexpr(stl::is_invocable_v<decltype(Data), Type &>) {
-                if(auto *clazz = instance->try_cast<Type>(); clazz) {
-                    return meta_dispatch<Policy>(instance->context(), stl::invoke(Data, *clazz));
-                }
-            }
-
-            if constexpr(stl::is_invocable_v<decltype(Data), const Type &>) {
-                if(auto *fallback = instance->try_cast<const Type>(); fallback) {
-                    return meta_dispatch<Policy>(instance->context(), stl::invoke(Data, *fallback));
-                }
+            if(auto *clazz = instance->try_cast<Type>(); clazz) {
+                return meta_dispatch<Policy>(instance->context(), stl::invoke(Data, *clazz));
+            } else if(auto *fallback = instance->try_cast<const Type>(); fallback) {
+                return meta_dispatch<Policy>(instance->context(), stl::invoke(Data, *fallback));
             }
             }
         }
         }
 
 
@@ -352,6 +351,19 @@ template<typename Type, auto Data, meta_policy Policy = as_value_t>
     }
     }
 }
 }
 
 
+/**
+ * @brief Gets the value of a given variable.
+ * @tparam Type Reflected type to which the variable is associated.
+ * @tparam Data The actual variable to get.
+ * @tparam Policy Optional policy (no policy set by default).
+ * @param instance An opaque instance of the underlying type, if required.
+ * @return A meta any containing the value of the underlying variable.
+ */
+template<typename Type, auto Data, meta_policy Policy = as_value_t>
+[[nodiscard]] meta_any meta_getter(meta_handle instance) {
+    return meta_getter<Type, Data, Policy>(*instance.operator->(), nullptr);
+}
+
 /**
 /**
  * @brief Tries to _invoke_ an object given a list of erased parameters.
  * @brief Tries to _invoke_ an object given a list of erased parameters.
  * @tparam Type Reflected type to which the object to _invoke_ is associated.
  * @tparam Type Reflected type to which the object to _invoke_ is associated.