mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-18 14:44:29 +01:00
Minor changes.
This commit is contained in:
parent
a3ddce0ef5
commit
30a957356a
6 changed files with 33 additions and 29 deletions
|
|
@ -1,4 +1,3 @@
|
||||||
using System.IO;
|
|
||||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
|
|
@ -168,7 +167,7 @@ public unsafe class ResourceLoader : IDisposable, IService
|
||||||
|
|
||||||
if (resolvedPath == null || !Utf8GamePath.FromByteString(resolvedPath.Value.InternalName, out var p))
|
if (resolvedPath == null || !Utf8GamePath.FromByteString(resolvedPath.Value.InternalName, out var p))
|
||||||
{
|
{
|
||||||
returnValue = _resources.GetOriginalResource(sync, category, type, hash, path.Path, parameters, original: original);
|
returnValue = _resources.GetOriginalResource(sync, category, type, hash, path.Path, original, parameters);
|
||||||
TrackResourceLoad(returnValue, original);
|
TrackResourceLoad(returnValue, original);
|
||||||
ResourceLoaded?.Invoke(returnValue, path, resolvedPath, data);
|
ResourceLoaded?.Invoke(returnValue, path, resolvedPath, data);
|
||||||
return;
|
return;
|
||||||
|
|
@ -179,7 +178,7 @@ public unsafe class ResourceLoader : IDisposable, IService
|
||||||
hash = ComputeHash(resolvedPath.Value.InternalName, parameters);
|
hash = ComputeHash(resolvedPath.Value.InternalName, parameters);
|
||||||
var oldPath = path;
|
var oldPath = path;
|
||||||
path = p;
|
path = p;
|
||||||
returnValue = _resources.GetOriginalResource(sync, category, type, hash, path.Path, parameters, original: original);
|
returnValue = _resources.GetOriginalResource(sync, category, type, hash, path.Path, original, parameters);
|
||||||
TrackResourceLoad(returnValue, original);
|
TrackResourceLoad(returnValue, original);
|
||||||
ResourceLoaded?.Invoke(returnValue, oldPath, resolvedPath.Value, data);
|
ResourceLoaded?.Invoke(returnValue, oldPath, resolvedPath.Value, data);
|
||||||
}
|
}
|
||||||
|
|
@ -194,7 +193,7 @@ public unsafe class ResourceLoader : IDisposable, IService
|
||||||
|
|
||||||
private void ResourceStateUpdatedHandler(ResourceHandle* handle, Utf8GamePath syncOriginal, (byte, LoadState) previousState, ref uint returnValue)
|
private void ResourceStateUpdatedHandler(ResourceHandle* handle, Utf8GamePath syncOriginal, (byte, LoadState) previousState, ref uint returnValue)
|
||||||
{
|
{
|
||||||
if (handle->UnkState != 2 || handle->LoadState < LoadState.Success || previousState.Item1 == 2 && previousState.Item2 >= LoadState.Success)
|
if (handle->UnkState != 2 || handle->LoadState < LoadState.Success || previousState is { Item1: 2, Item2: >= LoadState.Success })
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!_ongoingLoads.TryRemove((nint)handle, out var asyncOriginal))
|
if (!_ongoingLoads.TryRemove((nint)handle, out var asyncOriginal))
|
||||||
|
|
@ -205,7 +204,7 @@ public unsafe class ResourceLoader : IDisposable, IService
|
||||||
Penumbra.Log.Warning($"[ResourceLoader] Resource original paths inconsistency: 0x{(nint)handle:X}, of path {path}, sync original {syncOriginal}, async original {asyncOriginal}.");
|
Penumbra.Log.Warning($"[ResourceLoader] Resource original paths inconsistency: 0x{(nint)handle:X}, of path {path}, sync original {syncOriginal}, async original {asyncOriginal}.");
|
||||||
var original = !asyncOriginal.IsEmpty ? asyncOriginal : syncOriginal;
|
var original = !asyncOriginal.IsEmpty ? asyncOriginal : syncOriginal;
|
||||||
|
|
||||||
// Penumbra.Log.Information($"[ResourceLoader] Resource is complete: 0x{(nint)handle:X}, of path {path}, original {original}, state {previousState.Item1}:{previousState.Item2} -> {handle->UnkState}:{handle->LoadState}, sync: {asyncOriginal.IsEmpty}");
|
Penumbra.Log.Excessive($"[ResourceLoader] Resource is complete: 0x{(nint)handle:X}, of path {path}, original {original}, state {previousState.Item1}:{previousState.Item2} -> {handle->UnkState}:{handle->LoadState}, sync: {asyncOriginal.IsEmpty}");
|
||||||
if (PathDataHandler.Split(path.AsSpan(), out var actualPath, out var additionalData))
|
if (PathDataHandler.Split(path.AsSpan(), out var actualPath, out var additionalData))
|
||||||
ResourceComplete?.Invoke(handle, new CiByteString(actualPath), original, additionalData, !asyncOriginal.IsEmpty);
|
ResourceComplete?.Invoke(handle, new CiByteString(actualPath), original, additionalData, !asyncOriginal.IsEmpty);
|
||||||
else
|
else
|
||||||
|
|
@ -223,7 +222,7 @@ public unsafe class ResourceLoader : IDisposable, IService
|
||||||
var path = handle->CsHandle.FileName;
|
var path = handle->CsHandle.FileName;
|
||||||
var original = asyncOriginal.IsEmpty ? syncOriginal : asyncOriginal;
|
var original = asyncOriginal.IsEmpty ? syncOriginal : asyncOriginal;
|
||||||
|
|
||||||
// Penumbra.Log.Information($"[ResourceLoader] Resource is about to be complete: 0x{(nint)handle:X}, of path {path}, original {original}");
|
Penumbra.Log.Excessive($"[ResourceLoader] Resource is about to be complete: 0x{(nint)handle:X}, of path {path}, original {original}");
|
||||||
if (PathDataHandler.Split(path.AsSpan(), out var actualPath, out var additionalData))
|
if (PathDataHandler.Split(path.AsSpan(), out var actualPath, out var additionalData))
|
||||||
BeforeResourceComplete?.Invoke(handle, new CiByteString(actualPath), original, additionalData, !asyncOriginal.IsEmpty);
|
BeforeResourceComplete?.Invoke(handle, new CiByteString(actualPath), original, additionalData, !asyncOriginal.IsEmpty);
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -125,15 +125,13 @@ public unsafe class ResourceService : IDisposable, IRequiredService
|
||||||
if (returnValue != null)
|
if (returnValue != null)
|
||||||
return returnValue;
|
return returnValue;
|
||||||
|
|
||||||
return GetOriginalResource(isSync, *categoryId, *resourceType, *resourceHash, gamePath.Path, pGetResParams, isUnk, unk8, unk9, original);
|
return GetOriginalResource(isSync, *categoryId, *resourceType, *resourceHash, gamePath.Path, original, pGetResParams, isUnk, unk8, unk9);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Call the original GetResource function. </summary>
|
/// <summary> Call the original GetResource function. </summary>
|
||||||
public ResourceHandle* GetOriginalResource(bool sync, ResourceCategory categoryId, ResourceType type, int hash, CiByteString path,
|
public ResourceHandle* GetOriginalResource(bool sync, ResourceCategory categoryId, ResourceType type, int hash, CiByteString path, Utf8GamePath original,
|
||||||
GetResourceParameters* resourceParameters = null, byte unk = 0, nint unk8 = 0, uint unk9 = 0, Utf8GamePath original = default)
|
GetResourceParameters* resourceParameters = null, byte unk = 0, nint unk8 = 0, uint unk9 = 0)
|
||||||
{
|
{
|
||||||
if (original.Path is null) // i. e. if original is default
|
|
||||||
Utf8GamePath.FromByteString(path, out original);
|
|
||||||
var previous = _currentGetResourcePath.Value;
|
var previous = _currentGetResourcePath.Value;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -187,7 +185,7 @@ public unsafe class ResourceService : IDisposable, IRequiredService
|
||||||
private uint UpdateResourceStateDetour(ResourceHandle* handle, byte offFileThread)
|
private uint UpdateResourceStateDetour(ResourceHandle* handle, byte offFileThread)
|
||||||
{
|
{
|
||||||
var previousState = (handle->UnkState, handle->LoadState);
|
var previousState = (handle->UnkState, handle->LoadState);
|
||||||
var syncOriginal = _currentGetResourcePath.IsValueCreated ? _currentGetResourcePath.Value! : Utf8GamePath.Empty;
|
var syncOriginal = _currentGetResourcePath.IsValueCreated ? _currentGetResourcePath.Value : Utf8GamePath.Empty;
|
||||||
ResourceStateUpdating?.Invoke(handle, syncOriginal);
|
ResourceStateUpdating?.Invoke(handle, syncOriginal);
|
||||||
var ret = _updateResourceStateHook.OriginalDisposeSafe(handle, offFileThread);
|
var ret = _updateResourceStateHook.OriginalDisposeSafe(handle, offFileThread);
|
||||||
ResourceStateUpdated?.Invoke(handle, syncOriginal, previousState, ref ret);
|
ResourceStateUpdated?.Invoke(handle, syncOriginal, previousState, ref ret);
|
||||||
|
|
|
||||||
|
|
@ -23,20 +23,17 @@ public unsafe class FilePostProcessService : IRequiredService, IDisposable
|
||||||
{
|
{
|
||||||
_resourceLoader = resourceLoader;
|
_resourceLoader = resourceLoader;
|
||||||
_processors = services.GetServicesImplementing<IFilePostProcessor>().ToFrozenDictionary(s => s.Type, s => s);
|
_processors = services.GetServicesImplementing<IFilePostProcessor>().ToFrozenDictionary(s => s.Type, s => s);
|
||||||
_resourceLoader.BeforeResourceComplete += OnResourceComplete;
|
_resourceLoader.BeforeResourceComplete += OnBeforeResourceComplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_resourceLoader.BeforeResourceComplete -= OnResourceComplete;
|
_resourceLoader.BeforeResourceComplete -= OnBeforeResourceComplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnResourceComplete(ResourceHandle* resource, CiByteString path, Utf8GamePath original,
|
private void OnBeforeResourceComplete(ResourceHandle* resource, CiByteString path, Utf8GamePath original,
|
||||||
ReadOnlySpan<byte> additionalData, bool isAsync)
|
ReadOnlySpan<byte> additionalData, bool isAsync)
|
||||||
{
|
{
|
||||||
if (resource->LoadState != LoadState.Success)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (_processors.TryGetValue(resource->FileType, out var processor))
|
if (_processors.TryGetValue(resource->FileType, out var processor))
|
||||||
processor.PostProcess(resource, original.Path, additionalData);
|
processor.PostProcess(resource, original.Path, additionalData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,11 +143,11 @@ internal unsafe struct Record
|
||||||
Crc64 = 0,
|
Crc64 = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Record CreateResourceComplete(CiByteString path, ResourceHandle* handle, Utf8GamePath originalPath)
|
public static Record CreateResourceComplete(CiByteString path, ResourceHandle* handle, Utf8GamePath originalPath, ReadOnlySpan<byte> additionalData)
|
||||||
=> new()
|
=> new()
|
||||||
{
|
{
|
||||||
Time = DateTime.UtcNow,
|
Time = DateTime.UtcNow,
|
||||||
Path = path.IsOwned ? path : path.Clone(),
|
Path = CombinedPath(path, additionalData),
|
||||||
OriginalPath = originalPath.Path.IsOwned ? originalPath.Path : originalPath.Path.Clone(),
|
OriginalPath = originalPath.Path.IsOwned ? originalPath.Path : originalPath.Path.Clone(),
|
||||||
Collection = null,
|
Collection = null,
|
||||||
Handle = handle,
|
Handle = handle,
|
||||||
|
|
@ -162,4 +162,17 @@ internal unsafe struct Record
|
||||||
LoadState = handle->LoadState,
|
LoadState = handle->LoadState,
|
||||||
Crc64 = 0,
|
Crc64 = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static CiByteString CombinedPath(CiByteString path, ReadOnlySpan<byte> additionalData)
|
||||||
|
{
|
||||||
|
if (additionalData.Length is 0)
|
||||||
|
return path.IsOwned ? path : path.Clone();
|
||||||
|
|
||||||
|
fixed (byte* ptr = additionalData)
|
||||||
|
{
|
||||||
|
// If a path has additional data and is split, it is always in the form of |{additionalData}|{path},
|
||||||
|
// so we can just read from the start of additional data - 1 and sum their length +2 for the pipes.
|
||||||
|
return new CiByteString(new ReadOnlySpan<byte>(ptr - 1, additionalData.Length + 2 + path.Length)).Clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,7 @@ public sealed class ResourceWatcher : IDisposable, ITab, IUiService
|
||||||
_newRecords.Enqueue(record);
|
_newRecords.Enqueue(record);
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void OnResourceComplete(ResourceHandle* resource, CiByteString path, Utf8GamePath original, ReadOnlySpan<byte> _, bool isAsync)
|
private unsafe void OnResourceComplete(ResourceHandle* resource, CiByteString path, Utf8GamePath original, ReadOnlySpan<byte> additionalData, bool isAsync)
|
||||||
{
|
{
|
||||||
if (!isAsync)
|
if (!isAsync)
|
||||||
return;
|
return;
|
||||||
|
|
@ -269,7 +269,7 @@ public sealed class ResourceWatcher : IDisposable, ITab, IUiService
|
||||||
if (!_ephemeral.EnableResourceWatcher)
|
if (!_ephemeral.EnableResourceWatcher)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var record = Record.CreateResourceComplete(path, resource, original);
|
var record = Record.CreateResourceComplete(path, resource, original, additionalData);
|
||||||
if (!_ephemeral.OnlyAddMatchingResources || _table.WouldBeVisible(record))
|
if (!_ephemeral.OnlyAddMatchingResources || _table.WouldBeVisible(record))
|
||||||
_newRecords.Enqueue(record);
|
_newRecords.Enqueue(record);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1104,7 +1104,7 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
|
|
||||||
private unsafe void DrawResourceLoader()
|
private unsafe void DrawResourceLoader()
|
||||||
{
|
{
|
||||||
if (!ImGui.CollapsingHeader("Resource Loader"))
|
if (!ImUtf8.CollapsingHeader("Resource Loader"u8))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var ongoingLoads = _resourceLoader.OngoingLoads;
|
var ongoingLoads = _resourceLoader.OngoingLoads;
|
||||||
|
|
@ -1125,12 +1125,9 @@ public class DebugTab : Window, ITab, IUiService
|
||||||
|
|
||||||
foreach (var (handle, original) in ongoingLoads)
|
foreach (var (handle, original) in ongoingLoads)
|
||||||
{
|
{
|
||||||
ImGui.TableNextColumn();
|
ImUtf8.DrawTableColumn($"0x{handle:X}");
|
||||||
ImUtf8.Text($"0x{handle:X}");
|
ImUtf8.DrawTableColumn(((ResourceHandle*)handle)->CsHandle.FileName);
|
||||||
ImGui.TableNextColumn();
|
ImUtf8.DrawTableColumn(original.Path.Span);
|
||||||
ImUtf8.Text(((ResourceHandle*)handle)->CsHandle.FileName);
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImUtf8.Text(original.Path.Span);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue