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

C#: Can't bind extra arguments to callable #77799

Closed
MikeSchulze opened this issue Jun 3, 2023 · 7 comments
Closed

C#: Can't bind extra arguments to callable #77799

MikeSchulze opened this issue Jun 3, 2023 · 7 comments

Comments

@MikeSchulze
Copy link

MikeSchulze commented Jun 3, 2023

Godot version

v4.0.3.stable.mono.official.5222a99f5

System information

ALL

Issue description

I want to collect all emitted signals with his arguments plus my custom arguments.
Before there was a Bind method to add extra argument to the Callable but this is removed by #64930

This makes me imposible to delegate signals by using the signal name with additonal arguments.
All the examples I have found use actions like in this example:

var _t = GetTree().CreateTimer(1);
_t.Timeout += () => MySignalCallback(1, 2, 3);

This is not an option for me i iterrate over all possible signals from a custom Godot object, i do not have the signal actions.

I want to delegate emitted signals of an object to this function (including emitter and signal name):
private void OnSignalEmitted(Godot.GodotObject emitter, string signalName, params Godot.GodotObject[] signalArgs)

Steps to reproduce

Here is the parial code of my SignalCollector.

    public partial class SignalCollector : Godot.GodotObject
    {

        public void ConnectAllSignals(Godot.GodotObject emitter)
        {
            foreach (Godot.Collections.Dictionary signalDef in emitter.GetSignalList())
            {
                string signalName = (string)signalDef["name"];
                var cb = new Callable(this, nameof(OnSignalEmitted));
                emitter.Connect(signalName, cb);
            }
        }

        private void OnSignalEmitted() => Godot.GD.PrintS("A");
        private void OnSignalEmitted(Godot.GodotObject arg) => Godot.GD.PrintS("B", arg);
        
        // variable number of arguments is also not working
        private void OnSignalEmitted(params Godot.GodotObject[] args) => Godot.GD.PrintS("C", args, args.Length);

        private void OnSignalEmitted(Godot.GodotObject emitter, string signalName, params Godot.GodotObject[] args) => Godot.GD.PrintS(emitter, signalName, args);
    }
      var collector = new SignalCollectorTest();
      Node emitter = new Node();
      collector.ConnectAllSignals(emitter);

      AddChild(emitter);
      emitter.AddChild(new Node2D());

Minimal reproduction project

N/A

@RedworkDE
Copy link
Member

See the docs on this exact question: https://docs.godotengine.org/en/stable/tutorials/scripting/c_sharp/c_sharp_differences.html#callable

@MikeSchulze
Copy link
Author

MikeSchulze commented Jun 4, 2023

@RedworkDE thanks to pointing me to the right documentation ;)
It works but not for all kind of signals, maybe i do somthing wrong.
Here the updated version of the signal collector.

    public partial class SignalCollectorTest : Godot.GodotObject
    {

        public void ConnectAllSignals(Godot.GodotObject emitter)
        {
            foreach (Godot.Collections.Dictionary signalDef in emitter.GetSignalList())
            {
                string signalName = (string)signalDef["name"];
                var cb = Callable.From(() => OnSignalEmitted(emitter, signalName)); // not works
                emitter.Connect(signalName, cb);
            }
        }


        private void OnSignalEmitted(Godot.GodotObject emitter, string signalName) => Godot.GD.PrintS("A", emitter, signalName);

        private void OnSignalEmitted(Godot.GodotObject emitter, string signalName, Godot.Variant arg) => Godot.GD.PrintS("B", emitter, signalName, arg);

        private void OnSignalEmitted(Godot.Variant arg, Godot.GodotObject emitter, string signalName) => Godot.GD.PrintS("C", emitter, signalName, arg);

        private void OnSignalEmitted(Godot.GodotObject emitter, string signalName, params Godot.Variant[] args) => Godot.GD.PrintS("D", emitter, signalName, args);

        private void OnSignalEmitted(Godot.GodotObject emitter, string signalName, IEnumerable<Godot.Variant> args) => Godot.GD.PrintS("E", emitter, signalName, args);
    }

Signals without arguments are successful delegated to OnSignalEmitted#A.
But signals with arguements are failing with.
ERROR: 'System.ArgumentException: Invalid argument count for invoking callable. Expected 0 arguments, received 1. (Parameter 'args')'

I experimented with some convenience methods of OnSignalEmitted, but without success (OnSignalEmitted B,C,D, E are never called).

@MikeSchulze
Copy link
Author

@raulsntos Can you please take a look at my comments?

@MikeSchulze
Copy link
Author

any help is appreciated, it blocks me to build the signal monitor

@AThousandShips
Copy link
Member

If you need rapid response please turn to the other community channels, people have their own schedules and priorities with their time.

@MikeSchulze
Copy link
Author

ERROR: 'System.ArgumentException: Invalid argument count for invoking callable. Expected 0 arguments, received 1. (Parameter 'args')'

sorry I did not mean to rush anyone

@MikeSchulze
Copy link
Author

ok this issue can be closed i need to react on the signal argument count to build the callable

        private Callable BuildCallable(GodotObject emitter, string signalName, Godot.Collections.Array signalArguments)
        {
            switch (signalArguments.Count)
            {
                case 0:
                    return Callable.From(() => OnSignalEmitted(emitter, signalName, new Godot.Collections.Array<Variant>()));
                case 1:
                    return Callable.From<Godot.Variant>((arg) => OnSignalEmitted(emitter, signalName, arg));
                default:
                    throw new NotImplementedException();
            }
        }
        

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

5 participants