mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-02-23 08:17:59 +01:00
Some formatting, use ConcurrentSet explicitly for clarity.
This commit is contained in:
parent
32608ea45b
commit
0e0733dab0
4 changed files with 61 additions and 94 deletions
2
OtterGui
2
OtterGui
|
|
@ -1 +1 @@
|
||||||
Subproject commit 8c7a309d039fdf008c85cf51923b4eac51b32428
|
Subproject commit 86ec4d72c9c9ed57aa7be4a7d0c81069c5b94ad7
|
||||||
|
|
@ -154,7 +154,7 @@ public unsafe class SubfileHelper : IDisposable, IReadOnlyCollection<KeyValuePai
|
||||||
{
|
{
|
||||||
using var performance = _performance.Measure(PerformanceType.LoadShaders);
|
using var performance = _performance.Measure(PerformanceType.LoadShaders);
|
||||||
var last = _mtrlData.Value;
|
var last = _mtrlData.Value;
|
||||||
var mtrlData = LoadFileHelper(mtrlResourceHandle);
|
var mtrlData = LoadFileHelper(mtrlResourceHandle);
|
||||||
_mtrlData.Value = mtrlData;
|
_mtrlData.Value = mtrlData;
|
||||||
var ret = _loadMtrlShpkHook.Original(mtrlResourceHandle);
|
var ret = _loadMtrlShpkHook.Original(mtrlResourceHandle);
|
||||||
_mtrlData.Value = last;
|
_mtrlData.Value = last;
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Dalamud.Hooking;
|
using Dalamud.Hooking;
|
||||||
using Dalamud.Utility.Signatures;
|
using Dalamud.Utility.Signatures;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
|
using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
|
||||||
|
using OtterGui.Classes;
|
||||||
using Penumbra.Communication;
|
using Penumbra.Communication;
|
||||||
using Penumbra.GameData;
|
using Penumbra.GameData;
|
||||||
using Penumbra.Interop.ResourceLoading;
|
|
||||||
using Penumbra.Services;
|
using Penumbra.Services;
|
||||||
using Penumbra.Util;
|
|
||||||
|
|
||||||
namespace Penumbra.Interop.Services;
|
namespace Penumbra.Interop.Services;
|
||||||
|
|
||||||
|
|
@ -37,30 +35,28 @@ public sealed unsafe class SkinFixer : IDisposable
|
||||||
|
|
||||||
private readonly GameEventManager _gameEvents;
|
private readonly GameEventManager _gameEvents;
|
||||||
private readonly CommunicatorService _communicator;
|
private readonly CommunicatorService _communicator;
|
||||||
private readonly ResourceLoader _resources;
|
|
||||||
private readonly CharacterUtility _utility;
|
private readonly CharacterUtility _utility;
|
||||||
|
|
||||||
// MaterialResourceHandle set
|
// MaterialResourceHandle set
|
||||||
private readonly ConcurrentDictionary<nint, Unit> _moddedSkinShpkMaterials = new();
|
private readonly ConcurrentSet<nint> _moddedSkinShpkMaterials = new();
|
||||||
|
|
||||||
private readonly object _lock = new();
|
private readonly object _lock = new();
|
||||||
|
|
||||||
// ConcurrentDictionary.Count uses a lock in its current implementation.
|
// ConcurrentDictionary.Count uses a lock in its current implementation.
|
||||||
private int _moddedSkinShpkCount = 0;
|
private int _moddedSkinShpkCount;
|
||||||
private ulong _slowPathCallDelta = 0;
|
private ulong _slowPathCallDelta;
|
||||||
|
|
||||||
public bool Enabled { get; internal set; } = true;
|
public bool Enabled { get; internal set; } = true;
|
||||||
|
|
||||||
public int ModdedSkinShpkCount
|
public int ModdedSkinShpkCount
|
||||||
=> _moddedSkinShpkCount;
|
=> _moddedSkinShpkCount;
|
||||||
|
|
||||||
public SkinFixer(GameEventManager gameEvents, ResourceLoader resources, CharacterUtility utility, CommunicatorService communicator)
|
public SkinFixer(GameEventManager gameEvents, CharacterUtility utility, CommunicatorService communicator)
|
||||||
{
|
{
|
||||||
SignatureHelper.Initialise(this);
|
SignatureHelper.Initialise(this);
|
||||||
_gameEvents = gameEvents;
|
_gameEvents = gameEvents;
|
||||||
_resources = resources;
|
|
||||||
_utility = utility;
|
_utility = utility;
|
||||||
_communicator = communicator;
|
_communicator = communicator;
|
||||||
_onRenderMaterialHook = Hook<OnRenderMaterialDelegate>.FromAddress(_humanVTable[62], OnRenderHumanMaterial);
|
_onRenderMaterialHook = Hook<OnRenderMaterialDelegate>.FromAddress(_humanVTable[62], OnRenderHumanMaterial);
|
||||||
_communicator.MtrlShpkLoaded.Subscribe(OnMtrlShpkLoaded, MtrlShpkLoaded.Priority.SkinFixer);
|
_communicator.MtrlShpkLoaded.Subscribe(OnMtrlShpkLoaded, MtrlShpkLoaded.Priority.SkinFixer);
|
||||||
_gameEvents.ResourceHandleDestructor += OnResourceHandleDestructor;
|
_gameEvents.ResourceHandleDestructor += OnResourceHandleDestructor;
|
||||||
|
|
@ -95,19 +91,16 @@ public sealed unsafe class SkinFixer : IDisposable
|
||||||
if (shpk == null)
|
if (shpk == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!IsSkinMaterial(mtrl))
|
if (!IsSkinMaterial(mtrl) || (nint)shpk == _utility.DefaultSkinShpkResource)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((nint)shpk != _utility.DefaultSkinShpkResource)
|
if (_moddedSkinShpkMaterials.TryAdd(mtrlResourceHandle))
|
||||||
{
|
Interlocked.Increment(ref _moddedSkinShpkCount);
|
||||||
if (_moddedSkinShpkMaterials.TryAdd(mtrlResourceHandle, Unit.Instance))
|
|
||||||
Interlocked.Increment(ref _moddedSkinShpkCount);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnResourceHandleDestructor(Structs.ResourceHandle* handle)
|
private void OnResourceHandleDestructor(Structs.ResourceHandle* handle)
|
||||||
{
|
{
|
||||||
if (_moddedSkinShpkMaterials.TryRemove((nint)handle, out _))
|
if (_moddedSkinShpkMaterials.TryRemove((nint)handle))
|
||||||
Interlocked.Decrement(ref _moddedSkinShpkCount);
|
Interlocked.Decrement(ref _moddedSkinShpkCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,12 +108,12 @@ public sealed unsafe class SkinFixer : IDisposable
|
||||||
{
|
{
|
||||||
// If we don't have any on-screen instances of modded skin.shpk, we don't need the slow path at all.
|
// If we don't have any on-screen instances of modded skin.shpk, we don't need the slow path at all.
|
||||||
if (!Enabled || _moddedSkinShpkCount == 0)
|
if (!Enabled || _moddedSkinShpkCount == 0)
|
||||||
return _onRenderMaterialHook!.Original(human, param);
|
return _onRenderMaterialHook.Original(human, param);
|
||||||
|
|
||||||
var material = param->Model->Materials[param->MaterialIndex];
|
var material = param->Model->Materials[param->MaterialIndex];
|
||||||
var mtrlResource = (Structs.MtrlResource*)material->MaterialResourceHandle;
|
var mtrlResource = (Structs.MtrlResource*)material->MaterialResourceHandle;
|
||||||
if (!IsSkinMaterial(mtrlResource))
|
if (!IsSkinMaterial(mtrlResource))
|
||||||
return _onRenderMaterialHook!.Original(human, param);
|
return _onRenderMaterialHook.Original(human, param);
|
||||||
|
|
||||||
Interlocked.Increment(ref _slowPathCallDelta);
|
Interlocked.Increment(ref _slowPathCallDelta);
|
||||||
|
|
||||||
|
|
@ -134,7 +127,7 @@ public sealed unsafe class SkinFixer : IDisposable
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_utility.Address->SkinShpkResource = (Structs.ResourceHandle*)mtrlResource->ShpkResourceHandle;
|
_utility.Address->SkinShpkResource = (Structs.ResourceHandle*)mtrlResource->ShpkResourceHandle;
|
||||||
return _onRenderMaterialHook!.Original(human, param);
|
return _onRenderMaterialHook.Original(human, param);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Penumbra.Util;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An empty structure. Can be used as value of a concurrent dictionary, to use it as a set.
|
|
||||||
/// </summary>
|
|
||||||
public readonly struct Unit : IEquatable<Unit>
|
|
||||||
{
|
|
||||||
public static readonly Unit Instance = new();
|
|
||||||
|
|
||||||
public bool Equals(Unit other)
|
|
||||||
=> true;
|
|
||||||
|
|
||||||
public override bool Equals(object? obj)
|
|
||||||
=> obj is Unit;
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
=> 0;
|
|
||||||
|
|
||||||
public static bool operator ==(Unit left, Unit right)
|
|
||||||
=> true;
|
|
||||||
|
|
||||||
public static bool operator !=(Unit left, Unit right)
|
|
||||||
=> false;
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue