This commit is contained in:
KazWolfe 2025-12-11 23:18:27 +01:00 committed by GitHub
commit 00a3458208
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 157 additions and 63 deletions

View file

@ -48,12 +48,20 @@ internal class PluginIpcWidget : IDataWindowWidget
this.ipcPub.RegisterAction(msg => this.ipcPub.RegisterAction(msg =>
{ {
Log.Information("Data action was called: {Msg}", msg); Log.Information(
"Data action was called: {Msg}\n" +
" Context: {Context}",
msg,
this.ipcPub.GetContext());
}); });
this.ipcPub.RegisterFunc(msg => this.ipcPub.RegisterFunc(msg =>
{ {
Log.Information("Data func was called: {Msg}", msg); Log.Information(
"Data func was called: {Msg}\n" +
" Context: {Context}",
msg,
this.ipcPub.GetContext());
return Guid.NewGuid().ToString(); return Guid.NewGuid().ToString();
}); });
} }
@ -61,14 +69,8 @@ internal class PluginIpcWidget : IDataWindowWidget
if (this.ipcSub == null) if (this.ipcSub == null)
{ {
this.ipcSub = new CallGatePubSub<string, string>("dataDemo1"); this.ipcSub = new CallGatePubSub<string, string>("dataDemo1");
this.ipcSub.Subscribe(_ => this.ipcSub.Subscribe(_ => { Log.Information("PONG1"); });
{ this.ipcSub.Subscribe(_ => { Log.Information("PONG2"); });
Log.Information("PONG1");
});
this.ipcSub.Subscribe(_ =>
{
Log.Information("PONG2");
});
this.ipcSub.Subscribe(_ => throw new Exception("PONG3")); this.ipcSub.Subscribe(_ => throw new Exception("PONG3"));
} }
@ -78,12 +80,21 @@ internal class PluginIpcWidget : IDataWindowWidget
this.ipcPubGo.RegisterAction(go => this.ipcPubGo.RegisterAction(go =>
{ {
Log.Information("Data action was called: {Name}", go?.Name); Log.Information(
"Data action was called: {Name}" +
"\n Context: {Context}",
go?.Name,
this.ipcPubGo.GetContext());
}); });
this.ipcPubGo.RegisterFunc(go => this.ipcPubGo.RegisterFunc(go =>
{ {
Log.Information("Data func was called: {Name}", go?.Name); Log.Information(
"Data func was called: {Name}\n" +
" Context: {Context}",
go?.Name,
this.ipcPubGo.GetContext());
return "test"; return "test";
}); });
} }

View file

@ -248,75 +248,75 @@ internal sealed class DalamudPluginInterface : IDalamudPluginInterface, IDisposa
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateProvider<TRet> GetIpcProvider<TRet>(string name) public ICallGateProvider<TRet> GetIpcProvider<TRet>(string name)
=> new CallGatePubSub<TRet>(name); => new CallGatePubSub<TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateProvider<T1, TRet> GetIpcProvider<T1, TRet>(string name) public ICallGateProvider<T1, TRet> GetIpcProvider<T1, TRet>(string name)
=> new CallGatePubSub<T1, TRet>(name); => new CallGatePubSub<T1, TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateProvider<T1, T2, TRet> GetIpcProvider<T1, T2, TRet>(string name) public ICallGateProvider<T1, T2, TRet> GetIpcProvider<T1, T2, TRet>(string name)
=> new CallGatePubSub<T1, T2, TRet>(name); => new CallGatePubSub<T1, T2, TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateProvider<T1, T2, T3, TRet> GetIpcProvider<T1, T2, T3, TRet>(string name) public ICallGateProvider<T1, T2, T3, TRet> GetIpcProvider<T1, T2, T3, TRet>(string name)
=> new CallGatePubSub<T1, T2, T3, TRet>(name); => new CallGatePubSub<T1, T2, T3, TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateProvider<T1, T2, T3, T4, TRet> GetIpcProvider<T1, T2, T3, T4, TRet>(string name) public ICallGateProvider<T1, T2, T3, T4, TRet> GetIpcProvider<T1, T2, T3, T4, TRet>(string name)
=> new CallGatePubSub<T1, T2, T3, T4, TRet>(name); => new CallGatePubSub<T1, T2, T3, T4, TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateProvider<T1, T2, T3, T4, T5, TRet> GetIpcProvider<T1, T2, T3, T4, T5, TRet>(string name) public ICallGateProvider<T1, T2, T3, T4, T5, TRet> GetIpcProvider<T1, T2, T3, T4, T5, TRet>(string name)
=> new CallGatePubSub<T1, T2, T3, T4, T5, TRet>(name); => new CallGatePubSub<T1, T2, T3, T4, T5, TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateProvider<T1, T2, T3, T4, T5, T6, TRet> GetIpcProvider<T1, T2, T3, T4, T5, T6, TRet>(string name) public ICallGateProvider<T1, T2, T3, T4, T5, T6, TRet> GetIpcProvider<T1, T2, T3, T4, T5, T6, TRet>(string name)
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, TRet>(name); => new CallGatePubSub<T1, T2, T3, T4, T5, T6, TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, TRet> GetIpcProvider<T1, T2, T3, T4, T5, T6, T7, TRet>(string name) public ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, TRet> GetIpcProvider<T1, T2, T3, T4, T5, T6, T7, TRet>(string name)
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, TRet>(name); => new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, T8, TRet> GetIpcProvider<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(string name) public ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, T8, TRet> GetIpcProvider<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(string name)
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(name); => new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateSubscriber<TRet> GetIpcSubscriber<TRet>(string name) public ICallGateSubscriber<TRet> GetIpcSubscriber<TRet>(string name)
=> new CallGatePubSub<TRet>(name); => new CallGatePubSub<TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateSubscriber<T1, TRet> GetIpcSubscriber<T1, TRet>(string name) public ICallGateSubscriber<T1, TRet> GetIpcSubscriber<T1, TRet>(string name)
=> new CallGatePubSub<T1, TRet>(name); => new CallGatePubSub<T1, TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateSubscriber<T1, T2, TRet> GetIpcSubscriber<T1, T2, TRet>(string name) public ICallGateSubscriber<T1, T2, TRet> GetIpcSubscriber<T1, T2, TRet>(string name)
=> new CallGatePubSub<T1, T2, TRet>(name); => new CallGatePubSub<T1, T2, TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateSubscriber<T1, T2, T3, TRet> GetIpcSubscriber<T1, T2, T3, TRet>(string name) public ICallGateSubscriber<T1, T2, T3, TRet> GetIpcSubscriber<T1, T2, T3, TRet>(string name)
=> new CallGatePubSub<T1, T2, T3, TRet>(name); => new CallGatePubSub<T1, T2, T3, TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateSubscriber<T1, T2, T3, T4, TRet> GetIpcSubscriber<T1, T2, T3, T4, TRet>(string name) public ICallGateSubscriber<T1, T2, T3, T4, TRet> GetIpcSubscriber<T1, T2, T3, T4, TRet>(string name)
=> new CallGatePubSub<T1, T2, T3, T4, TRet>(name); => new CallGatePubSub<T1, T2, T3, T4, TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateSubscriber<T1, T2, T3, T4, T5, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, TRet>(string name) public ICallGateSubscriber<T1, T2, T3, T4, T5, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, TRet>(string name)
=> new CallGatePubSub<T1, T2, T3, T4, T5, TRet>(name); => new CallGatePubSub<T1, T2, T3, T4, T5, TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateSubscriber<T1, T2, T3, T4, T5, T6, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, T6, TRet>(string name) public ICallGateSubscriber<T1, T2, T3, T4, T5, T6, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, T6, TRet>(string name)
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, TRet>(name); => new CallGatePubSub<T1, T2, T3, T4, T5, T6, TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, T6, T7, TRet>(string name) public ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, T6, T7, TRet>(string name)
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, TRet>(name); => new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, TRet>(name, this.plugin);
/// <inheritdoc/> /// <inheritdoc/>
public ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, T8, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(string name) public ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, T8, TRet> GetIpcSubscriber<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(string name)
=> new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(name); => new CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, T8, TRet>(name, this.plugin);
#endregion #endregion

View file

@ -19,6 +19,9 @@ public interface ICallGateProvider
/// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/> /// <inheritdoc cref="CallGatePubSubBase.UnregisterFunc"/>
public void UnregisterFunc(); public void UnregisterFunc();
/// <inheritdoc cref="CallGatePubSubBase.GetContext"/>
public IpcContext? GetContext();
} }
/// <inheritdoc cref="ICallGateProvider"/> /// <inheritdoc cref="ICallGateProvider"/>

View file

@ -2,7 +2,9 @@ using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading;
using Dalamud.Plugin.Internal.Types;
using Dalamud.Plugin.Ipc.Exceptions; using Dalamud.Plugin.Ipc.Exceptions;
using Dalamud.Plugin.Ipc.Internal.Converters; using Dalamud.Plugin.Ipc.Internal.Converters;
@ -16,6 +18,8 @@ namespace Dalamud.Plugin.Ipc.Internal;
/// </summary> /// </summary>
internal class CallGateChannel internal class CallGateChannel
{ {
private readonly ThreadLocal<IpcContext> ipcExecutionContext = new();
/// <summary> /// <summary>
/// The actual storage. /// The actual storage.
/// </summary> /// </summary>
@ -145,6 +149,21 @@ internal class CallGateChannel
return (TRet)result; return (TRet)result;
} }
internal void SetInvocationContext(IpcContext ipcContext)
{
this.ipcExecutionContext.Value = ipcContext;
}
internal IpcContext? GetInvocationContext()
{
return this.ipcExecutionContext.IsValueCreated ? this.ipcExecutionContext.Value : null;
}
internal void ClearInvocationContext()
{
this.ipcExecutionContext.Value = null;
}
private void CheckAndConvertArgs(object?[]? args, MethodInfo methodInfo) private void CheckAndConvertArgs(object?[]? args, MethodInfo methodInfo)
{ {
var paramTypes = methodInfo.GetParameters() var paramTypes = methodInfo.GetParameters()

View file

@ -1,3 +1,5 @@
using Dalamud.Plugin.Internal.Types;
#pragma warning disable SA1402 // File may only contain a single type #pragma warning disable SA1402 // File may only contain a single type
namespace Dalamud.Plugin.Ipc.Internal; namespace Dalamud.Plugin.Ipc.Internal;
@ -5,9 +7,9 @@ namespace Dalamud.Plugin.Ipc.Internal;
/// <inheritdoc cref="CallGatePubSubBase"/> /// <inheritdoc cref="CallGatePubSubBase"/>
internal class CallGatePubSub<TRet> : CallGatePubSubBase, ICallGateProvider<TRet>, ICallGateSubscriber<TRet> internal class CallGatePubSub<TRet> : CallGatePubSubBase, ICallGateProvider<TRet>, ICallGateSubscriber<TRet>
{ {
/// <inheritdoc cref="CallGatePubSubBase(string)"/> /// <inheritdoc cref="CallGatePubSubBase(string, LocalPlugin?)"/>
public CallGatePubSub(string name) public CallGatePubSub(string name, LocalPlugin? owningPlugin = null)
: base(name) : base(name, owningPlugin)
{ {
} }
@ -43,9 +45,9 @@ internal class CallGatePubSub<TRet> : CallGatePubSubBase, ICallGateProvider<TRet
/// <inheritdoc cref="CallGatePubSubBase"/> /// <inheritdoc cref="CallGatePubSubBase"/>
internal class CallGatePubSub<T1, TRet> : CallGatePubSubBase, ICallGateProvider<T1, TRet>, ICallGateSubscriber<T1, TRet> internal class CallGatePubSub<T1, TRet> : CallGatePubSubBase, ICallGateProvider<T1, TRet>, ICallGateSubscriber<T1, TRet>
{ {
/// <inheritdoc cref="CallGatePubSubBase(string)"/> /// <inheritdoc cref="CallGatePubSubBase(string, LocalPlugin?)"/>
public CallGatePubSub(string name) public CallGatePubSub(string name, LocalPlugin? owningPlugin = null)
: base(name) : base(name, owningPlugin)
{ {
} }
@ -81,9 +83,9 @@ internal class CallGatePubSub<T1, TRet> : CallGatePubSubBase, ICallGateProvider<
/// <inheritdoc cref="CallGatePubSubBase"/> /// <inheritdoc cref="CallGatePubSubBase"/>
internal class CallGatePubSub<T1, T2, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, TRet>, ICallGateSubscriber<T1, T2, TRet> internal class CallGatePubSub<T1, T2, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, TRet>, ICallGateSubscriber<T1, T2, TRet>
{ {
/// <inheritdoc cref="CallGatePubSubBase(string)"/> /// <inheritdoc cref="CallGatePubSubBase(string, LocalPlugin?)"/>
public CallGatePubSub(string name) public CallGatePubSub(string name, LocalPlugin? owningPlugin = null)
: base(name) : base(name, owningPlugin)
{ {
} }
@ -119,9 +121,9 @@ internal class CallGatePubSub<T1, T2, TRet> : CallGatePubSubBase, ICallGateProvi
/// <inheritdoc cref="CallGatePubSubBase"/> /// <inheritdoc cref="CallGatePubSubBase"/>
internal class CallGatePubSub<T1, T2, T3, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, TRet>, ICallGateSubscriber<T1, T2, T3, TRet> internal class CallGatePubSub<T1, T2, T3, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, TRet>, ICallGateSubscriber<T1, T2, T3, TRet>
{ {
/// <inheritdoc cref="CallGatePubSubBase(string)"/> /// <inheritdoc cref="CallGatePubSubBase(string, LocalPlugin?)"/>
public CallGatePubSub(string name) public CallGatePubSub(string name, LocalPlugin? owningPlugin = null)
: base(name) : base(name, owningPlugin)
{ {
} }
@ -157,9 +159,9 @@ internal class CallGatePubSub<T1, T2, T3, TRet> : CallGatePubSubBase, ICallGateP
/// <inheritdoc cref="CallGatePubSubBase"/> /// <inheritdoc cref="CallGatePubSubBase"/>
internal class CallGatePubSub<T1, T2, T3, T4, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, TRet>, ICallGateSubscriber<T1, T2, T3, T4, TRet> internal class CallGatePubSub<T1, T2, T3, T4, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, TRet>, ICallGateSubscriber<T1, T2, T3, T4, TRet>
{ {
/// <inheritdoc cref="CallGatePubSubBase(string)"/> /// <inheritdoc cref="CallGatePubSubBase(string, LocalPlugin?)"/>
public CallGatePubSub(string name) public CallGatePubSub(string name, LocalPlugin? owningPlugin = null)
: base(name) : base(name, owningPlugin)
{ {
} }
@ -195,9 +197,9 @@ internal class CallGatePubSub<T1, T2, T3, T4, TRet> : CallGatePubSubBase, ICallG
/// <inheritdoc cref="CallGatePubSubBase"/> /// <inheritdoc cref="CallGatePubSubBase"/>
internal class CallGatePubSub<T1, T2, T3, T4, T5, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, TRet> internal class CallGatePubSub<T1, T2, T3, T4, T5, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, TRet>
{ {
/// <inheritdoc cref="CallGatePubSubBase(string)"/> /// <inheritdoc cref="CallGatePubSubBase(string, LocalPlugin?)"/>
public CallGatePubSub(string name) public CallGatePubSub(string name, LocalPlugin? owningPlugin = null)
: base(name) : base(name, owningPlugin)
{ {
} }
@ -233,9 +235,9 @@ internal class CallGatePubSub<T1, T2, T3, T4, T5, TRet> : CallGatePubSubBase, IC
/// <inheritdoc cref="CallGatePubSubBase"/> /// <inheritdoc cref="CallGatePubSubBase"/>
internal class CallGatePubSub<T1, T2, T3, T4, T5, T6, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, T6, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, T6, TRet> internal class CallGatePubSub<T1, T2, T3, T4, T5, T6, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, T6, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, T6, TRet>
{ {
/// <inheritdoc cref="CallGatePubSubBase(string)"/> /// <inheritdoc cref="CallGatePubSubBase(string, LocalPlugin?)"/>
public CallGatePubSub(string name) public CallGatePubSub(string name, LocalPlugin? owningPlugin = null)
: base(name) : base(name, owningPlugin)
{ {
} }
@ -271,9 +273,9 @@ internal class CallGatePubSub<T1, T2, T3, T4, T5, T6, TRet> : CallGatePubSubBase
/// <inheritdoc cref="CallGatePubSubBase"/> /// <inheritdoc cref="CallGatePubSubBase"/>
internal class CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, TRet> internal class CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, TRet>
{ {
/// <inheritdoc cref="CallGatePubSubBase(string)"/> /// <inheritdoc cref="CallGatePubSubBase(string, LocalPlugin?)"/>
public CallGatePubSub(string name) public CallGatePubSub(string name, LocalPlugin? owningPlugin = null)
: base(name) : base(name, owningPlugin)
{ {
} }
@ -309,9 +311,9 @@ internal class CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, TRet> : CallGatePubSub
/// <inheritdoc cref="CallGatePubSubBase"/> /// <inheritdoc cref="CallGatePubSubBase"/>
internal class CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, T8, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, T8, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, T8, TRet> internal class CallGatePubSub<T1, T2, T3, T4, T5, T6, T7, T8, TRet> : CallGatePubSubBase, ICallGateProvider<T1, T2, T3, T4, T5, T6, T7, T8, TRet>, ICallGateSubscriber<T1, T2, T3, T4, T5, T6, T7, T8, TRet>
{ {
/// <inheritdoc cref="CallGatePubSubBase(string)"/> /// <inheritdoc cref="CallGatePubSubBase(string, LocalPlugin?)"/>
public CallGatePubSub(string name) public CallGatePubSub(string name, LocalPlugin? owningPlugin = null)
: base(name) : base(name, owningPlugin)
{ {
} }

View file

@ -1,4 +1,11 @@
using System.Reactive.Disposables;
using System.Threading;
using Dalamud.Plugin.Internal.Types;
using Dalamud.Plugin.Ipc.Exceptions; using Dalamud.Plugin.Ipc.Exceptions;
using Dalamud.Utility;
using Serilog;
namespace Dalamud.Plugin.Ipc.Internal; namespace Dalamud.Plugin.Ipc.Internal;
@ -11,9 +18,11 @@ internal abstract class CallGatePubSubBase
/// Initializes a new instance of the <see cref="CallGatePubSubBase"/> class. /// Initializes a new instance of the <see cref="CallGatePubSubBase"/> class.
/// </summary> /// </summary>
/// <param name="name">The name of the IPC registration.</param> /// <param name="name">The name of the IPC registration.</param>
protected CallGatePubSubBase(string name) /// <param name="owningPlugin">The plugin that owns this IPC pubsub.</param>
protected CallGatePubSubBase(string name, LocalPlugin? owningPlugin)
{ {
this.Channel = Service<CallGate>.Get().GetOrCreateChannel(name); this.Channel = Service<CallGate>.Get().GetOrCreateChannel(name);
this.OwningPlugin = owningPlugin;
} }
/// <summary> /// <summary>
@ -39,6 +48,11 @@ internal abstract class CallGatePubSubBase
/// </summary> /// </summary>
protected CallGateChannel Channel { get; init; } protected CallGateChannel Channel { get; init; }
/// <summary>
/// Gets the plugin that owns this pubsub instance.
/// </summary>
protected LocalPlugin? OwningPlugin { get; init; }
/// <summary> /// <summary>
/// Removes the associated Action from this call gate, effectively disabling RPC calls. /// Removes the associated Action from this call gate, effectively disabling RPC calls.
/// </summary> /// </summary>
@ -53,6 +67,16 @@ internal abstract class CallGatePubSubBase
public void UnregisterFunc() public void UnregisterFunc()
=> this.Channel.Func = null; => this.Channel.Func = null;
/// <summary>
/// Gets the current context for this IPC call. This will only be present when called from within an IPC action
/// or function handler, and will be null otherwise.
/// </summary>
/// <returns>Returns a potential IPC context.</returns>
public IpcContext? GetContext()
{
return this.Channel.GetInvocationContext();
}
/// <summary> /// <summary>
/// Registers a <see cref="Delegate"/> for use by other plugins via RPC. This Delegate must satisfy the constraints /// Registers a <see cref="Delegate"/> for use by other plugins via RPC. This Delegate must satisfy the constraints
/// of an <see cref="Action"/> type as defined by the interface, meaning they may not return a value and must have /// of an <see cref="Action"/> type as defined by the interface, meaning they may not return a value and must have
@ -105,7 +129,12 @@ internal abstract class CallGatePubSubBase
/// <seealso cref="RegisterAction"/> /// <seealso cref="RegisterAction"/>
/// <seealso cref="UnregisterAction"/> /// <seealso cref="UnregisterAction"/>
private protected void InvokeAction(params object?[]? args) private protected void InvokeAction(params object?[]? args)
=> this.Channel.InvokeAction(args); {
using (this.BuildContext())
{
this.Channel.InvokeAction(args);
}
}
/// <summary> /// <summary>
/// Executes the Function registered for this IPC call gate via <see cref="RegisterFunc"/>. This method is intended /// Executes the Function registered for this IPC call gate via <see cref="RegisterFunc"/>. This method is intended
@ -120,7 +149,12 @@ internal abstract class CallGatePubSubBase
/// <seealso cref="RegisterFunc"/> /// <seealso cref="RegisterFunc"/>
/// <seealso cref="UnregisterFunc"/> /// <seealso cref="UnregisterFunc"/>
private protected TRet InvokeFunc<TRet>(params object?[]? args) private protected TRet InvokeFunc<TRet>(params object?[]? args)
=> this.Channel.InvokeFunc<TRet>(args); {
using (this.BuildContext())
{
return this.Channel.InvokeFunc<TRet>(args);
}
}
/// <summary> /// <summary>
/// Send the given arguments to all subscribers (through <see cref="Subscribe"/>) of this IPC call gate. This method /// Send the given arguments to all subscribers (through <see cref="Subscribe"/>) of this IPC call gate. This method
@ -132,4 +166,14 @@ internal abstract class CallGatePubSubBase
/// <param name="args">Delegate arguments.</param> /// <param name="args">Delegate arguments.</param>
private protected void SendMessage(params object?[]? args) private protected void SendMessage(params object?[]? args)
=> this.Channel.SendMessage(args); => this.Channel.SendMessage(args);
private IDisposable BuildContext()
{
this.Channel.SetInvocationContext(new IpcContext
{
SourcePlugin = this.OwningPlugin != null ? new ExposedPlugin(this.OwningPlugin) : null,
});
return Disposable.Create(() => { this.Channel.ClearInvocationContext(); });
}
} }

View file

@ -0,0 +1,15 @@
namespace Dalamud.Plugin.Ipc;
/// <summary>
/// The context associated for an IPC call. Reads from ThreadLocal.
/// </summary>
public class IpcContext
{
/// <summary>
/// Gets the plugin that initiated this IPC call.
/// </summary>
public IExposedPlugin? SourcePlugin { get; init; }
/// <inheritdoc/>
public override string ToString() => $"<IpcContext SourcePlugin={this.SourcePlugin?.Name ?? "null"}>";
}