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

Anonymous Functions with Bound Variables get lost on Build #76889

Open
CookieBadger opened this issue May 9, 2023 · 1 comment
Open

Anonymous Functions with Bound Variables get lost on Build #76889

CookieBadger opened this issue May 9, 2023 · 1 comment

Comments

@CookieBadger
Copy link
Contributor

CookieBadger commented May 9, 2023

Godot version

4.0.2 mono

System information

Windows 10

Issue description

Now this is a tough one. An EditorPlugin written in C# subscribes to a button via a lambda. If we change some C# file (outside of the plugin) and recompile the project, the subscription either gets lost or stays, depending on the captured variables of the lambda. If we capture a constant, it keeps working:

public override void _Ready() {    
    var button = new Button();
    button.Text = "Test captured constant";
    _addedControl.AddChild(button);
    button.Pressed += () => OnPressed(1);
}

public void OnPressed(int i) {
    GD.Print("Test Action successful: ", i);
}

LambdaBug

However, if we capture a variable in the lambda, upon changing a file outside the plugin and rebuilding the project, the signal now points to null.

public override void _Ready() {    
	  var button2 = new Button();
	  button2.Text = "Test captured variable";
	  _addedControl.AddChild(button2);
	  var i = 2;
	  button2.Pressed += () => OnPressed(i);
}

LambdaBug2

Weirdly enough, when I connect both buttons, one with the constant in the lambda, and the other with the variable in the lambda, none of them work after the rebuild, both now point to null!

Why is this a big problem

In some situations the captured variables in the lambdas are unavoidable. Lets say you have a list of buttons and need to know which one was pressed. When you make a C# plugin, you want it to function at all times in development, unless it is being changed. If you now program your gameplay logic in C#, every time you change something, the plugin breaks.

Maybe the much bigger problem here is the fact that the plugin is being recompiled at all. When nothing changed inside the addons folder, why would the plugin recompile after all.

Steps to reproduce

  1. Connect a signal in a plugin to a lambda and a captured variable.
  2. Enable the plugin
  3. Change some C# file.
  4. Recompile
  5. Observe the errors when the signal is emitted.

You can use the reproduction project, which adds a button to the side of the spatial view. Press the button to emit the signal. Change something in any C# file, press build, and press the button again. Observe that the method works if the button is connected to a lambda with constants only, but does not work if connected to a captured variable.

Minimal reproduction project

EditorPluginRebuildTest.zip

@ptlthg
Copy link

ptlthg commented May 2, 2024

I thought #83217 might have fixed this, but I can still reproduce this issue with the same error in 4.3dev6

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

3 participants