something something performance
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user