Can Godot and GDScript store functions in variables?
Asked Answered
Y

2

17

I am confused by part of the Godot Docs for the GDScript language. About midway down the page, in the "Referencing Functions" section, it says you can't store functions in variables, and then seems to immediately contradict itself.

Can Godot functions be stored in variables or not?

Referencing Functions

Contrary to Python, functions are not first class objects in GDScript. This means they cannot be stored in variables, passed as an argument to another function or be returned from other functions. This is for performance reasons.

To reference a function by name at runtime, (e.g. to store it in a variable, or pass it to another function as an argument) one must use the call or funcref helpers:

Yolondayon answered 15/1, 2019 at 17:46 Comment(0)
H
24

GDScript functions are not objects like they are in python. So, you cannot directly reference a function.

However, you can indirectly reference them by name using their associated instance.

For example with the following function:

func hello():
    print('Hello')

You can call a function on an instance by name:

call('hello') # prints 'Hello'

You can store an instance and function name with funcref():

var ref = funcref(hello_object_instance, 'hello')
ref.call_func() # prints 'Hello'
takes_func_ref_to_call_later(ref) # later, prints 'Hello'

FuncRef.call_func() does the same thing as Object.call() it just wraps it in an object.

Consequently, a common pattern for callback functions, as shown by Object.connect() and friends, is:

func deferred_finish(param1, param2, callback_obj, callback_func):
    # ... do something
    callback_ref = funcref(callback_obj, callback_func)
func _process(delta):
    if _finished:
        callback_ref.call_func()
func _enter_tree():
    deferred_finish('hello', 'world', self, 'finished_callback')

I hope this helps. Let me know if you would like any clarifications.

Hardan answered 18/1, 2019 at 3:16 Comment(2)
Just to add: There are plans to add function-variables and lambda syntax in Godot 3.2, see github.com/godotengine/godot-roadmap/issues/23. Given the existing release history, that may well happen in 2020.Calomel
Update mentioned in @Calomel 's comment seems postponed to version 4.0.Psychotherapy
C
5

It's not available in 3.x as far as I know, but it is a feature in Godot 4.0, see the docs on referencing functions (and the following section on lambdas

Basically you can declare a variable using

var f = func foo(x):
    <function body>

and then f.call(x) to call the function stored in that variable.

Chalcidice answered 15/2, 2023 at 16:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.