From a2f88124d71d921edac6fcca86b9155db75dee88 Mon Sep 17 00:00:00 2001 From: Stanley Dimant Date: Mon, 5 Sep 2022 11:23:02 +0200 Subject: [PATCH] move handling of critical ipc to main thread --- MareSynchronos/Managers/IpcManager.cs | 80 ++++++++++++++++++--------- 1 file changed, 55 insertions(+), 25 deletions(-) diff --git a/MareSynchronos/Managers/IpcManager.cs b/MareSynchronos/Managers/IpcManager.cs index a651d72..4e89693 100644 --- a/MareSynchronos/Managers/IpcManager.cs +++ b/MareSynchronos/Managers/IpcManager.cs @@ -34,6 +34,7 @@ namespace MareSynchronos.Managers _penumbraSetTemporaryMod; private readonly ICallGateSubscriber _penumbraGameObjectResourcePathResolved; private readonly DalamudUtil _dalamudUtil; + private readonly Queue actionQueue = new(); public IpcManager(DalamudPluginInterface pi, DalamudUtil dalamudUtil) { @@ -80,6 +81,15 @@ namespace MareSynchronos.Managers } this._dalamudUtil = dalamudUtil; + _dalamudUtil.FrameworkUpdate += HandleActionQueue; + } + + private void HandleActionQueue() + { + while (actionQueue.TryDequeue(out var action)) + { + action(); + } } private void ResourceLoaded(IntPtr ptr, string arg1, string arg2) @@ -125,6 +135,9 @@ namespace MareSynchronos.Managers { Logger.Verbose("Disposing " + nameof(IpcManager)); + _dalamudUtil.FrameworkUpdate -= HandleActionQueue; + actionQueue.Clear(); + _penumbraDispose.Unsubscribe(PenumbraDispose); _penumbraInit.Unsubscribe(PenumbraInit); _penumbraObjectIsRedrawn.Unsubscribe(RedrawEvent); @@ -134,26 +147,35 @@ namespace MareSynchronos.Managers public void GlamourerApplyAll(string? customization, IntPtr obj) { if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return; - var gameObj = _dalamudUtil.CreateGameObject(obj); - if (gameObj != null) + actionQueue.Enqueue(() => { - Logger.Verbose("Glamourer applying for " + gameObj); - _glamourerApplyAll!.InvokeAction(customization, gameObj); - } + var gameObj = _dalamudUtil.CreateGameObject(obj); + if (gameObj != null) + { + Logger.Verbose("Glamourer applying for " + gameObj); + _glamourerApplyAll!.InvokeAction(customization, gameObj); + } + }); } public void GlamourerApplyOnlyEquipment(string customization, GameObject character) { if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return; - Logger.Verbose("Glamourer apply only equipment to " + character); - _glamourerApplyOnlyEquipment!.InvokeAction(customization, character); + actionQueue.Enqueue(() => + { + Logger.Verbose("Glamourer apply only equipment to " + character); + _glamourerApplyOnlyEquipment!.InvokeAction(customization, character); + }); } public void GlamourerApplyOnlyCustomization(string customization, GameObject character) { if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return; - Logger.Verbose("Glamourer apply only customization to " + character); - _glamourerApplyOnlyCustomization!.InvokeAction(customization, character); + actionQueue.Enqueue(() => + { + Logger.Verbose("Glamourer apply only customization to " + character); + _glamourerApplyOnlyCustomization!.InvokeAction(customization, character); + }); } public string GlamourerGetCharacterCustomization(GameObject character) @@ -177,7 +199,7 @@ namespace MareSynchronos.Managers public void GlamourerRevertCharacterCustomization(GameObject character) { if (!CheckGlamourerApi()) return; - _glamourerRevertCustomization!.InvokeAction(character); + actionQueue.Enqueue(() => _glamourerRevertCustomization!.InvokeAction(character)); } public string PenumbraCreateTemporaryCollection(string characterName) @@ -203,32 +225,37 @@ namespace MareSynchronos.Managers public void PenumbraRedraw(IntPtr obj) { if (!CheckPenumbraApi()) return; - var gameObj = _dalamudUtil.CreateGameObject(obj); - if (gameObj != null) + actionQueue.Enqueue(() => { - Logger.Verbose("Redrawing " + gameObj); - _penumbraRedrawObject!.InvokeAction(gameObj, 0); - } + var gameObj = _dalamudUtil.CreateGameObject(obj); + if (gameObj != null) + { + Logger.Verbose("Redrawing " + gameObj); + _penumbraRedrawObject!.InvokeAction(gameObj, 0); + } + }); } public void PenumbraRedraw(string actorName) { if (!CheckPenumbraApi()) return; - _penumbraRedraw!.InvokeAction(actorName, 0); + actionQueue.Enqueue(() => _penumbraRedraw!.InvokeAction(actorName, 0)); } public void PenumbraRemoveTemporaryCollection(string characterName) { if (!CheckPenumbraApi()) return; - Logger.Verbose("Removing temp collection for " + characterName); - _penumbraRemoveTemporaryCollection.InvokeFunc(characterName); + actionQueue.Enqueue(() => + { + Logger.Verbose("Removing temp collection for " + characterName); + _penumbraRemoveTemporaryCollection.InvokeFunc(characterName); + }); } public string? PenumbraResolvePath(string path) { if (!CheckPenumbraApi()) return null; var resolvedPath = _penumbraResolvePlayer!.InvokeFunc(path); - //Logger.Verbose("Resolved " + path + "=>" + string.Join(", ", resolvedPath)); return resolvedPath; } @@ -240,7 +267,6 @@ namespace MareSynchronos.Managers { resolvedPaths = new[] { path }; } - //Logger.Verbose("Reverse Resolved " + path + "=>" + string.Join(", ", resolvedPaths)); return resolvedPaths; } @@ -248,12 +274,15 @@ namespace MareSynchronos.Managers { if (!CheckPenumbraApi()) return; - Logger.Verbose("Assigning temp mods for " + collectionName); - foreach (var mod in modPaths) + actionQueue.Enqueue(() => { - Logger.Verbose(mod.Key + " => " + mod.Value); - } - var ret = _penumbraSetTemporaryMod.InvokeFunc("MareSynchronos", collectionName, modPaths, manipulationData, 0); + Logger.Verbose("Assigning temp mods for " + collectionName); + foreach (var mod in modPaths) + { + Logger.Verbose(mod.Key + " => " + mod.Value); + } + _penumbraSetTemporaryMod.InvokeFunc("MareSynchronos", collectionName, modPaths, manipulationData, 0); + }); } private void RedrawEvent(IntPtr objectAddress, int objectTableIndex) @@ -270,6 +299,7 @@ namespace MareSynchronos.Managers private void PenumbraDispose() { PenumbraDisposed?.Invoke(); + actionQueue.Clear(); } } }