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

node.duplicate(7) fails to duplicate signals for specific ownership configuration #39119

Closed
adabru opened this issue May 28, 2020 · 1 comment · Fixed by #39390
Closed

node.duplicate(7) fails to duplicate signals for specific ownership configuration #39119

adabru opened this issue May 28, 2020 · 1 comment · Fixed by #39390
Milestone

Comments

@adabru
Copy link

adabru commented May 28, 2020

There were some issues with duplicating signals before:
#1888
#5405

Godot version: 3.2.1.stable

OS/device including version: Arch Linux

Issue description:
Duplicated node loses signal-connections of children. This happens only in the case that the duplicated node is not a scene and it has a descendant that is a scene with descendants that have signal-connections.

Steps to reproduce:
Open the minimal reproduction project. Click on button "node.duplicate(7)", then click on button "workaround duplicate(7)", then click on button "node.duplicate(15)". Each click duplicates the node $DuplicateMe in a different way and adds it to the main scene. The duplicated node contains a descendant whose "ready" signal is connected to a printout. The first button with the code node.duplicate(7) misses the printout. The output is:


--- Debugging process started ---
Godot Engine v3.2.1.stable.official - https://godotengine.org
OpenGL ES 2.0 Renderer: Mesa DRI Intel(R) HD Graphics 4000 (IVB GT2)

received ready signal!

┌─ $DuplicateMe.duplicate(7) ────────────
│ Original Scene2.owner: SceneMain
│ Original Scene2/Receive.owner: Scene2
│ Duplicate Scene2.owner: Null
│ Duplicate Scene2/Receive.owner: Null
│ incoming connections: []
└─────────────────────────────────────
┌─ workaround ────────────
│ Original Scene2.owner: DuplicateMe
│ Original Scene2/Receive.owner: DuplicateMe
│ Duplicate Scene2.owner: Null
│ Duplicate Scene2/Receive.owner: Null
│ incoming connections: [{method_name:_on_IDoEmit_ready, signal_name:ready, source:[Node:1340]}]
└─────────────────────────────────────
received ready signal!

┌─ $DuplicateMe.duplicate(15) ────────────
│ Original Scene2.owner: SceneMain
│ Original Scene2/Receive.owner: Scene2
│ Duplicate Scene2.owner: Null
│ Duplicate Scene2/Receive.owner: Scene2
│ incoming connections: [{method_name:_on_IDoEmit_ready, signal_name:ready, source:[Node:1403]}]
└─────────────────────────────────────
received ready signal!

The workaround precedes the duplicate(7) with a recursive own on the duplicated node $DuplicateMe:

  var nodes = $DuplicateMe.get_children()
  while len(nodes) > 0:
    var node = nodes.pop_front()
    node.owner = $DuplicateMe
    nodes += node.get_children()
  var duplicate = $DuplicateMe.duplicate(7)

I didn't compile godot yet, but a possible solution might add some mechanism to Node::_duplicate_signals(const Node *p_original, Node *p_copy) that changes p_original to any encountered scene-instance with the same owner as the node the duplicate call was made on before it calls get_child(i)->_duplicate_signals(p_original, p_copy); or something similar.

Minimal reproduction project:
Signal Duplication.zip

@Calinou
Copy link
Member

Calinou commented Jun 2, 2020

For the record, the value 7 corresponds to the flags DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants