diff --git a/MareSynchronos/Factories/CharacterDataFactory.cs b/MareSynchronos/Factories/CharacterDataFactory.cs index 91705c0..8f5a074 100644 --- a/MareSynchronos/Factories/CharacterDataFactory.cs +++ b/MareSynchronos/Factories/CharacterDataFactory.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; +using System.Threading.Tasks; +using Dalamud.Game; using Dalamud.Utility; using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; @@ -33,7 +35,12 @@ public class CharacterDataFactory this.transientResourceManager = transientResourceManager; } - public unsafe CharacterData BuildCharacterData(CharacterData previousData, ObjectKind objectKind, IntPtr playerPointer, CancellationToken token) + private unsafe bool CheckForPointer(IntPtr playerPointer) + { + return playerPointer == IntPtr.Zero || ((Character*)playerPointer)->GameObject.GetDrawObject() == null; + } + + public async Task BuildCharacterData(CharacterData previousData, ObjectKind objectKind, IntPtr playerPointer, CancellationToken token) { if (!_ipcManager.Initialized) { @@ -43,7 +50,7 @@ public class CharacterDataFactory bool pointerIsZero = true; try { - pointerIsZero = playerPointer == IntPtr.Zero || ((Character*)playerPointer)->GameObject.GetDrawObject() == null; + pointerIsZero = CheckForPointer(playerPointer); } catch (Exception ex) { @@ -65,7 +72,7 @@ public class CharacterDataFactory try { - return CreateCharacterData(previousData, objectKind, playerPointer, token); + return await _dalamudUtil.RunOnFrameworkThread(() => CreateCharacterData(previousData, objectKind, playerPointer, token)); } catch (OperationCanceledException) { diff --git a/MareSynchronos/Managers/PlayerManager.cs b/MareSynchronos/Managers/PlayerManager.cs index cdca271..c14d834 100644 --- a/MareSynchronos/Managers/PlayerManager.cs +++ b/MareSynchronos/Managers/PlayerManager.cs @@ -119,7 +119,7 @@ namespace MareSynchronos.Managers foreach (var unprocessedObject in playerRelatedObjects.Where(c => c.HasUnprocessedUpdate).ToList()) { Logger.Verbose("Building Cache for " + unprocessedObject.ObjectKind); - PermanentDataCache = _characterDataFactory.BuildCharacterData(PermanentDataCache, unprocessedObject.ObjectKind, unprocessedObject.Address, token); + PermanentDataCache = await _characterDataFactory.BuildCharacterData(PermanentDataCache, unprocessedObject.ObjectKind, unprocessedObject.Address, token); if (!token.IsCancellationRequested) { unprocessedObject.HasUnprocessedUpdate = false; diff --git a/MareSynchronos/Utils/DalamudUtil.cs b/MareSynchronos/Utils/DalamudUtil.cs index 070a2ad..c37c6ac 100644 --- a/MareSynchronos/Utils/DalamudUtil.cs +++ b/MareSynchronos/Utils/DalamudUtil.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; +using System.Threading.Tasks; using Dalamud.Game; using Dalamud.Game.ClientState; using Dalamud.Game.ClientState.Conditions; @@ -189,6 +190,11 @@ namespace MareSynchronos.Utils return null; } + public async Task RunOnFrameworkThread(Func func) + { + return await _framework.RunOnFrameworkThread(func); + } + public unsafe void WaitWhileCharacterIsDrawing(string name, IntPtr characterAddress, CancellationToken? ct = null) { if (!_clientState.IsLoggedIn || characterAddress == IntPtr.Zero) return;