Browse Source

Add missing CallableCustomMethodPointer for const methods

rune-scape 1 year ago
parent
commit
a84c480049
2 changed files with 50 additions and 91 deletions
  1. 48 89
      core/object/callable_method_pointer.h
  2. 2 2
      core/variant/binder_common.h

+ 48 - 89
core/object/callable_method_pointer.h

@@ -37,6 +37,8 @@
 #include "core/variant/binder_common.h"
 #include "core/variant/callable.h"
 
+#include <type_traits>
+
 class CallableCustomMethodPointerBase : public CallableCustom {
 	uint32_t *comp_ptr = nullptr;
 	uint32_t comp_size;
@@ -77,12 +79,13 @@ public:
 	virtual uint32_t hash() const;
 };
 
-template <typename T, typename... P>
+template <typename T, typename R, typename... P>
 class CallableCustomMethodPointer : public CallableCustomMethodPointerBase {
 	struct Data {
 		T *instance;
 		uint64_t object_id;
-		void (T::*method)(P...);
+		R(T::*method)
+		(P...);
 	} data;
 
 public:
@@ -100,10 +103,14 @@ public:
 
 	virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
 		ERR_FAIL_NULL_MSG(ObjectDB::get_instance(ObjectID(data.object_id)), "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
-		call_with_variant_args(data.instance, data.method, p_arguments, p_argcount, r_call_error);
+		if constexpr (std::is_same<R, void>::value) {
+			call_with_variant_args(data.instance, data.method, p_arguments, p_argcount, r_call_error);
+		} else {
+			call_with_variant_args_ret(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
+		}
 	}
 
-	CallableCustomMethodPointer(T *p_instance, void (T::*p_method)(P...)) {
+	CallableCustomMethodPointer(T *p_instance, R (T::*p_method)(P...)) {
 		memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
 		data.instance = p_instance;
 		data.object_id = p_instance->get_instance_id();
@@ -118,7 +125,7 @@ Callable create_custom_callable_function_pointer(T *p_instance,
 		const char *p_func_text,
 #endif
 		void (T::*p_method)(P...)) {
-	typedef CallableCustomMethodPointer<T, P...> CCMP; // Messes with memnew otherwise.
+	typedef CallableCustomMethodPointer<T, void, P...> CCMP; // Messes with memnew otherwise.
 	CCMP *ccmp = memnew(CCMP(p_instance, p_method));
 #ifdef DEBUG_METHODS_ENABLED
 	ccmp->set_text(p_func_text + 1); // Try to get rid of the ampersand.
@@ -126,51 +133,13 @@ Callable create_custom_callable_function_pointer(T *p_instance,
 	return Callable(ccmp);
 }
 
-// VERSION WITH RETURN
-
-template <typename T, typename R, typename... P>
-class CallableCustomMethodPointerRet : public CallableCustomMethodPointerBase {
-	struct Data {
-		T *instance;
-		uint64_t object_id;
-		R(T::*method)
-		(P...);
-	} data;
-
-public:
-	virtual ObjectID get_object() const {
-		if (ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr) {
-			return ObjectID();
-		}
-		return data.instance->get_instance_id();
-	}
-
-	virtual int get_argument_count(bool &r_is_valid) const {
-		r_is_valid = true;
-		return sizeof...(P);
-	}
-
-	virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
-		ERR_FAIL_NULL_MSG(ObjectDB::get_instance(ObjectID(data.object_id)), "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
-		call_with_variant_args_ret(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
-	}
-
-	CallableCustomMethodPointerRet(T *p_instance, R (T::*p_method)(P...)) {
-		memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
-		data.instance = p_instance;
-		data.object_id = p_instance->get_instance_id();
-		data.method = p_method;
-		_setup((uint32_t *)&data, sizeof(Data));
-	}
-};
-
 template <typename T, typename R, typename... P>
 Callable create_custom_callable_function_pointer(T *p_instance,
 #ifdef DEBUG_METHODS_ENABLED
 		const char *p_func_text,
 #endif
 		R (T::*p_method)(P...)) {
-	typedef CallableCustomMethodPointerRet<T, R, P...> CCMP; // Messes with memnew otherwise.
+	typedef CallableCustomMethodPointer<T, R, P...> CCMP; // Messes with memnew otherwise.
 	CCMP *ccmp = memnew(CCMP(p_instance, p_method));
 #ifdef DEBUG_METHODS_ENABLED
 	ccmp->set_text(p_func_text + 1); // Try to get rid of the ampersand.
@@ -178,10 +147,10 @@ Callable create_custom_callable_function_pointer(T *p_instance,
 	return Callable(ccmp);
 }
 
-// CONST VERSION WITH RETURN
+// CONST VERSION
 
 template <typename T, typename R, typename... P>
-class CallableCustomMethodPointerRetC : public CallableCustomMethodPointerBase {
+class CallableCustomMethodPointerC : public CallableCustomMethodPointerBase {
 	struct Data {
 		T *instance;
 		uint64_t object_id;
@@ -204,10 +173,14 @@ public:
 
 	virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override {
 		ERR_FAIL_NULL_MSG(ObjectDB::get_instance(ObjectID(data.object_id)), "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
-		call_with_variant_args_retc(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
+		if constexpr (std::is_same<R, void>::value) {
+			call_with_variant_argsc(data.instance, data.method, p_arguments, p_argcount, r_call_error);
+		} else {
+			call_with_variant_args_retc(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
+		}
 	}
 
-	CallableCustomMethodPointerRetC(T *p_instance, R (T::*p_method)(P...) const) {
+	CallableCustomMethodPointerC(T *p_instance, R (T::*p_method)(P...) const) {
 		memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
 		data.instance = p_instance;
 		data.object_id = p_instance->get_instance_id();
@@ -216,13 +189,27 @@ public:
 	}
 };
 
+template <typename T, typename... P>
+Callable create_custom_callable_function_pointer(T *p_instance,
+#ifdef DEBUG_METHODS_ENABLED
+		const char *p_func_text,
+#endif
+		void (T::*p_method)(P...) const) {
+	typedef CallableCustomMethodPointerC<T, void, P...> CCMP; // Messes with memnew otherwise.
+	CCMP *ccmp = memnew(CCMP(p_instance, p_method));
+#ifdef DEBUG_METHODS_ENABLED
+	ccmp->set_text(p_func_text + 1); // Try to get rid of the ampersand.
+#endif
+	return Callable(ccmp);
+}
+
 template <typename T, typename R, typename... P>
 Callable create_custom_callable_function_pointer(T *p_instance,
 #ifdef DEBUG_METHODS_ENABLED
 		const char *p_func_text,
 #endif
 		R (T::*p_method)(P...) const) {
-	typedef CallableCustomMethodPointerRetC<T, R, P...> CCMP; // Messes with memnew otherwise.
+	typedef CallableCustomMethodPointerC<T, R, P...> CCMP; // Messes with memnew otherwise.
 	CCMP *ccmp = memnew(CCMP(p_instance, p_method));
 #ifdef DEBUG_METHODS_ENABLED
 	ccmp->set_text(p_func_text + 1); // Try to get rid of the ampersand.
@@ -238,10 +225,11 @@ Callable create_custom_callable_function_pointer(T *p_instance,
 
 // STATIC VERSIONS
 
-template <typename... P>
+template <typename R, typename... P>
 class CallableCustomStaticMethodPointer : public CallableCustomMethodPointerBase {
 	struct Data {
-		void (*method)(P...);
+		R(*method)
+		(P...);
 	} data;
 
 public:
@@ -259,24 +247,27 @@ public:
 	}
 
 	virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override {
-		call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
-		r_return_value = Variant();
+		if constexpr (std::is_same<R, void>::value) {
+			call_with_variant_args_static(data.method, p_arguments, p_argcount, r_call_error);
+		} else {
+			call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
+		}
 	}
 
-	CallableCustomStaticMethodPointer(void (*p_method)(P...)) {
+	CallableCustomStaticMethodPointer(R (*p_method)(P...)) {
 		memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
 		data.method = p_method;
 		_setup((uint32_t *)&data, sizeof(Data));
 	}
 };
 
-template <typename T, typename... P>
+template <typename... P>
 Callable create_custom_callable_static_function_pointer(
 #ifdef DEBUG_METHODS_ENABLED
 		const char *p_func_text,
 #endif
 		void (*p_method)(P...)) {
-	typedef CallableCustomStaticMethodPointer<P...> CCMP; // Messes with memnew otherwise.
+	typedef CallableCustomStaticMethodPointer<void, P...> CCMP; // Messes with memnew otherwise.
 	CCMP *ccmp = memnew(CCMP(p_method));
 #ifdef DEBUG_METHODS_ENABLED
 	ccmp->set_text(p_func_text + 1); // Try to get rid of the ampersand.
@@ -284,45 +275,13 @@ Callable create_custom_callable_static_function_pointer(
 	return Callable(ccmp);
 }
 
-template <typename R, typename... P>
-class CallableCustomStaticMethodPointerRet : public CallableCustomMethodPointerBase {
-	struct Data {
-		R(*method)
-		(P...);
-	} data;
-
-public:
-	virtual bool is_valid() const override {
-		return true;
-	}
-
-	virtual ObjectID get_object() const override {
-		return ObjectID();
-	}
-
-	virtual int get_argument_count(bool &r_is_valid) const override {
-		r_is_valid = true;
-		return sizeof...(P);
-	}
-
-	virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override {
-		call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
-	}
-
-	CallableCustomStaticMethodPointerRet(R (*p_method)(P...)) {
-		memset(&data, 0, sizeof(Data)); // Clear beforehand, may have padding bytes.
-		data.method = p_method;
-		_setup((uint32_t *)&data, sizeof(Data));
-	}
-};
-
 template <typename R, typename... P>
 Callable create_custom_callable_static_function_pointer(
 #ifdef DEBUG_METHODS_ENABLED
 		const char *p_func_text,
 #endif
 		R (*p_method)(P...)) {
-	typedef CallableCustomStaticMethodPointerRet<R, P...> CCMP; // Messes with memnew otherwise.
+	typedef CallableCustomStaticMethodPointer<R, P...> CCMP; // Messes with memnew otherwise.
 	CCMP *ccmp = memnew(CCMP(p_method));
 #ifdef DEBUG_METHODS_ENABLED
 	ccmp->set_text(p_func_text + 1); // Try to get rid of the ampersand.

+ 2 - 2
core/variant/binder_common.h

@@ -466,7 +466,7 @@ void call_with_variant_argsc(T *p_instance, void (T::*p_method)(P...) const, con
 		return;
 	}
 #endif
-	call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
+	call_with_variant_argsc_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
 }
 
 template <typename T, typename... P>
@@ -830,7 +830,7 @@ void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_ar
 }
 
 template <typename... P>
-void call_with_variant_args_static_ret(void (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
+void call_with_variant_args_static(void (*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
 #ifdef DEBUG_METHODS_ENABLED
 	if ((size_t)p_argcount > sizeof...(P)) {
 		r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;