something something performance
This commit is contained in:
		| @@ -11,11 +11,12 @@ namespace MareSynchronos.FileCache; | |||||||
|  |  | ||||||
| public sealed class TransientResourceManager : DisposableMediatorSubscriberBase | public sealed class TransientResourceManager : DisposableMediatorSubscriberBase | ||||||
| { | { | ||||||
|  |     private readonly HashSet<string> _cachedHandledPaths = new(StringComparer.Ordinal); | ||||||
|     private readonly TransientConfigService _configurationService; |     private readonly TransientConfigService _configurationService; | ||||||
|     private readonly DalamudUtilService _dalamudUtil; |     private readonly DalamudUtilService _dalamudUtil; | ||||||
|  |  | ||||||
|     private readonly string[] _fileTypesToHandle = new[] { "tmb", "pap", "avfx", "atex", "sklb", "eid", "phyb", "scd", "skp", "shpk" }; |     private readonly string[] _fileTypesToHandle = new[] { "tmb", "pap", "avfx", "atex", "sklb", "eid", "phyb", "scd", "skp", "shpk" }; | ||||||
|     private readonly HashSet<GameObjectHandler> _playerRelatedPointers = new(); |     private readonly HashSet<GameObjectHandler> _playerRelatedPointers = new(); | ||||||
|  |     private HashSet<IntPtr> _cachedFrameAddresses = new(); | ||||||
|  |  | ||||||
|     public TransientResourceManager(ILogger<TransientResourceManager> logger, TransientConfigService configurationService, |     public TransientResourceManager(ILogger<TransientResourceManager> logger, TransientConfigService configurationService, | ||||||
|         DalamudUtilService dalamudUtil, MareMediator mediator) : base(logger, mediator) |         DalamudUtilService dalamudUtil, MareMediator mediator) : base(logger, mediator) | ||||||
| @@ -60,7 +61,6 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private string PlayerPersistentDataKey => _dalamudUtil.PlayerName + "_" + _dalamudUtil.WorldId; |     private string PlayerPersistentDataKey => _dalamudUtil.PlayerName + "_" + _dalamudUtil.WorldId; | ||||||
|  |  | ||||||
|     private ConcurrentDictionary<ObjectKind, HashSet<string>> SemiTransientResources { get; } = new(); |     private ConcurrentDictionary<ObjectKind, HashSet<string>> SemiTransientResources { get; } = new(); | ||||||
|     private ConcurrentDictionary<IntPtr, HashSet<string>> TransientResources { get; } = new(); |     private ConcurrentDictionary<IntPtr, HashSet<string>> TransientResources { get; } = new(); | ||||||
|  |  | ||||||
| @@ -169,6 +169,8 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase | |||||||
|  |  | ||||||
|     private void DalamudUtil_FrameworkUpdate() |     private void DalamudUtil_FrameworkUpdate() | ||||||
|     { |     { | ||||||
|  |         _cachedFrameAddresses = _playerRelatedPointers.Select(c => c.CurrentAddress).ToHashSet(); | ||||||
|  |         _cachedHandledPaths.Clear(); | ||||||
|         foreach (var item in TransientResources.Where(item => !_dalamudUtil.IsGameObjectPresent(item.Key)).Select(i => i.Key).ToList()) |         foreach (var item in TransientResources.Where(item => !_dalamudUtil.IsGameObjectPresent(item.Key)).Select(i => i.Key).ToList()) | ||||||
|         { |         { | ||||||
|             Logger.LogDebug("Object not present anymore: {addr}", item.ToString("X")); |             Logger.LogDebug("Object not present anymore: {addr}", item.ToString("X")); | ||||||
| @@ -193,13 +195,35 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase | |||||||
|         var gamePath = msg.GamePath.ToLowerInvariant(); |         var gamePath = msg.GamePath.ToLowerInvariant(); | ||||||
|         var gameObject = msg.GameObject; |         var gameObject = msg.GameObject; | ||||||
|         var filePath = msg.FilePath; |         var filePath = msg.FilePath; | ||||||
|  |  | ||||||
|  |         // ignore files already processed this frame | ||||||
|  |         if (_cachedHandledPaths.Contains(gamePath)) return; | ||||||
|  |  | ||||||
|  |         _cachedHandledPaths.Add(gamePath); | ||||||
|  |  | ||||||
|  |         // replace individual mtrl stuff | ||||||
|  |         if (filePath.StartsWith("|", StringComparison.OrdinalIgnoreCase)) | ||||||
|  |         { | ||||||
|  |             filePath = filePath.Split("|")[2]; | ||||||
|  |         } | ||||||
|  |         // replace filepath | ||||||
|  |         filePath = filePath.ToLowerInvariant().Replace("\\", "/", StringComparison.OrdinalIgnoreCase); | ||||||
|  |  | ||||||
|  |         // ignore files that are the same | ||||||
|  |         var replacedGamePath = gamePath.ToLowerInvariant().Replace("\\", "/", StringComparison.OrdinalIgnoreCase); | ||||||
|  |         if (string.Equals(filePath, replacedGamePath, StringComparison.OrdinalIgnoreCase)) return; | ||||||
|  |  | ||||||
|  |         // ignore files to not handle | ||||||
|         if (!_fileTypesToHandle.Any(type => gamePath.EndsWith(type, StringComparison.OrdinalIgnoreCase))) |         if (!_fileTypesToHandle.Any(type => gamePath.EndsWith(type, StringComparison.OrdinalIgnoreCase))) | ||||||
|         { |         { | ||||||
|  |             _cachedHandledPaths.Add(gamePath); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         if (!_playerRelatedPointers.Select(p => p.CurrentAddress).Contains(gameObject)) |  | ||||||
|  |         // ignore files not belonging to anything player related | ||||||
|  |         if (!_cachedFrameAddresses.Contains(gameObject)) | ||||||
|         { |         { | ||||||
|             //_logger.LogDebug("Got resource " + gamePath + " for ptr " + gameObject.ToString("X")); |             _cachedHandledPaths.Add(gamePath); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -208,18 +232,8 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase | |||||||
|             TransientResources[gameObject] = new(StringComparer.OrdinalIgnoreCase); |             TransientResources[gameObject] = new(StringComparer.OrdinalIgnoreCase); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (filePath.StartsWith("|", StringComparison.OrdinalIgnoreCase)) |  | ||||||
|         { |  | ||||||
|             filePath = filePath.Split("|")[2]; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         filePath = filePath.ToLowerInvariant().Replace("\\", "/", StringComparison.OrdinalIgnoreCase); |  | ||||||
|  |  | ||||||
|         var replacedGamePath = gamePath.ToLowerInvariant().Replace("\\", "/", StringComparison.OrdinalIgnoreCase); |  | ||||||
|         if (string.Equals(filePath, replacedGamePath, StringComparison.OrdinalIgnoreCase)) return; |  | ||||||
|  |  | ||||||
|         if (TransientResources[gameObject].Contains(replacedGamePath) || |         if (TransientResources[gameObject].Contains(replacedGamePath) || | ||||||
|             SemiTransientResources.Any(r => r.Value.Any(f => string.Equals(f, gamePath, StringComparison.OrdinalIgnoreCase)))) |             SemiTransientResources.SelectMany(k => k.Value).Any(f => string.Equals(f, gamePath, StringComparison.OrdinalIgnoreCase))) | ||||||
|         { |         { | ||||||
|             Logger.LogTrace("Not adding {replacedPath} : {filePath}", replacedGamePath, filePath); |             Logger.LogTrace("Not adding {replacedPath} : {filePath}", replacedGamePath, filePath); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -119,7 +119,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase | |||||||
|     public async Task Initialize(string name) |     public async Task Initialize(string name) | ||||||
|     { |     { | ||||||
|         PlayerName = name; |         PlayerName = name; | ||||||
|         _charaHandler = _gameObjectHandlerFactory(ObjectKind.Player, () => _dalamudUtil.GetPlayerCharacterFromObjectTableByName(PlayerName)?.Address ?? IntPtr.Zero, false); |         _charaHandler = _gameObjectHandlerFactory(ObjectKind.Player, () => _dalamudUtil.GetPlayerCharacterFromObjectTableByName(PlayerName), false); | ||||||
|  |  | ||||||
|         _originalGlamourerData = await _ipcManager.GlamourerGetCharacterCustomization(PlayerCharacter).ConfigureAwait(false); |         _originalGlamourerData = await _ipcManager.GlamourerGetCharacterCustomization(PlayerCharacter).ConfigureAwait(false); | ||||||
|         _lastGlamourerData = _originalGlamourerData; |         _lastGlamourerData = _originalGlamourerData; | ||||||
| @@ -541,7 +541,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase | |||||||
|  |  | ||||||
|     private async Task RevertCustomizationData(ObjectKind objectKind, string name, Guid applicationId) |     private async Task RevertCustomizationData(ObjectKind objectKind, string name, Guid applicationId) | ||||||
|     { |     { | ||||||
|         nint address = _dalamudUtil.GetPlayerCharacterFromObjectTableByName(name)?.Address ?? IntPtr.Zero; |         nint address = _dalamudUtil.GetPlayerCharacterFromObjectTableByName(name); | ||||||
|         if (address == IntPtr.Zero) return; |         if (address == IntPtr.Zero) return; | ||||||
|  |  | ||||||
|         var cancelToken = new CancellationTokenSource(); |         var cancelToken = new CancellationTokenSource(); | ||||||
|   | |||||||
| @@ -30,6 +30,7 @@ public class DalamudUtilService : IHostedService | |||||||
|     private readonly List<uint> ClassJobIdsIgnoredForPets = new() { 30 }; |     private readonly List<uint> ClassJobIdsIgnoredForPets = new() { 30 }; | ||||||
|     private uint? _classJobId = 0; |     private uint? _classJobId = 0; | ||||||
|     private DateTime _delayedFrameworkUpdateCheck = DateTime.Now; |     private DateTime _delayedFrameworkUpdateCheck = DateTime.Now; | ||||||
|  |     private Dictionary<string, IntPtr> _playerCharas = new(StringComparer.Ordinal); | ||||||
|     private bool _sentBetweenAreas = false; |     private bool _sentBetweenAreas = false; | ||||||
|  |  | ||||||
|     public DalamudUtilService(ILogger<DalamudUtilService> logger, ClientState clientState, ObjectTable objectTable, Framework framework, |     public DalamudUtilService(ILogger<DalamudUtilService> logger, ClientState clientState, ObjectTable objectTable, Framework framework, | ||||||
| @@ -111,35 +112,20 @@ public class DalamudUtilService : IHostedService | |||||||
|         return await RunOnFrameworkThread(() => GetPetInternal(playerPointer)).ConfigureAwait(false); |         return await RunOnFrameworkThread(() => GetPetInternal(playerPointer)).ConfigureAwait(false); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public PlayerCharacter? GetPlayerCharacterFromObjectTableByName(string characterName) |     public IntPtr GetPlayerCharacterFromObjectTableByName(string characterName) | ||||||
|     { |     { | ||||||
|         foreach (var item in _objectTable) |         if (_playerCharas.TryGetValue(characterName, out var pchar)) return pchar; | ||||||
|         { |         return IntPtr.Zero; | ||||||
|             if (item.ObjectKind != Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Player) continue; |  | ||||||
|             if (string.Equals(item.Name.ToString(), characterName, StringComparison.Ordinal)) return (PlayerCharacter)item; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return null; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public List<PlayerCharacter> GetPlayerCharacters() |     public List<PlayerCharacter> GetPlayerCharacters() | ||||||
|     { |     { | ||||||
|         return _objectTable.Where(obj => |         return _objectTable.OfType<PlayerCharacter>().ToList(); | ||||||
|             obj.ObjectKind == Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Player && |  | ||||||
|             !string.Equals(obj.Name.ToString(), PlayerName, StringComparison.Ordinal)).Cast<PlayerCharacter>().ToList(); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public unsafe bool IsGameObjectPresent(IntPtr key) |     public unsafe bool IsGameObjectPresent(IntPtr key) | ||||||
|     { |     { | ||||||
|         foreach (var obj in _objectTable) |         return _objectTable.Any(f => f.Address == key); | ||||||
|         { |  | ||||||
|             if (obj.Address == key) |  | ||||||
|             { |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return false; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public async Task RunOnFrameworkThread(Action act, [CallerMemberName] string callerMember = "", |     public async Task RunOnFrameworkThread(Action act, [CallerMemberName] string callerMember = "", | ||||||
| @@ -261,6 +247,9 @@ public class DalamudUtilService : IHostedService | |||||||
|     private unsafe void FrameworkOnUpdateInternal() |     private unsafe void FrameworkOnUpdateInternal() | ||||||
|     { |     { | ||||||
|         if (_clientState.LocalPlayer?.IsDead ?? false) return; |         if (_clientState.LocalPlayer?.IsDead ?? false) return; | ||||||
|  |  | ||||||
|  |         _playerCharas = _objectTable.OfType<PlayerCharacter>().ToDictionary(p => p.Name.ToString(), p => p.Address, StringComparer.Ordinal); | ||||||
|  |  | ||||||
|         if (GposeTarget != null && !IsInGpose) |         if (GposeTarget != null && !IsInGpose) | ||||||
|         { |         { | ||||||
|             _logger.LogDebug("Gpose start"); |             _logger.LogDebug("Gpose start"); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 rootdarkarchon
					rootdarkarchon