Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RefCounted object gets freed even when a Callable is referencing one of its methods #74990

Open
lilizoey opened this issue Mar 16, 2023 · 3 comments

Comments

@lilizoey
Copy link

lilizoey commented Mar 16, 2023

Godot version

4.0.stable

System information

Linux 5.10.167-1-MANJARO

Issue description

Creating a callable referencing a function from a RefCounted object does not ensure that the RefCounted object stays alive.

I would expect a callable to count as a reference for the ref-count.

Steps to reproduce

run

extends Node2D

class Foo extends RefCounted:
	func meow():
		print("meow")

var meow: Callable

func _ready():
	var foo = Foo.new()
	meow = foo.meow

func _process(delta):
	meow.call()

Godot will then error saying "Attempt to call function 'null::meow (Callable)' on a null instance."

Minimal reproduction project

N/A

@dalexeev
Copy link
Member

This affects core. Right now, only CallableCustom can hold a reference to RefCounted.

You can workaround this with a lambda:

extends Node2D

class Foo extends RefCounted:
    func meow():
        print("meow")

var meow: Callable

func _ready():
    var foo = Foo.new()

    meow = foo.meow
    print(meow.is_custom()) # false

    meow = func (): foo.meow()
    print(meow.is_custom()) # true

func _process(delta):
    meow.call()

@lilizoey
Copy link
Author

I found this initially when trying to convert rust closures into godot callables with gdextension (basically by creating an object specifically for calling that closure). and the above workaround wouldn't work for that use-case at least, since there's no way of making a lambda with gdextension as far as i know.

though it's good to know that something exists for gdscript at least.

@Trey2k
Copy link

Trey2k commented Jul 5, 2023

Ran into this issue while trying to find a work around for the current lack of support for CallableCustom's in GDExtension. Manually increasing the RefCount will just cause it to never be freed.

Edit:
I believe this is because the Callable constructor takes a const Object* reference. Being const it wont modify the RefCount. So this makes sense to me now and im unsure if its a bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants