something something performance

This commit is contained in:
rootdarkarchon
2023-04-29 01:58:42 +02:00
parent 4f200f2072
commit 996f784c2b
3 changed files with 40 additions and 37 deletions

View File

@@ -11,11 +11,12 @@ namespace MareSynchronos.FileCache;
public sealed class TransientResourceManager : DisposableMediatorSubscriberBase
{
private readonly HashSet<string> _cachedHandledPaths = new(StringComparer.Ordinal);
private readonly TransientConfigService _configurationService;
private readonly DalamudUtilService _dalamudUtil;
private readonly string[] _fileTypesToHandle = new[] { "tmb", "pap", "avfx", "atex", "sklb", "eid", "phyb", "scd", "skp", "shpk" };
private readonly HashSet<GameObjectHandler> _playerRelatedPointers = new();
private HashSet<IntPtr> _cachedFrameAddresses = new();
public TransientResourceManager(ILogger<TransientResourceManager> logger, TransientConfigService configurationService,
DalamudUtilService dalamudUtil, MareMediator mediator) : base(logger, mediator)
@@ -60,7 +61,6 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase
}
private string PlayerPersistentDataKey => _dalamudUtil.PlayerName + "_" + _dalamudUtil.WorldId;
private ConcurrentDictionary<ObjectKind, HashSet<string>> SemiTransientResources { get; } = new();
private ConcurrentDictionary<IntPtr, HashSet<string>> TransientResources { get; } = new();
@@ -169,6 +169,8 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase
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())
{
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 gameObject = msg.GameObject;
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)))
{
_cachedHandledPaths.Add(gamePath);
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;
}
@@ -208,18 +232,8 @@ public sealed class TransientResourceManager : DisposableMediatorSubscriberBase
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) ||
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);
}

View File

@@ -119,7 +119,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
public async Task Initialize(string 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);
_lastGlamourerData = _originalGlamourerData;
@@ -541,7 +541,7 @@ public sealed class CachedPlayer : DisposableMediatorSubscriberBase
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;
var cancelToken = new CancellationTokenSource();

View File

@@ -30,6 +30,7 @@ public class DalamudUtilService : IHostedService
private readonly List<uint> ClassJobIdsIgnoredForPets = new() { 30 };
private uint? _classJobId = 0;
private DateTime _delayedFrameworkUpdateCheck = DateTime.Now;
private Dictionary<string, IntPtr> _playerCharas = new(StringComparer.Ordinal);
private bool _sentBetweenAreas = false;
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);
}
public PlayerCharacter? GetPlayerCharacterFromObjectTableByName(string characterName)
public IntPtr GetPlayerCharacterFromObjectTableByName(string characterName)
{
foreach (var item in _objectTable)
{
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;
if (_playerCharas.TryGetValue(characterName, out var pchar)) return pchar;
return IntPtr.Zero;
}
public List<PlayerCharacter> GetPlayerCharacters()
{
return _objectTable.Where(obj =>
obj.ObjectKind == Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Player &&
!string.Equals(obj.Name.ToString(), PlayerName, StringComparison.Ordinal)).Cast<PlayerCharacter>().ToList();
return _objectTable.OfType<PlayerCharacter>().ToList();
}
public unsafe bool IsGameObjectPresent(IntPtr key)
{
foreach (var obj in _objectTable)
{
if (obj.Address == key)
{
return true;
}
}
return false;
return _objectTable.Any(f => f.Address == key);
}
public async Task RunOnFrameworkThread(Action act, [CallerMemberName] string callerMember = "",
@@ -261,6 +247,9 @@ public class DalamudUtilService : IHostedService
private unsafe void FrameworkOnUpdateInternal()
{
if (_clientState.LocalPlayer?.IsDead ?? false) return;
_playerCharas = _objectTable.OfType<PlayerCharacter>().ToDictionary(p => p.Name.ToString(), p => p.Address, StringComparer.Ordinal);
if (GposeTarget != null && !IsInGpose)
{
_logger.LogDebug("Gpose start");