mirror of
https://github.com/godotengine/godot.git
synced 2025-12-07 22:00:10 +00:00
Merge pull request #113282 from dsnopek/required-ptr-get-out-there
Use `RequiredParam`/`RequiredResult` in some high value places
This commit is contained in:
commit
9f76aa3df5
79 changed files with 372 additions and 321 deletions
|
|
@ -670,9 +670,9 @@ void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), co
|
|||
r_error.error = Callable::CallError::CALL_OK;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
|
||||
r_ret = VariantInternal::make((p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...));
|
||||
#else
|
||||
r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
|
||||
r_ret = VariantInternal::make((p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -681,9 +681,9 @@ void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_ar
|
|||
r_error.error = Callable::CallError::CALL_OK;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
r_ret = (p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
|
||||
r_ret = VariantInternal::make((p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...));
|
||||
#else
|
||||
r_ret = (p_method)(VariantCaster<P>::cast(*p_args[Is])...);
|
||||
r_ret = VariantInternal::make((p_method)(VariantCaster<P>::cast(*p_args[Is])...));
|
||||
#endif // DEBUG_ENABLED
|
||||
}
|
||||
|
||||
|
|
@ -721,9 +721,9 @@ void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) co
|
|||
r_error.error = Callable::CallError::CALL_OK;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
r_ret = (p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
|
||||
r_ret = VariantInternal::make((p_instance->*p_method)(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...));
|
||||
#else
|
||||
r_ret = (p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...);
|
||||
r_ret = VariantInternal::make((p_instance->*p_method)(VariantCaster<P>::cast(*p_args[Is])...));
|
||||
#endif // DEBUG_ENABLED
|
||||
(void)p_args;
|
||||
}
|
||||
|
|
@ -787,9 +787,9 @@ void call_with_variant_args_retc_static_helper(T *p_instance, R (*p_method)(T *,
|
|||
r_error.error = Callable::CallError::CALL_OK;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
r_ret = (p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
|
||||
r_ret = VariantInternal::make((p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...));
|
||||
#else
|
||||
r_ret = (p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...);
|
||||
r_ret = VariantInternal::make((p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...));
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
(void)p_args;
|
||||
|
|
|
|||
|
|
@ -253,8 +253,8 @@ struct PtrToArg<T *> {
|
|||
return likely(p_ptr) ? *reinterpret_cast<T *const *>(p_ptr) : nullptr;
|
||||
}
|
||||
typedef Object *EncodeT;
|
||||
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
|
||||
*((T **)p_ptr) = p_var;
|
||||
_FORCE_INLINE_ static void encode(const T *p_var, void *p_ptr) {
|
||||
*((T **)p_ptr) = const_cast<T *>(p_var);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -264,8 +264,8 @@ struct PtrToArg<const T *> {
|
|||
return likely(p_ptr) ? *reinterpret_cast<T *const *>(p_ptr) : nullptr;
|
||||
}
|
||||
typedef const Object *EncodeT;
|
||||
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
|
||||
*((T **)p_ptr) = p_var;
|
||||
_FORCE_INLINE_ static void encode(const T *p_var, void *p_ptr) {
|
||||
*((T **)p_ptr) = const_cast<T *>(p_var);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@
|
|||
|
||||
#include "core/variant/variant.h"
|
||||
|
||||
// Using `RequiredResult<T>` as the return type indicates that null will only be returned in the case of an error.
|
||||
// This allows GDExtension language bindings to use the appropriate error handling mechanism for that language
|
||||
// when null is returned (for example, throwing an exception), rather than simply returning the value.
|
||||
template <typename T>
|
||||
class RequiredResult {
|
||||
static_assert(!is_fully_defined_v<T> || std::is_base_of_v<Object, T>, "T must be an Object subtype");
|
||||
|
|
@ -43,9 +46,9 @@ public:
|
|||
private:
|
||||
ptr_type _value = ptr_type();
|
||||
|
||||
public:
|
||||
_FORCE_INLINE_ RequiredResult() = default;
|
||||
|
||||
public:
|
||||
RequiredResult(const RequiredResult &p_other) = default;
|
||||
RequiredResult(RequiredResult &&p_other) = default;
|
||||
RequiredResult &operator=(const RequiredResult &p_other) = default;
|
||||
|
|
@ -123,12 +126,13 @@ public:
|
|||
return _value;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ operator ptr_type() {
|
||||
_FORCE_INLINE_ operator ptr_type() const {
|
||||
return _value;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ operator Variant() const {
|
||||
return Variant(_value);
|
||||
template <typename T_Other, std::enable_if_t<std::is_base_of_v<RefCounted, T> && std::is_base_of_v<T, T_Other>, int> = 0>
|
||||
_FORCE_INLINE_ operator Ref<T_Other>() const {
|
||||
return Ref<T_Other>(_value);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ element_type *operator*() const {
|
||||
|
|
@ -140,6 +144,10 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// Using `RequiredParam<T>` as an argument type indicates that passing null as that parameter is an error,
|
||||
// that will prevent the method from doing its intended function.
|
||||
// This allows GDExtension bindings to use language-specific mechanisms to prevent users from passing null,
|
||||
// because it is never valid to do so.
|
||||
template <typename T>
|
||||
class RequiredParam {
|
||||
static_assert(!is_fully_defined_v<T> || std::is_base_of_v<Object, T>, "T must be an Object subtype");
|
||||
|
|
|
|||
|
|
@ -40,6 +40,12 @@
|
|||
|
||||
class RefCounted;
|
||||
|
||||
template <typename T>
|
||||
struct GDExtensionConstPtr;
|
||||
|
||||
template <typename T>
|
||||
struct GDExtensionPtr;
|
||||
|
||||
class VariantInternal {
|
||||
friend class Variant;
|
||||
|
||||
|
|
@ -539,6 +545,29 @@ public:
|
|||
}
|
||||
ERR_FAIL_V(nullptr);
|
||||
}
|
||||
|
||||
// Used internally in GDExtension and Godot's binding system when converting to Variant
|
||||
// from values that may include RequiredParam<T> or RequiredResult<T>.
|
||||
template <typename T>
|
||||
_FORCE_INLINE_ static Variant make(const T &v) {
|
||||
return Variant(v);
|
||||
}
|
||||
template <typename T>
|
||||
_FORCE_INLINE_ static Variant make(const GDExtensionConstPtr<T> &v) {
|
||||
return v.operator Variant();
|
||||
}
|
||||
template <typename T>
|
||||
_FORCE_INLINE_ static Variant make(const GDExtensionPtr<T> &v) {
|
||||
return v.operator Variant();
|
||||
}
|
||||
template <typename T>
|
||||
_FORCE_INLINE_ static Variant make(const RequiredParam<T> &v) {
|
||||
return Variant(v._internal_ptr_dont_use());
|
||||
}
|
||||
template <typename T>
|
||||
_FORCE_INLINE_ static Variant make(const RequiredResult<T> &v) {
|
||||
return Variant(v._internal_ptr_dont_use());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename = void>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue