From 3906a7b34f9ecb1a4f8fdabcff8247a2750a8267 Mon Sep 17 00:00:00 2001 From: Stanley Dimant Date: Mon, 30 Jan 2023 17:47:47 +0100 Subject: [PATCH] add start of mediator --- MareSynchronos/Mediator/IMessage.cs | 3 ++ MareSynchronos/Mediator/MareMediator.cs | 51 +++++++++++++++++++++++++ MareSynchronos/Plugin.cs | 6 +++ 3 files changed, 60 insertions(+) create mode 100644 MareSynchronos/Mediator/IMessage.cs create mode 100644 MareSynchronos/Mediator/MareMediator.cs diff --git a/MareSynchronos/Mediator/IMessage.cs b/MareSynchronos/Mediator/IMessage.cs new file mode 100644 index 0000000..68e4d6c --- /dev/null +++ b/MareSynchronos/Mediator/IMessage.cs @@ -0,0 +1,3 @@ +namespace MareSynchronos.Mediator; + +public interface IMessage { } \ No newline at end of file diff --git a/MareSynchronos/Mediator/MareMediator.cs b/MareSynchronos/Mediator/MareMediator.cs new file mode 100644 index 0000000..03ee16d --- /dev/null +++ b/MareSynchronos/Mediator/MareMediator.cs @@ -0,0 +1,51 @@ +using MareSynchronos.Utils; + +namespace MareSynchronos.Mediator; + +public class MareMediator : IDisposable +{ + private record MediatorSubscriber(object Subscriber, Action Action); + + private readonly Dictionary> _subscriberDict = new(); + + public void Subscribe(object subscriber, Action action) where T : IMessage + { + _subscriberDict.TryAdd(typeof(T), new HashSet()); + + if (!_subscriberDict[typeof(T)].Add(new(subscriber, action))) + { + throw new InvalidOperationException("Already subscribed"); + } + } + + public void Unsubscribe(object subscriber) where T : IMessage + { + if (_subscriberDict.TryGetValue(typeof(T), out var subscribers)) + { + subscribers.RemoveWhere(p => p.Subscriber == subscriber); + } + } + + public void Publish(IMessage message) + { + if (_subscriberDict.TryGetValue(message.GetType(), out var subscribers)) + { + foreach (var subscriber in subscribers) + { + try + { + subscriber.Action.Invoke(message); + } + catch (Exception ex) + { + Logger.Error("Error executing " + subscriber.Action.Method, ex); + } + } + } + } + + public void Dispose() + { + _subscriberDict.Clear(); + } +} \ No newline at end of file diff --git a/MareSynchronos/Plugin.cs b/MareSynchronos/Plugin.cs index 7b8a4bb..e9fc7e5 100644 --- a/MareSynchronos/Plugin.cs +++ b/MareSynchronos/Plugin.cs @@ -16,6 +16,7 @@ using Dalamud.Game.Gui; using MareSynchronos.Export; using Dalamud.Data; using MareSynchronos.MareConfiguration; +using MareSynchronos.Mediator; namespace MareSynchronos; @@ -46,6 +47,7 @@ public sealed class Plugin : IDalamudPlugin private readonly ServerConfigurationManager _serverConfigurationManager; private readonly GposeUi _gposeUi; private readonly ConfigurationService _configurationService; + private readonly MareMediator _mediator; public Plugin(DalamudPluginInterface pluginInterface, CommandManager commandManager, DataManager gameData, @@ -56,6 +58,7 @@ public sealed class Plugin : IDalamudPlugin _pluginInterface.UiBuilder.DisableGposeUiHide = true; _commandManager = commandManager; _configurationService = new(_pluginInterface); + _mediator = new(); _localization = new Dalamud.Localization("MareSynchronos.Localization.", "", useEmbedded: true); _localization.SetupWithLangCode("en"); @@ -138,6 +141,9 @@ public sealed class Plugin : IDalamudPlugin _transientResourceManager?.Dispose(); _dalamudUtil.Dispose(); _configurationService?.Dispose(); + + _mediator.Dispose(); + Logger.Debug("Shut down"); }