godot-cpp icon indicating copy to clipboard operation
godot-cpp copied to clipboard

Callable supplied to GDExtension method doesn't remember its object

Open 2shady4u opened this issue 3 years ago • 2 comments

Code in GDScript:

extends Node

var cpp_class : CppClass = null

func _ready():
    var callable := Callable(self, "cool_method")
    print(callable.get_object())

    cpp_class = CppClass.new()
    cpp_class.test_function(cool_method)

func cool_method():
    pass

Code in C++:

void CppClass::test_function(Callable p_callable)
{
        UtilityFunctions::printerr(p_callable.get_object());
}

In GDScript this prints the correct object: Database:[Node:24696062342]

While in my C++ method this prints: [Object:null]

As a result I've been unable to use Calllables in my C++ GDExtension code 😅

Am I doing something horribly wrong? Or is there something missing?

2shady4u avatar Jun 04 '22 20:06 2shady4u

This is probably a poor workaround, but this worked for me (of course adjust to your needs). Not sure if it will work for every case.

GDScript

func _ready():
	var callable = Callable(self, "callable_func")
	$Example.do_call(callable)

func callable_func():
	print("this is a callable func")

C++

void Example::do_call(const Variant **args, GDNativeInt arg_count, GDNativeCallError &error)
{
    if (arg_count == 0) {
        UtilityFunctions::print("Callable function isn't valid");
        return;
    }

    UtilityFunctions::print("Valid callable function");

    StringName method_name = "call";
    Variant callable = *args[0];

    const Variant** call_args = nullptr;
    Variant result;
    GDNativeCallError err;
    callable.call(method_name, call_args, 0, result, err);
}

void Example::_bind_methods() {
    {
        MethodInfo mi;
        mi.arguments.push_back(PropertyInfo(Variant::STRING, "some_argument"));
        mi.name = "do_call";
        ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "do_call", &Example::do_call, mi);
    }
}

Again, this is just a workaround and I haven't tested multiple cases yet, just this simple one. Also, you'll probably want to make sure to check the type of the Variant and modify how args are being passed. This was just a quick test.

victorholt avatar Jul 16 '22 00:07 victorholt

@victorholt thanks, but I'm not really happy with that work-around 😛

Still doesn't work as of alpha 13

2shady4u avatar Aug 07 '22 16:08 2shady4u

This is now working correctly in beta 2

2shady4u avatar Oct 01 '22 11:10 2shady4u