diff --git a/Dalamud/Plugin/Ipc/ICallGateProvider.cs b/Dalamud/Plugin/Ipc/ICallGateProvider.cs
index cf4c59b2e..1d160d9cb 100644
--- a/Dalamud/Plugin/Ipc/ICallGateProvider.cs
+++ b/Dalamud/Plugin/Ipc/ICallGateProvider.cs
@@ -4,27 +4,37 @@
namespace Dalamud.Plugin.Ipc;
-///
-public interface ICallGateProvider
+///
+/// The backing interface for the provider ("server") half of an IPC channel. This interface is used to expose methods
+/// to other plugins via RPC, as well as to allow other plugins to subscribe to notifications from this plugin.
+///
+public interface ICallGateProvider
{
- ///
- public void RegisterAction(Action action);
-
- ///
- public void RegisterFunc(Func func);
-
+ ///
+ public int SubscriptionCount { get; }
+
///
public void UnregisterAction();
///
public void UnregisterFunc();
+}
+
+///
+public interface ICallGateProvider : ICallGateProvider
+{
+ ///
+ public void RegisterAction(Action action);
+
+ ///
+ public void RegisterFunc(Func func);
///
public void SendMessage();
}
-///
-public interface ICallGateProvider
+///
+public interface ICallGateProvider : ICallGateProvider
{
///
public void RegisterAction(Action action);
@@ -32,18 +42,12 @@ public interface ICallGateProvider
///
public void RegisterFunc(Func func);
- ///
- public void UnregisterAction();
-
- ///
- public void UnregisterFunc();
-
///
public void SendMessage(T1 arg1);
}
-///
-public interface ICallGateProvider
+///
+public interface ICallGateProvider : ICallGateProvider
{
///
public void RegisterAction(Action action);
@@ -51,18 +55,12 @@ public interface ICallGateProvider
///
public void RegisterFunc(Func func);
- ///
- public void UnregisterAction();
-
- ///
- public void UnregisterFunc();
-
///
public void SendMessage(T1 arg1, T2 arg2);
}
-///
-public interface ICallGateProvider
+///
+public interface ICallGateProvider : ICallGateProvider
{
///
public void RegisterAction(Action action);
@@ -70,18 +68,12 @@ public interface ICallGateProvider
///
public void RegisterFunc(Func func);
- ///
- public void UnregisterAction();
-
- ///
- public void UnregisterFunc();
-
///
public void SendMessage(T1 arg1, T2 arg2, T3 arg3);
}
-///
-public interface ICallGateProvider
+///
+public interface ICallGateProvider : ICallGateProvider
{
///
public void RegisterAction(Action action);
@@ -89,18 +81,12 @@ public interface ICallGateProvider
///
public void RegisterFunc(Func func);
- ///
- public void UnregisterAction();
-
- ///
- public void UnregisterFunc();
-
///
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
}
-///
-public interface ICallGateProvider
+///
+public interface ICallGateProvider : ICallGateProvider
{
///
public void RegisterAction(Action action);
@@ -108,18 +94,12 @@ public interface ICallGateProvider
///
public void RegisterFunc(Func func);
- ///
- public void UnregisterAction();
-
- ///
- public void UnregisterFunc();
-
///
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
}
-///
-public interface ICallGateProvider
+///
+public interface ICallGateProvider : ICallGateProvider
{
///
public void RegisterAction(Action action);
@@ -127,18 +107,12 @@ public interface ICallGateProvider
///
public void RegisterFunc(Func func);
- ///
- public void UnregisterAction();
-
- ///
- public void UnregisterFunc();
-
///
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
}
-///
-public interface ICallGateProvider
+///
+public interface ICallGateProvider : ICallGateProvider
{
///
public void RegisterAction(Action action);
@@ -146,18 +120,12 @@ public interface ICallGateProvider
///
public void RegisterFunc(Func func);
- ///
- public void UnregisterAction();
-
- ///
- public void UnregisterFunc();
-
///
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
}
-///
-public interface ICallGateProvider
+///
+public interface ICallGateProvider : ICallGateProvider
{
///
public void RegisterAction(Action action);
@@ -165,12 +133,6 @@ public interface ICallGateProvider
///
public void RegisterFunc(Func func);
- ///
- public void UnregisterAction();
-
- ///
- public void UnregisterFunc();
-
///
public void SendMessage(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
}
diff --git a/Dalamud/Plugin/Ipc/ICallGateSubscriber.cs b/Dalamud/Plugin/Ipc/ICallGateSubscriber.cs
index 40d642a61..fd67ec7db 100644
--- a/Dalamud/Plugin/Ipc/ICallGateSubscriber.cs
+++ b/Dalamud/Plugin/Ipc/ICallGateSubscriber.cs
@@ -4,8 +4,21 @@
namespace Dalamud.Plugin.Ipc;
+///
+/// An interface for all IPC subscribers.
+///
+public interface ICallGateSubscriber
+{
+
+ ///
+ public bool HasAction { get; }
+
+ ///
+ public bool HasFunction { get; }
+}
+
///
-public interface ICallGateSubscriber
+public interface ICallGateSubscriber : ICallGateSubscriber
{
///
public void Subscribe(Action action);
@@ -21,7 +34,7 @@ public interface ICallGateSubscriber
}
///
-public interface ICallGateSubscriber
+public interface ICallGateSubscriber : ICallGateSubscriber
{
///
public void Subscribe(Action action);
@@ -37,7 +50,7 @@ public interface ICallGateSubscriber
}
///
-public interface ICallGateSubscriber
+public interface ICallGateSubscriber : ICallGateSubscriber
{
///
public void Subscribe(Action action);
@@ -53,7 +66,7 @@ public interface ICallGateSubscriber
}
///
-public interface ICallGateSubscriber
+public interface ICallGateSubscriber : ICallGateSubscriber
{
///
public void Subscribe(Action action);
@@ -69,7 +82,7 @@ public interface ICallGateSubscriber
}
///
-public interface ICallGateSubscriber
+public interface ICallGateSubscriber : ICallGateSubscriber
{
///
public void Subscribe(Action action);
@@ -84,7 +97,7 @@ public interface ICallGateSubscriber
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
}
-///
+/// : ICallGateSubscriber
public interface ICallGateSubscriber
{
///
@@ -100,7 +113,7 @@ public interface ICallGateSubscriber
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
}
-///
+/// : ICallGateSubscriber
public interface ICallGateSubscriber
{
///
@@ -116,7 +129,7 @@ public interface ICallGateSubscriber
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
}
-///
+/// : ICallGateSubscriber
public interface ICallGateSubscriber
{
///
@@ -132,7 +145,7 @@ public interface ICallGateSubscriber
public TRet InvokeFunc(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
}
-///
+/// : ICallGateSubscriber
public interface ICallGateSubscriber
{
///
diff --git a/Dalamud/Plugin/Ipc/Internal/CallGatePubSubBase.cs b/Dalamud/Plugin/Ipc/Internal/CallGatePubSubBase.cs
index b6a4e8a61..308457373 100644
--- a/Dalamud/Plugin/Ipc/Internal/CallGatePubSubBase.cs
+++ b/Dalamud/Plugin/Ipc/Internal/CallGatePubSubBase.cs
@@ -16,71 +16,118 @@ protected CallGatePubSubBase(string name)
this.Channel = Service.Get().GetOrCreateChannel(name);
}
+ ///
+ /// Gets a value indicating whether this IPC call gate has an associated Action. Only exposed to
+ /// s.
+ ///
+ public bool HasAction => this.Channel.Action != null;
+
+ ///
+ /// Gets a value indicating whether this IPC call gate has an associated Function. Only exposed to
+ /// s.
+ ///
+ public bool HasFunction => this.Channel.Func != null;
+
+ ///
+ /// Gets the count of subscribers listening for messages through this call gate. Only exposed to
+ /// s, and can be used to determine if messages should be sent through the gate.
+ ///
+ public int SubscriptionCount => this.Channel.Subscriptions.Count;
+
///
/// Gets the underlying channel implementation.
///
protected CallGateChannel Channel { get; init; }
-
+
///
- /// Removes a registered Action from inter-plugin communication.
+ /// Removes the associated Action from this call gate, effectively disabling RPC calls.
///
+ ///
public void UnregisterAction()
=> this.Channel.Action = null;
///
- /// Removes a registered Func from inter-plugin communication.
+ /// Removes the associated Function from this call gate.
///
+ ///
public void UnregisterFunc()
=> this.Channel.Func = null;
///
- /// Registers an Action for inter-plugin communication.
+ /// Registers a for use by other plugins via RPC. This Delegate must satisfy the constraints
+ /// of an type as defined by the interface, meaning they may not return a value and must have
+ /// the proper number of parameters.
///
/// Action to register.
+ ///
+ ///
private protected void RegisterAction(Delegate action)
=> this.Channel.Action = action;
///
- /// Registers a Func for inter-plugin communication.
+ /// Registers a for use by other plugins via RPC. This Delegate must satisfy the constraints
+ /// of a type as defined by the interface, meaning its return type and parameters must
+ /// match accordingly.
///
/// Func to register.
+ ///
+ ///
private protected void RegisterFunc(Delegate func)
=> this.Channel.Func = func;
///
- /// Subscribe an expression to this registration.
+ /// Registers a (of type ) that will be called when the providing
+ /// plugin calls . This method can be used to receive notifications
+ /// of events or data updates from a specific plugin.
///
/// Action to subscribe.
+ ///
private protected void Subscribe(Delegate action)
=> this.Channel.Subscribe(action);
///
- /// Unsubscribe an expression from this registration.
+ /// Removes a subscription created through . Note that the to be
+ /// unsubscribed must be the same instance as the one passed in.
///
/// Action to unsubscribe.
+ ///
private protected void Unsubscribe(Delegate action)
=> this.Channel.Unsubscribe(action);
///
- /// Invoke an action registered for inter-plugin communication.
+ /// Executes the Action registered for this IPC call gate via . This method is intended
+ /// to be called by plugins wishing to access another plugin via RPC. The parameters passed to this method will be
+ /// passed to the owning plugin, with appropriate serialization for complex data types. Primitive data types will
+ /// be passed as-is. The target Action will be called on the same thread as the caller.
///
/// Action arguments.
/// This is thrown when the IPC publisher has not registered an action for calling yet.
+ ///
+ ///
private protected void InvokeAction(params object?[]? args)
=> this.Channel.InvokeAction(args);
///
- /// Invoke a function registered for inter-plugin communication.
+ /// Executes the Function registered for this IPC call gate via . This method is intended
+ /// to be called by plugins wishing to access another plugin via RPC. The parameters passed to this method will be
+ /// passed to the owning plugin, with appropriate serialization for complex data types. Primitive data types will
+ /// be passed as-is. The target Action will be called on the same thread as the caller.
///
/// Parameter args.
/// The return value.
/// The return type.
/// This is thrown when the IPC publisher has not registered a func for calling yet.
+ ///
+ ///
private protected TRet InvokeFunc(params object?[]? args)
=> this.Channel.InvokeFunc(args);
///
- /// Invoke all actions that have subscribed to this IPC.
+ /// Send the given arguments to all subscribers (through ) of this IPC call gate. This method
+ /// is intended to be used by the provider plugin to notify all subscribers of an event or data update. The
+ /// parameters passed to this method will be passed to all subscribers, with appropriate serialization for complex
+ /// data types. Primitive data types will be passed as-is. The subscription actions will be called sequentially in
+ /// order of registration on the same thread as the caller.
///
/// Delegate arguments.
private protected void SendMessage(params object?[]? args)