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

Can't get method on CallableCustom "Delegate::Invoke" error when using a lambda function in UndoRedo.AddDoMethod and UndoRedo.AddUndoMethod #90430

Open
robbertzzz opened this issue Apr 9, 2024 · 5 comments · Fixed by #92350

Comments

@robbertzzz
Copy link

robbertzzz commented Apr 9, 2024

Tested versions

Tested on v4.2.1.stable.mono.official [b09f793]

System information

Windows 11

Issue description

I'm converting a tool written in C# from a plugin to a runtime tool and have an undo function where a variable is being bound to the Callable. In C# this can only be done through a lambda, which is what I'm doing. However, unfortunately UndoRedo's AddDoMethod() and AddUndoMethod() throw the error Can't get method on CallableCustom "Delegate::Invoke" which from a quick look in the engine codebase means the function name isn't accessible (which is isn't, it's a lambda function).

Note that this is not the same issue as #70026 because it only happens when the UndoRedo functions are actually called, but it seems to be similar to #80434 except that that's in GDScript.

Steps to reproduce

Use any lambda function when calling UndoRedo.AddDoMethod or UndoRedo.AddUndoMethod, i.e., UndoRedo.AddUndoMethod(Callable.From(() => GD.Print("Hello World!")))

Minimal reproduction project (MRP)

UndoRedoLambdaBug.zip

Run the project, click the button, check the error log.

@raulsntos
Copy link
Member

It looks like UndoRedo tries to get the Callable's method name with Callable::get_method() and then falls back to Callable::operator String():

do_op.name = p_callable.get_method();
if (do_op.name == StringName()) {
// There's no `get_method()` for custom callables, so use `operator String()` instead.
do_op.name = static_cast<String>(p_callable);
}

The error can safely be ignored, but maybe we should implement CallableCustom::get_method like they did for GDScript in #80506.

@4d49
Copy link
Contributor

4d49 commented May 25, 2024

The problem also affects GDScript.

func _ready() -> void:
	var undo_redo := UndoRedo.new()

	var callable: Callable = func() -> void:
		pass

	undo_redo.add_do_method(callable)

I got error: Can't get method on CallableCustom "<anonymous lambda>(lambda)"

@KoBeWi
Copy link
Member

KoBeWi commented May 25, 2024

I got error: Can't get method on CallableCustom "(lambda)"

This doesn't seem to happen on master.

@4d49
Copy link
Contributor

4d49 commented May 25, 2024

This doesn't seem to happen on master.

I'm sorry! I must have made a mistake. Here's the correct example.

var undo_redo := UndoRedo.new()
var value: bool = false

func _ready() -> void:
	var do = func() -> void:
		value = true

	var undo = func() -> void:
		value = false

	undo_redo.create_action("test")
	undo_redo.add_do_method(do)
	undo_redo.add_undo_method(undo)
	undo_redo.commit_action()

@Chaosus
Copy link
Member

Chaosus commented Nov 20, 2024

Since #92350 is being reverted, I think this issue should be reopened(I can reproduce it).

@Chaosus Chaosus reopened this Nov 20, 2024
@Chaosus Chaosus modified the milestones: 4.3, 4.x Nov 20, 2024
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.

7 participants