using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
#nullable enable
namespace Capnp.Rpc
{
///
/// Combines multiple skeletons to represent objects which implement multiple interfaces.
///
public class PolySkeleton: Skeleton
{
readonly Dictionary _ifmap = new Dictionary();
///
/// Adds a skeleton to this instance.
///
/// Interface ID
/// Skeleton to add
/// is null.
/// A skeleton with was already added.
public void AddInterface(ulong interfaceId, Skeleton skeleton)
{
if (skeleton == null)
throw new ArgumentNullException(nameof(skeleton));
skeleton.Claim();
_ifmap.Add(interfaceId, skeleton);
}
internal void AddInterface(Skeleton skeleton)
{
AddInterface(((IMonoSkeleton)skeleton).InterfaceId, skeleton);
}
///
/// Calls an interface method of this capability.
///
/// ID of interface to call
/// ID of method to call
/// Method arguments ("params struct")
/// Cancellation token, indicating when the call should cancelled.
/// A Task which will resolve to the call result
public override Task Invoke(ulong interfaceId, ushort methodId, DeserializerState args, CancellationToken cancellationToken = default)
{
if (_ifmap.TryGetValue(interfaceId, out var skel))
return skel.Invoke(interfaceId, methodId, args, cancellationToken);
throw new NotImplementedException("Unknown interface id");
}
///
/// Dispose pattern implementation
///
protected override void Dispose(bool disposing)
{
foreach (var cap in _ifmap.Values)
{
cap.Relinquish();
}
base.Dispose(disposing);
}
internal override void Bind(object impl)
{
foreach (Skeleton skel in _ifmap.Values)
{
skel.Bind(impl);
}
}
}
}
#nullable restore