Await for deferred frame

Godot Version

4.2

Question

I have the current gdscript pseudocode:

func do_a():
  # Do stuff here.
  do_b.call_deferred()

func do_b():
  # Do some more stuff here, but at the end of the frame

This is working for me, but I don’t like how my logic is split in half. The first bit I need to happen at the start of the frame, then the next bit needs to happen at the end of this frame. I was hoping this could be simplified with await, something like below:

func do_stuff():
  # Do stuff here at start of frame.
  await <something idk>
  # Do some more stuff here, but at the end of the frame

But I don’t know what would be put in the triangle brackets. I know it needs a signal, but not sure how to give a signal that emits in the deferred update, assuming that’s possible.

await get_tree().process_frame should work I think.

I’m not sure when the process_frame signal is emitted exactly compared to when all the call_deferred stuff is called, but it’s sometime before _process() is called for the next frame…

No, I don’t think this is it, that signal will emit on the next frame, not the current one. I want a signal that emits at the end of this frame, similar to how call_deferred works. Perhaps the signal you suggested calls before the next frame’s code runs, but I do want it to happen on this frame to avoid any visual stuttering.

I tried creating the following function which seemed promising:

func wait_deferred() -> Signal:
	var deferred_signal := Signal(self, "deferred")
	deferred_signal.emit.call_deferred()
	return deferred_signal

func something():
	await wait_deferred()

but this throws an error:

Attempt to connect nonexistent signal 'deferred' to callable

What do you do to define a signal? There’s also the create_user_signal function, however I don’t see any way to get a reference to said signal for use with the await keyword

Aha got it, for anyone else who needs it:

signal deferred

func wait_deferred() -> Signal:
	var deferred_signal := Signal(deferred)
	deferred_signal.emit.call_deferred()
	return deferred_signal

func do_something():
	# Stuff happens here
	await wait_deferred()
	# Stuff happens here at the end of the current frame

The key was to define a signal, then make duplicates of it when needed. I’m not sure how to make signals from scratch at runtime…

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.