Merge pull request #77688 from L4Vo5/clarify-deferred

Clear up misconceptions about when deferred things run in the docs
This commit is contained in:
Rémi Verschelde 2023-06-22 10:29:56 +02:00
commit d40c45ed99
No known key found for this signature in database
GPG key ID: C3336907360768E1
4 changed files with 28 additions and 14 deletions

View file

@ -108,11 +108,12 @@
<method name="call_deferred" qualifiers="vararg const">
<return type="void" />
<description>
Calls the method represented by this [Callable] in deferred mode, i.e. during the idle frame. Arguments can be passed and should match the method's signature.
Calls the method represented by this [Callable] in deferred mode, i.e. at the end of the current frame. Arguments can be passed and should match the method's signature.
[codeblock]
func _ready():
grab_focus.call_deferred()
[/codeblock]
See also [method Object.call_deferred].
</description>
</method>
<method name="callv" qualifiers="const">

View file

@ -656,6 +656,7 @@
<description>
Queues a node for deletion at the end of the current frame. When deleted, all of its child nodes will be deleted as well, and all references to the node and its children will become invalid, see [method Object.free].
It is safe to call [method queue_free] multiple times per frame on a node, and to [method Object.free] a node that is currently queued for deletion. Use [method Object.is_queued_for_deletion] to check whether a node will be deleted at the end of the frame.
The node will only be freed after all other deferred calls are finished, so using [method queue_free] is not always the same as calling [method Object.free] through [method Object.call_deferred].
</description>
</method>
<method name="remove_child">

View file

@ -315,7 +315,9 @@
<return type="Variant" />
<param index="0" name="method" type="StringName" />
<description>
Calls the [param method] on the object during idle time. This method supports a variable number of arguments, so parameters can be passed as a comma separated list.
Calls the [param method] on the object during idle time. Always returns null, [b]not[/b] the method's result.
Idle time happens mainly at the end of process and physics frames. In it, deferred calls will be run until there are none left, which means you can defer calls from other deferred calls and they'll still be run in the current idle time cycle. If not done carefully, this can result in infinite recursion without causing a stack overflow, which will hang the game similarly to an infinite loop.
This method supports a variable number of arguments, so parameters can be passed as a comma separated list.
[codeblocks]
[gdscript]
var node = Node3D.new()
@ -326,7 +328,17 @@
node.CallDeferred(Node3D.MethodName.Rotate, new Vector3(1f, 0f, 0f), 1.571f);
[/csharp]
[/codeblocks]
See also [method Callable.call_deferred].
[b]Note:[/b] In C#, [param method] must be in snake_case when referring to built-in Godot methods. Prefer using the names exposed in the [code]MethodName[/code] class to avoid allocating a new [StringName] on each call.
[b]Note:[/b] If you're looking to delay the function call by a frame, refer to the [signal SceneTree.process_frame] and [signal SceneTree.physics_frame] signals.
[codeblock]
var node = Node3D.new()
# Make a Callable and bind the arguments to the node's rotate() call.
var callable = node.rotate.bind(Vector3(1.0, 0.0, 0.0), 1.571)
# Connect the callable to the process_frame signal, so it gets called in the next process frame.
# CONNECT_ONE_SHOT makes sure it only gets called once instead of every frame.
get_tree().process_frame.connect(callable, CONNECT_ONE_SHOT)
[/codeblock]
</description>
</method>
<method name="callv">
@ -827,7 +839,7 @@
<param index="0" name="property" type="StringName" />
<param index="1" name="value" type="Variant" />
<description>
Assigns [param value] to the given [param property], after the current frame's physics step. This is equivalent to calling [method set] through [method call_deferred].
Assigns [param value] to the given [param property], at the end of the current frame. This is equivalent to calling [method set] through [method call_deferred].
[codeblocks]
[gdscript]
var node = Node2D.new()
@ -954,7 +966,7 @@
Notification received when the object is about to be deleted. Can act as the deconstructor of some programming languages.
</constant>
<constant name="CONNECT_DEFERRED" value="1" enum="ConnectFlags">
Deferred connections trigger their [Callable]s on idle time, rather than instantly.
Deferred connections trigger their [Callable]s on idle time (at the end of the frame), rather than instantly.
</constant>
<constant name="CONNECT_PERSIST" value="2" enum="ConnectFlags">
Persisting connections are stored when the object is serialized (such as when using [method PackedScene.pack]). In the editor, connections created through the Node dock are always persisting.

View file

@ -19,7 +19,7 @@
<param index="1" name="method" type="StringName" />
<description>
Calls [param method] on each member of the given group. You can pass arguments to [param method] by specifying them at the end of the method call. If a node doesn't have the given method or the argument list does not match (either in count or in types), it will be skipped.
[b]Note:[/b] [method call_group] will call methods immediately on all members at once, which can cause stuttering if an expensive method is called on lots of members. To wait for one frame after [method call_group] was called, use [method call_group_flags] with the [constant GROUP_CALL_DEFERRED] flag.
[b]Note:[/b] [method call_group] will call methods immediately on all members at once, which can cause stuttering if an expensive method is called on lots of members.
</description>
</method>
<method name="call_group_flags" qualifiers="vararg">
@ -33,7 +33,7 @@
# Call the method in a deferred manner and in reverse order.
get_tree().call_group_flags(SceneTree.GROUP_CALL_DEFERRED | SceneTree.GROUP_CALL_REVERSE)
[/codeblock]
[b]Note:[/b] Group call flags are used to control the method calling behavior. By default, methods will be called immediately in a way similar to [method call_group]. However, if the [constant GROUP_CALL_DEFERRED] flag is present in the [param flags] argument, methods will be called with a one-frame delay in a way similar to [method Object.set_deferred].
[b]Note:[/b] Group call flags are used to control the method calling behavior. By default, methods will be called immediately in a way similar to [method call_group]. However, if the [constant GROUP_CALL_DEFERRED] flag is present in the [param flags] argument, methods will be called at the end of the frame in a way similar to [method Object.set_deferred].
</description>
</method>
<method name="change_scene_to_file">
@ -42,7 +42,7 @@
<description>
Changes the running scene to the one at the given [param path], after loading it into a [PackedScene] and creating a new instance.
Returns [constant OK] on success, [constant ERR_CANT_OPEN] if the [param path] cannot be loaded into a [PackedScene], or [constant ERR_CANT_CREATE] if that scene cannot be instantiated.
[b]Note:[/b] The scene change is deferred, which means that the new scene node is added on the next idle frame. This ensures that both scenes are never loaded at the same time, which can exhaust system resources if the scenes are too large or if running in a memory constrained environment. As such, you won't be able to access the loaded scene immediately after the [method change_scene_to_file] call.
[b]Note:[/b] The scene change is deferred, which means that the new scene node is added to the tree at the end of the frame. This ensures that both scenes aren't running at the same time, while still freeing the previous scene in a safe way similar to [method Node.queue_free]. As such, you won't be able to access the loaded scene immediately after the [method change_scene_to_file] call.
</description>
</method>
<method name="change_scene_to_packed">
@ -51,7 +51,7 @@
<description>
Changes the running scene to a new instance of the given [PackedScene] (which must be valid).
Returns [constant OK] on success, [constant ERR_CANT_CREATE] if the scene cannot be instantiated, or [constant ERR_INVALID_PARAMETER] if the scene is invalid.
[b]Note:[/b] The scene change is deferred, which means that the new scene node is added on the next idle frame. You won't be able to access it immediately after the [method change_scene_to_packed] call.
[b]Note:[/b] The scene change is deferred, which means that the new scene node is added to the tree at the end of the frame. You won't be able to access it immediately after the [method change_scene_to_packed] call.
</description>
</method>
<method name="create_timer">
@ -144,7 +144,7 @@
<param index="1" name="notification" type="int" />
<description>
Sends the given notification to all members of the [param group].
[b]Note:[/b] [method notify_group] will immediately notify all members at once, which can cause stuttering if an expensive method is called as a result of sending the notification lots of members. To wait for one frame, use [method notify_group_flags] with the [constant GROUP_CALL_DEFERRED] flag.
[b]Note:[/b] [method notify_group] will immediately notify all members at once, which can cause stuttering if an expensive method is called as a result of sending the notification to lots of members.
</description>
</method>
<method name="notify_group_flags">
@ -154,14 +154,14 @@
<param index="2" name="notification" type="int" />
<description>
Sends the given notification to all members of the [param group], respecting the given [enum GroupCallFlags].
[b]Note:[/b] Group call flags are used to control the notification sending behavior. By default, notifications will be sent immediately in a way similar to [method notify_group]. However, if the [constant GROUP_CALL_DEFERRED] flag is present in the [param call_flags] argument, notifications will be sent with a one-frame delay in a way similar to using [code]Object.call_deferred("notification", ...)[/code].
[b]Note:[/b] Group call flags are used to control the notification sending behavior. By default, notifications will be sent immediately in a way similar to [method notify_group]. However, if the [constant GROUP_CALL_DEFERRED] flag is present in the [param call_flags] argument, notifications will be sent at the end of the current frame in a way similar to using [code]Object.call_deferred("notification", ...)[/code].
</description>
</method>
<method name="queue_delete">
<return type="void" />
<param index="0" name="obj" type="Object" />
<description>
Queues the given object for deletion, delaying the call to [method Object.free] to after the current frame.
Queues the given object for deletion, delaying the call to [method Object.free] to the end of the current frame.
</description>
</method>
<method name="quit">
@ -188,7 +188,7 @@
<param index="2" name="value" type="Variant" />
<description>
Sets the given [param property] to [param value] on all members of the given group.
[b]Note:[/b] [method set_group] will set the property immediately on all members at once, which can cause stuttering if a property with an expensive setter is set on lots of members. To wait for one frame, use [method set_group_flags] with the [constant GROUP_CALL_DEFERRED] flag.
[b]Note:[/b] [method set_group] will set the property immediately on all members at once, which can cause stuttering if a property with an expensive setter is set on lots of members.
</description>
</method>
<method name="set_group_flags">
@ -199,7 +199,7 @@
<param index="3" name="value" type="Variant" />
<description>
Sets the given [param property] to [param value] on all members of the given group, respecting the given [enum GroupCallFlags].
[b]Note:[/b] Group call flags are used to control the property setting behavior. By default, properties will be set immediately in a way similar to [method set_group]. However, if the [constant GROUP_CALL_DEFERRED] flag is present in the [param call_flags] argument, properties will be set with a one-frame delay in a way similar to [method Object.call_deferred].
[b]Note:[/b] Group call flags are used to control the property setting behavior. By default, properties will be set immediately in a way similar to [method set_group]. However, if the [constant GROUP_CALL_DEFERRED] flag is present in the [param call_flags] argument, properties will be set at the end of the frame in a way similar to [method Object.call_deferred].
</description>
</method>
<method name="set_multiplayer">
@ -311,7 +311,7 @@
Call a group in reverse scene order.
</constant>
<constant name="GROUP_CALL_DEFERRED" value="2" enum="GroupCallFlags">
Call a group with a one-frame delay (idle frame, not physics).
Call a group at the end of the current frame (process or physics).
</constant>
<constant name="GROUP_CALL_UNIQUE" value="4" enum="GroupCallFlags">
Call a group only once even if the call is executed many times.