You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
2.7 KiB
55 lines
2.7 KiB
10 months ago
|
public class RPC
|
||
|
{
|
||
|
readonly IEnumerable<int> _targets; // null for "everyone"
|
||
|
IEnumerable<int> _except = null;
|
||
|
|
||
|
RPC(IEnumerable<int> targets) => _targets = targets;
|
||
|
|
||
|
public static RPC ToAll() => new(null);
|
||
|
|
||
|
public static RPC To(IEnumerable<int> peerIds) => new(peerIds);
|
||
|
public static RPC To(params int[] peerIds) => To((IEnumerable<int>)peerIds);
|
||
|
public static RPC To(int peerId) => To([ peerId ]);
|
||
|
|
||
|
public static RPC To(IEnumerable<Player> players) => To(players.Select(p => p.PeerId));
|
||
|
public static RPC To(params Player[] players) => To((IEnumerable<Player>)players);
|
||
|
public static RPC To(Player player) => To(player.PeerId);
|
||
|
|
||
|
public RPC Except(IEnumerable<int> peerIds) { _except = peerIds; return this; }
|
||
|
public RPC Except(params int[] peerIds) => Except((IEnumerable<int>)peerIds);
|
||
|
public RPC Except(int peerId) => Except([ peerId ]);
|
||
|
|
||
|
public RPC Except(IEnumerable<Player> players) => Except(players.Select(p => p.PeerId));
|
||
|
public RPC Except(params Player[] players) => Except((IEnumerable<Player>)players);
|
||
|
public RPC Except(Player player) => Except(player.PeerId);
|
||
|
|
||
|
public void Send(Action action)
|
||
|
=> SendInternal(GetNode(action), action.Method.Name, []);
|
||
|
public void Send<[MustBeVariant] T>(Action<T> action, T arg)
|
||
|
=> SendInternal(GetNode(action), action.Method.Name, Variant.From(arg));
|
||
|
public void Send<[MustBeVariant] T0, [MustBeVariant] T1>(Action<T0, T1> action, T0 arg0, T1 arg1)
|
||
|
=> SendInternal(GetNode(action), action.Method.Name, Variant.From(arg0), Variant.From(arg1));
|
||
|
public void Send<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2>(Action<T0, T1, T2> action, T0 arg0, T1 arg1, T2 arg2)
|
||
|
=> SendInternal(GetNode(action), action.Method.Name, Variant.From(arg0), Variant.From(arg1), Variant.From(arg2));
|
||
|
public void Send<[MustBeVariant] T0, [MustBeVariant] T1, [MustBeVariant] T2, [MustBeVariant] T3>(Action<T0, T1, T2, T3> action, T0 arg0, T1 arg1, T2 arg2, T3 arg3)
|
||
|
=> SendInternal(GetNode(action), action.Method.Name, Variant.From(arg0), Variant.From(arg1), Variant.From(arg2), Variant.From(arg3));
|
||
|
|
||
|
|
||
|
/// <summary> Returns the target of the instance method <paramref name="action"/> as a <see cref="Node"/>. </summary>
|
||
|
static Node GetNode(Delegate action)
|
||
|
=> (action.Target as Node) ?? throw new ArgumentException(
|
||
|
$"Target ({action.Target?.GetType().ToString() ?? "null"}) must be a Node", nameof(action));
|
||
|
|
||
|
void SendInternal(Node node, StringName method, params Variant[] args)
|
||
|
{
|
||
|
if ((_targets == null) && (_except == null))
|
||
|
node.Rpc(method, args);
|
||
|
else {
|
||
|
var targets = _targets ?? node.Multiplayer.GetPeers();
|
||
|
if (_except != null) targets = targets.Except(_except);
|
||
|
foreach (var target in targets)
|
||
|
node.RpcId(target, method, args);
|
||
|
}
|
||
|
}
|
||
|
}
|