diff --git a/LightlessSync/PlayerData/Factories/PlayerDataFactory.cs b/LightlessSync/PlayerData/Factories/PlayerDataFactory.cs index 4a20467..31df865 100644 --- a/LightlessSync/PlayerData/Factories/PlayerDataFactory.cs +++ b/LightlessSync/PlayerData/Factories/PlayerDataFactory.cs @@ -165,30 +165,67 @@ public class PlayerDataFactory } } - await _transientResourceManager.WaitForRecording(ct).ConfigureAwait(false); + Task? getHeelsOffset = null; + Task? getGlamourerData = null; + Task? getCustomizeData = null; + Task? getHonorificTitle = null; + Task? getMoodlesData = null; - if (objectKind == ObjectKind.Pet) + if (objectKind == ObjectKind.Player) { - foreach (var item in fragment.FileReplacements.Where(i => i.HasFileReplacement).SelectMany(p => p.GamePaths)) + getHeelsOffset = _ipcManager.Heels.GetOffsetAsync(); + getGlamourerData = _ipcManager.Glamourer.GetCharacterCustomizationAsync(playerRelatedObject.Address); + getCustomizeData = _ipcManager.CustomizePlus.GetScaleAsync(playerRelatedObject.Address); + getHonorificTitle = _ipcManager.Honorific.GetTitle(); + getMoodlesData = _ipcManager.Moodles.GetStatusAsync(playerRelatedObject.Address); + } + else + { + getGlamourerData = _ipcManager.Glamourer.GetCharacterCustomizationAsync(playerRelatedObject.Address); + getCustomizeData = _ipcManager.CustomizePlus.GetScaleAsync(playerRelatedObject.Address); + } + + var staticReplacements = fragment.FileReplacements.ToHashSet(); + + Task<(IReadOnlyDictionary ResolvedPaths, HashSet? ClearedReplacements)> transientTask = Task.Run(async () => + { + await _transientResourceManager.WaitForRecording(ct).ConfigureAwait(false); + + HashSet? clearedReplacements = null; + + if (objectKind == ObjectKind.Pet) { - if (_transientResourceManager.AddTransientResource(objectKind, item)) + foreach (var item in staticReplacements.Where(i => i.HasFileReplacement).SelectMany(p => p.GamePaths)) { - _logger.LogDebug("Marking static {item} for Pet as transient", item); + if (_transientResourceManager.AddTransientResource(objectKind, item)) + { + _logger.LogDebug("Marking static {item} for Pet as transient", item); + } } + + _logger.LogTrace("Clearing {count} Static Replacements for Pet", staticReplacements.Count); + clearedReplacements = staticReplacements; } - _logger.LogTrace("Clearing {count} Static Replacements for Pet", fragment.FileReplacements.Count); - fragment.FileReplacements.Clear(); - } + ct.ThrowIfCancellationRequested(); + + _logger.LogDebug("Handling transient update for {obj}", playerRelatedObject); + + _transientResourceManager.ClearTransientPaths(objectKind, [.. staticReplacements.SelectMany(c => c.GamePaths)]); + + var transientPaths = ManageSemiTransientData(objectKind); + IReadOnlyDictionary resolved = await GetFileReplacementsFromPaths(playerRelatedObject, transientPaths, new HashSet(StringComparer.Ordinal)).ConfigureAwait(false); + return (resolved, clearedReplacements); + }, ct); ct.ThrowIfCancellationRequested(); - _logger.LogDebug("Handling transient update for {obj}", playerRelatedObject); + var (resolvedTransientPaths, clearedForPet) = await transientTask.ConfigureAwait(false); - _transientResourceManager.ClearTransientPaths(objectKind, [.. fragment.FileReplacements.SelectMany(c => c.GamePaths)]); - - var transientPaths = ManageSemiTransientData(objectKind); - var resolvedTransientPaths = await GetFileReplacementsFromPaths(playerRelatedObject, transientPaths, new HashSet(StringComparer.Ordinal)).ConfigureAwait(false); + if (clearedForPet != null) + { + fragment.FileReplacements.Clear(); + } if (logDebug) { @@ -213,11 +250,6 @@ public class PlayerDataFactory fragment.FileReplacements = new HashSet(fragment.FileReplacements.Where(v => v.HasFileReplacement).OrderBy(v => v.ResolvedPath, StringComparer.Ordinal), FileReplacementComparer.Instance); - // gather up data from ipc - Task getHeelsOffset = _ipcManager.Heels.GetOffsetAsync(); - Task getGlamourerData = _ipcManager.Glamourer.GetCharacterCustomizationAsync(playerRelatedObject.Address); - Task getCustomizeData = _ipcManager.CustomizePlus.GetScaleAsync(playerRelatedObject.Address); - Task getHonorificTitle = _ipcManager.Honorific.GetTitle(); fragment.GlamourerString = await getGlamourerData.ConfigureAwait(false); _logger.LogDebug("Glamourer is now: {data}", fragment.GlamourerString); var customizeScale = await getCustomizeData.ConfigureAwait(false); @@ -229,13 +261,13 @@ public class PlayerDataFactory var playerFragment = (fragment as CharacterDataFragmentPlayer)!; playerFragment.ManipulationString = _ipcManager.Penumbra.GetMetaManipulations(); - playerFragment!.HonorificData = await getHonorificTitle.ConfigureAwait(false); + playerFragment!.HonorificData = await getHonorificTitle!.ConfigureAwait(false); _logger.LogDebug("Honorific is now: {data}", playerFragment!.HonorificData); - playerFragment!.HeelsData = await getHeelsOffset.ConfigureAwait(false); + playerFragment!.HeelsData = await getHeelsOffset!.ConfigureAwait(false); _logger.LogDebug("Heels is now: {heels}", playerFragment!.HeelsData); - playerFragment!.MoodlesData = await _ipcManager.Moodles.GetStatusAsync(playerRelatedObject.Address).ConfigureAwait(false) ?? string.Empty; + playerFragment!.MoodlesData = await getMoodlesData!.ConfigureAwait(false) ?? string.Empty; _logger.LogDebug("Moodles is now: {moodles}", playerFragment!.MoodlesData); playerFragment!.PetNamesData = _ipcManager.PetNames.GetLocalNames();