Make resolvedData thread-local

This commit is contained in:
Exter-N 2025-03-30 13:44:04 +02:00
parent cc76125b1c
commit 05dd985118

View file

@ -23,7 +23,7 @@ public unsafe class ResourceLoader : IDisposable, IService
private readonly ConcurrentDictionary<nint, Utf8GamePath> _ongoingLoads = []; private readonly ConcurrentDictionary<nint, Utf8GamePath> _ongoingLoads = [];
private ResolveData _resolvedData = ResolveData.Invalid; private readonly ThreadLocal<ResolveData> _resolvedData = new(() => ResolveData.Invalid);
public event Action<Utf8GamePath, FullPath?, ResolveData>? PapRequested; public event Action<Utf8GamePath, FullPath?, ResolveData>? PapRequested;
public IReadOnlyDictionary<nint, Utf8GamePath> OngoingLoads public IReadOnlyDictionary<nint, Utf8GamePath> OngoingLoads
@ -56,10 +56,11 @@ public unsafe class ResourceLoader : IDisposable, IService
if (!_config.EnableMods || !Utf8GamePath.FromPointer(path, MetaDataComputation.CiCrc32, out var gamePath)) if (!_config.EnableMods || !Utf8GamePath.FromPointer(path, MetaDataComputation.CiCrc32, out var gamePath))
return length; return length;
var resolvedData = _resolvedData.Value;
var (resolvedPath, data) = _incMode.Value var (resolvedPath, data) = _incMode.Value
? (null, ResolveData.Invalid) ? (null, ResolveData.Invalid)
: _resolvedData.Valid : resolvedData.Valid
? (_resolvedData.ModCollection.ResolvePath(gamePath), _resolvedData) ? (resolvedData.ModCollection.ResolvePath(gamePath), resolvedData)
: ResolvePath(gamePath, ResourceCategory.Chara, ResourceType.Pap); : ResolvePath(gamePath, ResourceCategory.Chara, ResourceType.Pap);
@ -78,19 +79,31 @@ public unsafe class ResourceLoader : IDisposable, IService
/// <summary> Load a resource for a given path and a specific collection. </summary> /// <summary> Load a resource for a given path and a specific collection. </summary>
public ResourceHandle* LoadResolvedResource(ResourceCategory category, ResourceType type, CiByteString path, ResolveData resolveData) public ResourceHandle* LoadResolvedResource(ResourceCategory category, ResourceType type, CiByteString path, ResolveData resolveData)
{ {
_resolvedData = resolveData; var previous = _resolvedData.Value;
var ret = _resources.GetResource(category, type, path); _resolvedData.Value = resolveData;
_resolvedData = ResolveData.Invalid; try
return ret; {
return _resources.GetResource(category, type, path);
}
finally
{
_resolvedData.Value = previous;
}
} }
/// <summary> Load a resource for a given path and a specific collection. </summary> /// <summary> Load a resource for a given path and a specific collection. </summary>
public SafeResourceHandle LoadResolvedSafeResource(ResourceCategory category, ResourceType type, CiByteString path, ResolveData resolveData) public SafeResourceHandle LoadResolvedSafeResource(ResourceCategory category, ResourceType type, CiByteString path, ResolveData resolveData)
{ {
_resolvedData = resolveData; var previous = _resolvedData.Value;
var ret = _resources.GetSafeResource(category, type, path); _resolvedData.Value = resolveData;
_resolvedData = ResolveData.Invalid; try
return ret; {
return _resources.GetSafeResource(category, type, path);
}
finally
{
_resolvedData.Value = previous;
}
} }
/// <summary> The function to use to resolve a given path. </summary> /// <summary> The function to use to resolve a given path. </summary>
@ -159,10 +172,11 @@ public unsafe class ResourceLoader : IDisposable, IService
CompareHash(ComputeHash(path.Path, parameters), hash, path); CompareHash(ComputeHash(path.Path, parameters), hash, path);
// If no replacements are being made, we still want to be able to trigger the event. // If no replacements are being made, we still want to be able to trigger the event.
var resolvedData = _resolvedData.Value;
var (resolvedPath, data) = _incMode.Value var (resolvedPath, data) = _incMode.Value
? (null, ResolveData.Invalid) ? (null, ResolveData.Invalid)
: _resolvedData.Valid : resolvedData.Valid
? (_resolvedData.ModCollection.ResolvePath(path), _resolvedData) ? (resolvedData.ModCollection.ResolvePath(path), resolvedData)
: ResolvePath(path, category, type); : ResolvePath(path, category, type);
if (resolvedPath == null || !Utf8GamePath.FromByteString(resolvedPath.Value.InternalName, out var p)) if (resolvedPath == null || !Utf8GamePath.FromByteString(resolvedPath.Value.InternalName, out var p))