using Dalamud.Plugin;
using Dalamud.Plugin.Ipc;
using Dalamud.Plugin.Services;
namespace Penumbra.Api.Helpers;
///
/// Specialized disposable Subscriber for Events.
/// Subscriptions are wrapped to be individually exception-safe.
/// Can be enabled and disabled.
///
public sealed class EventSubscriber : IDisposable
{
private readonly string _label;
private readonly IPluginLog _log;
private readonly Dictionary _delegates = new();
private ICallGateSubscriber? _subscriber;
private bool _disabled;
public EventSubscriber(IDalamudPluginInterface pi, string label, params Action[] actions)
{
_label = label;
_log = PluginLogHelper.GetLog(pi);
try
{
_subscriber = pi.GetIpcSubscriber(label);
foreach (var action in actions)
Event += action;
_disabled = false;
}
catch (Exception e)
{
_log.Error($"Error registering IPC Subscriber for {label}\n{e}");
_subscriber = null;
}
}
///
/// Enable all currently subscribed actions registered with this EventSubscriber.
/// Does nothing if it is already enabled.
///
public void Enable()
{
if (_disabled && _subscriber != null)
{
foreach (var action in _delegates.Values)
_subscriber.Subscribe(action);
_disabled = false;
}
}
///
/// Disable all subscribed actions registered with this EventSubscriber.
/// Does nothing if it is already disabled.
/// Does not forget the actions, only disables them.
///
public void Disable()
{
if (!_disabled)
{
if (_subscriber != null)
foreach (var action in _delegates.Values)
_subscriber.Unsubscribe(action);
_disabled = true;
}
}
///
/// Add or remove an action to the IPC event, if it is valid.
///
public event Action Event
{
add
{
if (_subscriber != null && !_delegates.ContainsKey(value))
{
void Action()
{
try
{
value();
}
catch (Exception e)
{
_log.Error($"Exception invoking IPC event {_label}:\n{e}");
}
}
if (_delegates.TryAdd(value, Action) && !_disabled)
_subscriber.Subscribe(Action);
}
}
remove
{
if (_subscriber != null && _delegates.Remove(value, out var action))
_subscriber.Unsubscribe(action);
}
}
public void Dispose()
{
Disable();
_subscriber = null;
_delegates.Clear();
}
~EventSubscriber()
=> Dispose();
}
///
public sealed class EventSubscriber : IDisposable
{
private readonly string _label;
private readonly IPluginLog _log;
private readonly Dictionary, Action> _delegates = new();
private ICallGateSubscriber? _subscriber;
private bool _disabled;
public EventSubscriber(IDalamudPluginInterface pi, string label, params Action[] actions)
{
_label = label;
_log = PluginLogHelper.GetLog(pi);
try
{
_subscriber = pi.GetIpcSubscriber(label);
foreach (var action in actions)
Event += action;
_disabled = false;
}
catch (Exception e)
{
_log.Error($"Error registering IPC Subscriber for {label}\n{e}");
_subscriber = null;
}
}
///
public void Enable()
{
if (_disabled && _subscriber != null)
{
foreach (var action in _delegates.Values)
_subscriber.Subscribe(action);
_disabled = false;
}
}
///
public void Disable()
{
if (!_disabled)
{
if (_subscriber != null)
foreach (var action in _delegates.Values)
_subscriber.Unsubscribe(action);
_disabled = true;
}
}
///
public event Action Event
{
add
{
if (_subscriber != null && !_delegates.ContainsKey(value))
{
void Action(T1 a)
{
try
{
value(a);
}
catch (Exception e)
{
_log.Error($"Exception invoking IPC event {_label}:\n{e}");
}
}
if (_delegates.TryAdd(value, Action) && !_disabled)
_subscriber.Subscribe(Action);
}
}
remove
{
if (_subscriber != null && _delegates.Remove(value, out var action))
_subscriber.Unsubscribe(action);
}
}
public void Dispose()
{
Disable();
_subscriber = null;
_delegates.Clear();
}
~EventSubscriber()
=> Dispose();
}
///
public sealed class EventSubscriber : IDisposable
{
private readonly string _label;
private readonly IPluginLog _log;
private readonly Dictionary, Action> _delegates = new();
private ICallGateSubscriber? _subscriber;
private bool _disabled;
public EventSubscriber(IDalamudPluginInterface pi, string label, params Action[] actions)
{
_label = label;
_log = PluginLogHelper.GetLog(pi);
try
{
_subscriber = pi.GetIpcSubscriber(label);
foreach (var action in actions)
Event += action;
_disabled = false;
}
catch (Exception e)
{
_log.Error($"Error registering IPC Subscriber for {label}\n{e}");
_subscriber = null;
}
}
///
public void Enable()
{
if (_disabled && _subscriber != null)
{
foreach (var action in _delegates.Values)
_subscriber.Subscribe(action);
_disabled = false;
}
}
///
public void Disable()
{
if (!_disabled)
{
if (_subscriber != null)
foreach (var action in _delegates.Values)
_subscriber.Unsubscribe(action);
_disabled = true;
}
}
///
public event Action Event
{
add
{
if (_subscriber != null && !_delegates.ContainsKey(value))
{
void Action(T1 a, T2 b)
{
try
{
value(a, b);
}
catch (Exception e)
{
_log.Error($"Exception invoking IPC event {_label}:\n{e}");
}
}
if (_delegates.TryAdd(value, Action) && !_disabled)
_subscriber.Subscribe(Action);
}
}
remove
{
if (_subscriber != null && _delegates.Remove(value, out var action))
_subscriber.Unsubscribe(action);
}
}
public void Dispose()
{
Disable();
_subscriber = null;
_delegates.Clear();
}
~EventSubscriber()
=> Dispose();
}
///
public sealed class EventSubscriber : IDisposable
{
private readonly string _label;
private readonly IPluginLog _log;
private readonly Dictionary, Action> _delegates = [];
private ICallGateSubscriber? _subscriber;
private bool _disabled;
public EventSubscriber(IDalamudPluginInterface pi, string label, params Action[] actions)
{
_label = label;
_log = PluginLogHelper.GetLog(pi);
try
{
_subscriber = pi.GetIpcSubscriber(label);
foreach (var action in actions)
Event += action;
_disabled = false;
}
catch (Exception e)
{
_log.Error($"Error registering IPC Subscriber for {label}\n{e}");
_subscriber = null;
}
}
///
public void Enable()
{
if (_disabled && _subscriber != null)
{
foreach (var action in _delegates.Values)
_subscriber.Subscribe(action);
_disabled = false;
}
}
///
public void Disable()
{
if (!_disabled)
{
if (_subscriber != null)
foreach (var action in _delegates.Values)
_subscriber.Unsubscribe(action);
_disabled = true;
}
}
///
public event Action Event
{
add
{
if (_subscriber != null && !_delegates.ContainsKey(value))
{
void Action(T1 a, T2 b, T3 c)
{
try
{
value(a, b, c);
}
catch (Exception e)
{
_log.Error($"Exception invoking IPC event {_label}:\n{e}");
}
}
if (_delegates.TryAdd(value, Action) && !_disabled)
_subscriber.Subscribe(Action);
}
}
remove
{
if (_subscriber != null && _delegates.Remove(value, out var action))
_subscriber.Unsubscribe(action);
}
}
public void Dispose()
{
Disable();
_subscriber = null;
_delegates.Clear();
}
~EventSubscriber()
=> Dispose();
}
///
public sealed class EventSubscriber : IDisposable
{
private readonly string _label;
private readonly IPluginLog _log;
private readonly Dictionary, Action> _delegates = new();
private ICallGateSubscriber? _subscriber;
private bool _disabled;
public EventSubscriber(IDalamudPluginInterface pi, string label, params Action[] actions)
{
_label = label;
_log = PluginLogHelper.GetLog(pi);
try
{
_subscriber = pi.GetIpcSubscriber(label);
foreach (var action in actions)
Event += action;
_disabled = false;
}
catch (Exception e)
{
_log.Error($"Error registering IPC Subscriber for {label}\n{e}");
_subscriber = null;
}
}
///
public void Enable()
{
if (_disabled && _subscriber != null)
{
foreach (var action in _delegates.Values)
_subscriber.Subscribe(action);
_disabled = false;
}
}
///
public void Disable()
{
if (!_disabled)
{
if (_subscriber != null)
foreach (var action in _delegates.Values)
_subscriber.Unsubscribe(action);
_disabled = true;
}
}
///
public event Action Event
{
add
{
if (_subscriber != null && !_delegates.ContainsKey(value))
{
void Action(T1 a, T2 b, T3 c, T4 d)
{
try
{
value(a, b, c, d);
}
catch (Exception e)
{
_log.Error($"Exception invoking IPC event {_label}:\n{e}");
}
}
if (_delegates.TryAdd(value, Action) && !_disabled)
_subscriber.Subscribe(Action);
}
}
remove
{
if (_subscriber != null && _delegates.Remove(value, out var action))
_subscriber.Unsubscribe(action);
}
}
public void Dispose()
{
Disable();
_subscriber = null;
_delegates.Clear();
}
~EventSubscriber()
=> Dispose();
}
///
public sealed class EventSubscriber : IDisposable
{
private readonly string _label;
private readonly IPluginLog _log;
private readonly Dictionary, Action> _delegates = new();
private ICallGateSubscriber? _subscriber;
private bool _disabled;
public EventSubscriber(IDalamudPluginInterface pi, string label, params Action[] actions)
{
_label = label;
_log = PluginLogHelper.GetLog(pi);
try
{
_subscriber = pi.GetIpcSubscriber(label);
foreach (var action in actions)
Event += action;
_disabled = false;
}
catch (Exception e)
{
_log.Error($"Error registering IPC Subscriber for {label}\n{e}");
_subscriber = null;
}
}
///
public void Enable()
{
if (_disabled && _subscriber != null)
{
foreach (var action in _delegates.Values)
_subscriber.Subscribe(action);
_disabled = false;
}
}
///
public void Disable()
{
if (!_disabled)
{
if (_subscriber != null)
foreach (var action in _delegates.Values)
_subscriber.Unsubscribe(action);
_disabled = true;
}
}
///
public event Action Event
{
add
{
if (_subscriber != null && !_delegates.ContainsKey(value))
{
void Action(T1 a, T2 b, T3 c, T4 d, T5 e)
{
try
{
value(a, b, c, d, e);
}
catch (Exception ex)
{
_log.Error($"Exception invoking IPC event {_label}:\n{ex}");
}
}
if (_delegates.TryAdd(value, Action) && !_disabled)
_subscriber.Subscribe(Action);
}
}
remove
{
if (_subscriber != null && _delegates.Remove(value, out var action))
_subscriber.Unsubscribe(action);
}
}
public void Dispose()
{
Disable();
_subscriber = null;
_delegates.Clear();
}
~EventSubscriber()
=> Dispose();
}