Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Actions with variable argument count

I'm working with Unity networking, and I'm writing a method that calls another one over the network. Currently I have a bunch of methods that look like

void Call<A>(Action<A> method, A arg) {
    _networkView.RPC(method.Method.Name, RPCMode.Others, arg);
}

void Call<A,B>(Action<A,B> method, A arg1, B arg2) {
    _networkView.RPC(method.Method.Name, RPCMode.Others, arg1, arg2);
}

... And so on

There are also variants to call it on a specific player and a system to make it work with Photon Cloud. So there are a whole lot of these methods, and it's getting very cluttered.

Now, I was wondering if it's possible to have an Action that can have any amount of arguments. So I can make something like:

void Call(Action method, params object[] args) {
    _networkView.RPC(method.Method.Name, RPCMode.Others, args);
}

Is this possible?

Thanks!

like image 948
The Oddler Avatar asked Jan 24 '26 01:01

The Oddler


1 Answers

Actions with variable argument count

It is possible:

public delegate void ParamArrayAction<V>(params V[] variableArgs);
public delegate void ParamArrayAction<F, V>(F fixedArg, params V[] variableArgs);
public delegate void ParamArrayAction<F1, F2, V>(F1 fixedArg1, F2 fixedArg2, params V[] variableArgs);
public delegate void ParamArrayAction<F1, F2, F3, V>(F1 fixedArg1, F2 fixedArg2, F3 fixedArg3, params V[] variableArgs);

Your problem

But it's not what you ask for. Actually, you are asking for some magic delegate type to which any method is assignable. As far as I know it's impossible.

This is quite strange (or, maybe, I don't understand something). As far as I understand, you have whole bunch of methods like this

void Call<A>(Action<A> method, A arg) {
    _networkView.RPC(method.Method.Name, RPCMode.Others, arg);
}

void Call<A, B>(Action<A, B> method, A arg1, B arg2) {
    _networkView.RPC(method.Method.Name, RPCMode.Others, arg1, arg2);
}

.....

void Call<A, B, C, D>(Action<A, B, C, D> method, A arg1, B arg2, C arg3, D arg4) {
    _networkView.RPC(method.Method.Name, RPCMode.Others, arg1, arg2, arg3, arg4);
}

.....

And then you use them like this:

[RPC]
void DoSomething(string someText, int someValue)
{
    // Bla-bla-bla
}

.....

void SomeRPCCallingMethod()
{
    // Bla-bla-bla
    Call(DoSomething, "Hello, World!", 42);
    // Bla-bla-bla
}

And I kinda like it. It adds compile time check for method params. Which is good. What I don't understand is:

there are a whole lot of these methods

Why? I'm not familiar with Unity's RPC. But anyway, you can:

  1. Create a separate class which will encapsulate NetworkView and Call<> methods.
  2. Add RPCMode as a parameter to Call<> methods.

If you still want to do it, do it like this:

    void Call(string methodName, params object[] args) {
        _networkView.RPC(methodName, RPCMode.Others, args);
    }

Usage:

    [RPC]
    void DoSomething(string someText, int someValue)
    {
        // Bla-bla-bla
    }

    .....

    void SomeRPCCallingMethod()
    {
        // Bla-bla-bla
        Call("DoSomething", "Hello, World!", 42);
        // Bla-bla-bla
    }
like image 142
Sergey Krusch Avatar answered Jan 26 '26 14:01

Sergey Krusch