From 06aecb3a28a7b8ba1a12223d3fe42a5bb9924e14 Mon Sep 17 00:00:00 2001 From: Ninni Pipping Date: Mon, 27 Mar 2023 16:05:59 +0200 Subject: [PATCH] Test rebind --- core/variant/callable.cpp | 12 ++++++++++++ core/variant/callable.h | 4 ++++ core/variant/callable_bind.cpp | 8 ++++++++ core/variant/callable_bind.h | 4 ++++ core/variant/variant_call.cpp | 6 ++++++ doc/classes/Callable.xml | 6 ++++++ modules/gdscript/gdscript_lambda_callable.cpp | 4 ++++ modules/gdscript/gdscript_lambda_callable.h | 2 ++ 8 files changed, 46 insertions(+) diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp index 2f2acc55a60c..bedaae175692 100644 --- a/core/variant/callable.cpp +++ b/core/variant/callable.cpp @@ -199,6 +199,18 @@ const Callable *Callable::get_base_comparator() const { } } +Callable Callable::rebind(const Object *p_object) const { + if (is_custom()) { + CallableCustom *new_custom = custom->rebind(p_object); + if (new_custom) { + return Callable(new_custom); + } + return Callable(); + } else { + return Callable(p_object, method); + } +} + uint32_t Callable::hash() const { if (is_custom()) { return custom->hash(); diff --git a/core/variant/callable.h b/core/variant/callable.h index 0abbb64c0bd6..559b23e81bbd 100644 --- a/core/variant/callable.h +++ b/core/variant/callable.h @@ -111,6 +111,8 @@ class Callable { void get_bound_arguments_ref(Vector &r_arguments, int &r_argcount) const; // Internal engine use, the exposed one is below. Array get_bound_arguments() const; + Callable rebind(const Object *p_object) const; + uint32_t hash() const; const Callable *get_base_comparator() const; //used for bind/unbind to do less precise comparisons (ignoring binds) in signal connect/disconnect @@ -153,6 +155,8 @@ class CallableCustom { virtual int get_bound_arguments_count() const; virtual void get_bound_arguments(Vector &r_arguments, int &r_argcount) const; + virtual CallableCustom *rebind(const Object *p_object) const { return nullptr; }; + CallableCustom(); virtual ~CallableCustom() {} }; diff --git a/core/variant/callable_bind.cpp b/core/variant/callable_bind.cpp index 5be91c6e118e..b623510ae98e 100644 --- a/core/variant/callable_bind.cpp +++ b/core/variant/callable_bind.cpp @@ -140,6 +140,10 @@ void CallableCustomBind::call(const Variant **p_arguments, int p_argcount, Varia callable.callp(args, p_argcount + binds.size(), r_return_value, r_call_error); } +CallableCustom *CallableCustomBind::rebind(const Object *p_object) const { + return memnew(CallableCustomBind(callable.rebind(p_object), binds)); +} + CallableCustomBind::CallableCustomBind(const Callable &p_callable, const Vector &p_binds) { callable = p_callable; binds = p_binds; @@ -234,6 +238,10 @@ void CallableCustomUnbind::call(const Variant **p_arguments, int p_argcount, Var callable.callp(p_arguments, p_argcount - argcount, r_return_value, r_call_error); } +CallableCustom *CallableCustomUnbind::rebind(const Object *p_object) const { + return memnew(CallableCustomUnbind(callable.rebind(p_object), argcount)); +} + CallableCustomUnbind::CallableCustomUnbind(const Callable &p_callable, int p_argcount) { callable = p_callable; argcount = p_argcount; diff --git a/core/variant/callable_bind.h b/core/variant/callable_bind.h index 278ed335d08f..ff808a9271a9 100644 --- a/core/variant/callable_bind.h +++ b/core/variant/callable_bind.h @@ -56,6 +56,8 @@ class CallableCustomBind : public CallableCustom { Callable get_callable() { return callable; } Vector get_binds() { return binds; } + CallableCustom *rebind(const Object *p_object) const override; + CallableCustomBind(const Callable &p_callable, const Vector &p_binds); virtual ~CallableCustomBind(); }; @@ -83,6 +85,8 @@ class CallableCustomUnbind : public CallableCustom { Callable get_callable() { return callable; } int get_unbinds() { return argcount; } + CallableCustom *rebind(const Object *p_object) const override; + CallableCustomUnbind(const Callable &p_callable, int p_argcount); virtual ~CallableCustomUnbind(); }; diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index ae151588362b..1d91bea0147a 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1055,6 +1055,10 @@ struct _VariantCall { r_ret = callable->bindp(p_args, p_argcount); } + static Callable func_Callable_rebind(Callable *p_callable, Object *p_object) { + return p_callable->rebind(p_object); + } + static void func_Signal_emit(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { Signal *signal = VariantGetInternalPtr::get_ptr(v); signal->emit(p_args, p_argcount); @@ -2036,6 +2040,8 @@ static void _register_variant_builtin_methods() { bind_method(Callable, hash, sarray(), varray()); bind_method(Callable, bindv, sarray("arguments"), varray()); bind_method(Callable, unbind, sarray("argcount"), varray()); + // bind_method(Callable, rebind, sarray("object"), varray()); + bind_functionnc(Callable, rebind, _VariantCall::func_Callable_rebind, sarray("object"), varray()); bind_custom(Callable, call, _VariantCall::func_Callable_call, true, Variant); bind_custom(Callable, call_deferred, _VariantCall::func_Callable_call_deferred, false, Variant); diff --git a/doc/classes/Callable.xml b/doc/classes/Callable.xml index aa5c58884878..94c445d015c2 100644 --- a/doc/classes/Callable.xml +++ b/doc/classes/Callable.xml @@ -170,6 +170,12 @@ Returns [code]true[/code] if the callable's object exists and has a valid method name assigned, or is a custom callable. + + + + + + diff --git a/modules/gdscript/gdscript_lambda_callable.cpp b/modules/gdscript/gdscript_lambda_callable.cpp index e9fe17bb170d..a5ba40fb2a84 100644 --- a/modules/gdscript/gdscript_lambda_callable.cpp +++ b/modules/gdscript/gdscript_lambda_callable.cpp @@ -155,6 +155,10 @@ void GDScriptLambdaSelfCallable::call(const Variant **p_arguments, int p_argcoun } } +CallableCustom *GDScriptLambdaSelfCallable::rebind(const Object *p_object) const { + return memnew(GDScriptLambdaSelfCallable(const_cast(p_object), function, captures)); +} + GDScriptLambdaSelfCallable::GDScriptLambdaSelfCallable(Ref p_self, GDScriptFunction *p_function, const Vector &p_captures) { reference = p_self; object = p_self.ptr(); diff --git a/modules/gdscript/gdscript_lambda_callable.h b/modules/gdscript/gdscript_lambda_callable.h index 33bdf6dfc1e8..2fac9e5316d1 100644 --- a/modules/gdscript/gdscript_lambda_callable.h +++ b/modules/gdscript/gdscript_lambda_callable.h @@ -82,6 +82,8 @@ class GDScriptLambdaSelfCallable : public CallableCustom { ObjectID get_object() const override; void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override; + CallableCustom *rebind(const Object *p_object) const override; + GDScriptLambdaSelfCallable(Ref p_self, GDScriptFunction *p_function, const Vector &p_captures); GDScriptLambdaSelfCallable(Object *p_self, GDScriptFunction *p_function, const Vector &p_captures); virtual ~GDScriptLambdaSelfCallable() = default;