diff --git a/util/CallableNode.gd b/util/CallableNode.gd index 6620031..b3b9468 100644 --- a/util/CallableNode.gd +++ b/util/CallableNode.gd @@ -11,7 +11,11 @@ var result: Variant = null ## Calls the CallableNode, waits for it to finish, and returns its result. ## ## When a CallableNode is called, the following sequence of events occurs: -## 1. if the CallableNode is in the tree, it is removed; +## 1. we wait for the parent node to be in the tree +## and self to be out of the tree at the same time +## (if this never happens, then the function will never terminate, +## and thus any await subscribers will never be notified +## and will themselves never terminate); ## 2. the CallableNode is passed the given args and opts; ## 3. the CallableNode is requested to call _ready, ## and then added as a child to the parent; @@ -34,8 +38,9 @@ func invoke_existing( var prev_process_mode := process_mode var parent_prev_process_mode := parent.process_mode # step 1 - if is_inside_tree(): - get_parent().remove_child(self) + var ok := func() -> bool: + return parent.is_inside_tree() and not is_inside_tree() + await Wait.until(ok) # step 2 args = p_args opts = p_opts @@ -76,18 +81,18 @@ func invoke_existing( static func invoke( what: Variant, parent: Node, - args: Array = [], - opts: Dictionary = {} + p_args: Array = [], + p_opts: Dictionary = {} ) -> Variant: if what is CallableNode: - return await what.invoke_existing(parent, args, opts) + return await what.invoke_existing(parent, p_args, p_opts) elif what is PackedScene: var inst := what.instantiate() as Node var cn := inst as CallableNode if cn: - var result = await cn.invoke_existing(parent, args, opts) + var p_result = await cn.invoke_existing(parent, p_args, p_opts) cn.queue_free() - return result + return p_result elif inst: push_error( "Tried to invoke a PackedScene " + @@ -102,9 +107,9 @@ static func invoke( var inst = what.new() var cn := inst as CallableNode if cn: - var result = await cn.invoke_existing(parent, args, opts) + var p_result = await cn.invoke_existing(parent, p_args, p_opts) cn.queue_free() - return result + return p_result elif inst: push_error( "Tried to invoke a GDScript not derived from CallableNode: " + @@ -116,7 +121,7 @@ static func invoke( else: return null elif what is String: - return await CallableNode.invoke(load(what), parent, args, opts) + return await CallableNode.invoke(load(what), parent, p_args, p_opts) else: push_error("No way to infer a CallableNode from value: %s" % what) return null