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

Don't remove the owner immediately #39835

Closed
wants to merge 1 commit into from

Conversation

KoBeWi
Copy link
Member

@KoBeWi KoBeWi commented Jun 25, 2020

Closes #22840

The question is whether setting owner to null immediately in NOTIFICATION_PREDELETE was done for a reason or the order doesn't matter (but some code might still rely on the old order). I did a quick test and didn't notice any unusual behavior.

Also here's a test code:

func _ready():
	var se1f = self
	$Node2D.connect("tree_exiting", Callable(se1f, "exiting"), [$Node2D])
	$Node2D.connect("tree_exited", Callable(se1f, "exited"), [$Node2D])
	$Node2D.free()

func exiting(node):
	print(node.owner) #prints node; before it was null

func exited(node):
	print(node.owner) #prints null

@KoBeWi KoBeWi added this to the 4.0 milestone Jun 25, 2020
@KoBeWi KoBeWi requested a review from reduz June 25, 2020 19:54
if (data.parent) {
data.parent->remove_child(this);
data.parent->remove_child(this); // This also removes the owner.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure about this? From a quick look at remove_child() and the follow-up call to _propagate_validate_owner(), it doesn't seem strictly equivalent to the while loop above removing all owners.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The node loses its parent, _propagate_validate_owner will search for current owner in node's ancestors and will remove the owner if it's not found (which will happen, because the parent was removed).

Although this probably needs to be tested with instanced scenes, because they have different owner...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, instanced scenes are broken. Here's a test case (replace code in OP):

$Node2D/Node.connect("tree_exiting", Callable(self, StringName("exiting")), [$Node2D/Node])
$Node2D/Node.connect("tree_exited", Callable(self, StringName("exited")), [$Node2D/Node])
$Node2D.free()

Node2D is an instanced scene with a Node child. Seems like Node will never lose its owner (prints the node in both cases, while previously it was both nulls).

Not sure how to fix this other than by forcing the removal of owner inside remove_child (which would require some hacks probably).

@mhilbrunner
Copy link
Member

PR meeting: reduz says the original code is indeed fishy, but we need to research/review and make sure to test it, also maybe @RandomShaper could have a look

@RandomShaper
Copy link
Member

I checked this trying to suggest some changes, but in the end I've needed to check the issue deeply and that has lead to a very different approach I've opened a PR for: #55512.

@akien-mga
Copy link
Member

Superseded by #55512.

@akien-mga akien-mga closed this Jan 5, 2022
@KoBeWi KoBeWi deleted the late_owner branch January 5, 2022 09:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Owner variable is null on tree_exiting signal
4 participants