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

Building C# solution leads to errors if signals are connected in the editor #102455

Open
Lennart-Bours opened this issue Feb 5, 2025 · 1 comment

Comments

@Lennart-Bours
Copy link

Tested versions

v4.3.stable.mono.official [77dcf97]

System information

Godot v4.3.stable.mono - Windows 10.0.19045 - Vulkan (Forward+) - dedicated AMD Radeon RX 6700 XT (Advanced Micro Devices, Inc.; 32.0.11027.2001) - AMD Ryzen 5 7600X 6-Core Processor (12 Threads)

Issue description

I have a CustomNode class that holds data in a CustomResource class. When a value of this Resource is changed in the editor, I want to execute code. However, subscribing to the Resource "changed" event, leads to errors if the C# solution is rebuild and the scene is closed.

Steps to reproduce

Setup
Create a Node derived [Tool] script with a resource field. Create a Resource derived [Tool] class with a property that calls emit_changed() in the setter. In the CustomNode class, subscribe to the Resource's changed event in _ready. I'm using += and -= to connect and disconnect the signal.

Reproducing the error

  • Open the scene (CustomNode subscribes to CustomResource's changed event)
  • Rebuild C# solution
  • Signal is unconnected after deserialization
  • Close or reload scene -> error: Attempt to disconnect a nonexistent connection from '<Resource#-...>'. Signal: 'changed', callable: 'Delegate::Invoke'.
  • Rebuild C# solution again -> error System.ObjectDisposedException: Cannot access a disposed object. Object name: 'CustomNode'. -> failed to unload assemblies (related issue .NET: Failed to unload assemblies. Please check <this issue> for more information. #78513)

Workaround
It seems this error can be worked aroud by

  • Using ISerializationListener to un- and resubscribe to the signal before and after serialization
  • Using _Notification to unubscribe from the signal on the "predelete" notification

Note this workaround relies on the undocumented ISerializationListener which apparently should not be used: godotengine/godot-docs#10615

Variant without workaround
The error also occurs when connecting to the signal in a CustomNode CustomResource property, as suggested in the manual. When using the property, the signal is automatically reconnected after the build as the setter is called. However, the "predelete" workaround somehow doesn't prevent the error when the scene is closed.

Related Issues
#84394 (possible duplicate)
#70026
#70414

Informative issue on the (de)serialization process: godotengine/godot-proposals#9001

Minimal reproduction project (MRP)

signal-errors.zip

@Lennart-Bours
Copy link
Author

I'm not sure if it is related, but I've noted that the life of [Tool] Resource objects in the editor is different from what I expected.

Once a scene holding a [Tool] Resource has been opened, or a [Tool] Resource on disc has been opened in the inspector, that Resource continues to live on in the editor. On subsequent recompilation, its parameterless constructor and its setters will be called.

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

No branches or pull requests

2 participants