using Dalamud.Plugin; using Dalamud.Plugin.Ipc; using Dalamud.Plugin.Services; namespace Glamourer.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 = 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) { 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(); }