mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-01-03 06:13:45 +01:00
Add mechanism to handle completion of async res loads
This commit is contained in:
parent
dcab443b2f
commit
a3ddce0ef5
11 changed files with 303 additions and 58 deletions
|
|
@ -10,10 +10,11 @@ namespace Penumbra.UI.ResourceWatcher;
|
|||
[Flags]
|
||||
public enum RecordType : byte
|
||||
{
|
||||
Request = 0x01,
|
||||
ResourceLoad = 0x02,
|
||||
FileLoad = 0x04,
|
||||
Destruction = 0x08,
|
||||
Request = 0x01,
|
||||
ResourceLoad = 0x02,
|
||||
FileLoad = 0x04,
|
||||
Destruction = 0x08,
|
||||
ResourceComplete = 0x10,
|
||||
}
|
||||
|
||||
internal unsafe struct Record
|
||||
|
|
@ -141,4 +142,24 @@ internal unsafe struct Record
|
|||
LoadState = handle->LoadState,
|
||||
Crc64 = 0,
|
||||
};
|
||||
|
||||
public static Record CreateResourceComplete(CiByteString path, ResourceHandle* handle, Utf8GamePath originalPath)
|
||||
=> new()
|
||||
{
|
||||
Time = DateTime.UtcNow,
|
||||
Path = path.IsOwned ? path : path.Clone(),
|
||||
OriginalPath = originalPath.Path.IsOwned ? originalPath.Path : originalPath.Path.Clone(),
|
||||
Collection = null,
|
||||
Handle = handle,
|
||||
ResourceType = handle->FileType.ToFlag(),
|
||||
Category = handle->Category.ToFlag(),
|
||||
RefCount = handle->RefCount,
|
||||
RecordType = RecordType.ResourceComplete,
|
||||
Synchronously = false,
|
||||
ReturnValue = OptionalBool.Null,
|
||||
CustomLoad = OptionalBool.Null,
|
||||
AssociatedGameObject = string.Empty,
|
||||
LoadState = handle->LoadState,
|
||||
Crc64 = 0,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,9 +47,10 @@ public sealed class ResourceWatcher : IDisposable, ITab, IUiService
|
|||
_table = new ResourceWatcherTable(config.Ephemeral, _records);
|
||||
_resources.ResourceRequested += OnResourceRequested;
|
||||
_destructor.Subscribe(OnResourceDestroyed, ResourceHandleDestructor.Priority.ResourceWatcher);
|
||||
_loader.ResourceLoaded += OnResourceLoaded;
|
||||
_loader.FileLoaded += OnFileLoaded;
|
||||
_loader.PapRequested += OnPapRequested;
|
||||
_loader.ResourceLoaded += OnResourceLoaded;
|
||||
_loader.ResourceComplete += OnResourceComplete;
|
||||
_loader.FileLoaded += OnFileLoaded;
|
||||
_loader.PapRequested += OnPapRequested;
|
||||
UpdateFilter(_ephemeral.ResourceLoggingFilter, false);
|
||||
_newMaxEntries = _config.MaxResourceWatcherRecords;
|
||||
}
|
||||
|
|
@ -73,9 +74,10 @@ public sealed class ResourceWatcher : IDisposable, ITab, IUiService
|
|||
_records.TrimExcess();
|
||||
_resources.ResourceRequested -= OnResourceRequested;
|
||||
_destructor.Unsubscribe(OnResourceDestroyed);
|
||||
_loader.ResourceLoaded -= OnResourceLoaded;
|
||||
_loader.FileLoaded -= OnFileLoaded;
|
||||
_loader.PapRequested -= OnPapRequested;
|
||||
_loader.ResourceLoaded -= OnResourceLoaded;
|
||||
_loader.ResourceComplete -= OnResourceComplete;
|
||||
_loader.FileLoaded -= OnFileLoaded;
|
||||
_loader.PapRequested -= OnPapRequested;
|
||||
}
|
||||
|
||||
private void Clear()
|
||||
|
|
@ -255,6 +257,23 @@ public sealed class ResourceWatcher : IDisposable, ITab, IUiService
|
|||
_newRecords.Enqueue(record);
|
||||
}
|
||||
|
||||
private unsafe void OnResourceComplete(ResourceHandle* resource, CiByteString path, Utf8GamePath original, ReadOnlySpan<byte> _, bool isAsync)
|
||||
{
|
||||
if (!isAsync)
|
||||
return;
|
||||
|
||||
if (_ephemeral.EnableResourceLogging && FilterMatch(path, out var match))
|
||||
Penumbra.Log.Information(
|
||||
$"[ResourceLoader] [DONE] [{resource->FileType}] Finished loading {match} into 0x{(ulong)resource:X}, state {resource->LoadState}.");
|
||||
|
||||
if (!_ephemeral.EnableResourceWatcher)
|
||||
return;
|
||||
|
||||
var record = Record.CreateResourceComplete(path, resource, original);
|
||||
if (!_ephemeral.OnlyAddMatchingResources || _table.WouldBeVisible(record))
|
||||
_newRecords.Enqueue(record);
|
||||
}
|
||||
|
||||
private unsafe void OnFileLoaded(ResourceHandle* resource, CiByteString path, bool success, bool custom, ReadOnlySpan<byte> _)
|
||||
{
|
||||
if (_ephemeral.EnableResourceLogging && FilterMatch(path, out var match))
|
||||
|
|
|
|||
|
|
@ -124,11 +124,12 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
{
|
||||
ImGui.TextUnformatted(item.RecordType switch
|
||||
{
|
||||
RecordType.Request => "REQ",
|
||||
RecordType.ResourceLoad => "LOAD",
|
||||
RecordType.FileLoad => "FILE",
|
||||
RecordType.Destruction => "DEST",
|
||||
_ => string.Empty,
|
||||
RecordType.Request => "REQ",
|
||||
RecordType.ResourceLoad => "LOAD",
|
||||
RecordType.FileLoad => "FILE",
|
||||
RecordType.Destruction => "DEST",
|
||||
RecordType.ResourceComplete => "DONE",
|
||||
_ => string.Empty,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -317,10 +318,10 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
{
|
||||
LoadState.None => FilterValue.HasFlag(LoadStateFlag.None),
|
||||
LoadState.Success => FilterValue.HasFlag(LoadStateFlag.Success),
|
||||
LoadState.Async => FilterValue.HasFlag(LoadStateFlag.Async),
|
||||
LoadState.Failure => FilterValue.HasFlag(LoadStateFlag.Failed),
|
||||
LoadState.FailedSubResource => FilterValue.HasFlag(LoadStateFlag.FailedSub),
|
||||
_ => FilterValue.HasFlag(LoadStateFlag.Unknown),
|
||||
<= LoadState.Constructed => FilterValue.HasFlag(LoadStateFlag.Unknown),
|
||||
< LoadState.Success => FilterValue.HasFlag(LoadStateFlag.Async),
|
||||
> LoadState.Success => FilterValue.HasFlag(LoadStateFlag.Failed),
|
||||
};
|
||||
|
||||
public override void DrawColumn(Record item, int _)
|
||||
|
|
@ -332,12 +333,12 @@ internal sealed class ResourceWatcherTable : Table<Record>
|
|||
{
|
||||
LoadState.Success => (FontAwesomeIcon.CheckCircle, ColorId.IncreasedMetaValue.Value(),
|
||||
$"Successfully loaded ({(byte)item.LoadState})."),
|
||||
LoadState.Async => (FontAwesomeIcon.Clock, ColorId.FolderLine.Value(), $"Loading asynchronously ({(byte)item.LoadState})."),
|
||||
LoadState.Failure => (FontAwesomeIcon.Times, ColorId.DecreasedMetaValue.Value(),
|
||||
$"Failed to load ({(byte)item.LoadState})."),
|
||||
LoadState.FailedSubResource => (FontAwesomeIcon.ExclamationCircle, ColorId.DecreasedMetaValue.Value(),
|
||||
$"Dependencies failed to load ({(byte)item.LoadState})."),
|
||||
_ => (FontAwesomeIcon.QuestionCircle, ColorId.UndefinedMod.Value(), $"Unknown state ({(byte)item.LoadState})."),
|
||||
<= LoadState.Constructed => (FontAwesomeIcon.QuestionCircle, ColorId.UndefinedMod.Value(), $"Not yet loaded ({(byte)item.LoadState})."),
|
||||
< LoadState.Success => (FontAwesomeIcon.Clock, ColorId.FolderLine.Value(), $"Loading asynchronously ({(byte)item.LoadState})."),
|
||||
> LoadState.Success => (FontAwesomeIcon.Times, ColorId.DecreasedMetaValue.Value(),
|
||||
$"Failed to load ({(byte)item.LoadState})."),
|
||||
};
|
||||
using (var font = ImRaii.PushFont(UiBuilder.IconFont))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ public class DebugTab : Window, ITab, IUiService
|
|||
private readonly StainService _stains;
|
||||
private readonly GlobalVariablesDrawer _globalVariablesDrawer;
|
||||
private readonly ResourceManagerService _resourceManager;
|
||||
private readonly ResourceLoader _resourceLoader;
|
||||
private readonly CollectionResolver _collectionResolver;
|
||||
private readonly DrawObjectState _drawObjectState;
|
||||
private readonly PathState _pathState;
|
||||
|
|
@ -109,7 +110,7 @@ public class DebugTab : Window, ITab, IUiService
|
|||
public DebugTab(PerformanceTracker performance, Configuration config, CollectionManager collectionManager, ObjectManager objects,
|
||||
IClientState clientState, IDataManager dataManager,
|
||||
ValidityChecker validityChecker, ModManager modManager, HttpApi httpApi, ActorManager actors, StainService stains,
|
||||
ResourceManagerService resourceManager, CollectionResolver collectionResolver,
|
||||
ResourceManagerService resourceManager, ResourceLoader resourceLoader, CollectionResolver collectionResolver,
|
||||
DrawObjectState drawObjectState, PathState pathState, SubfileHelper subfileHelper, IdentifiedCollectionCache identifiedCollectionCache,
|
||||
CutsceneService cutsceneService, ModImportManager modImporter, ImportPopup importPopup, FrameworkManager framework,
|
||||
TextureManager textureManager, ShaderReplacementFixer shaderReplacementFixer, RedrawService redraws, DictEmote emotes,
|
||||
|
|
@ -133,6 +134,7 @@ public class DebugTab : Window, ITab, IUiService
|
|||
_actors = actors;
|
||||
_stains = stains;
|
||||
_resourceManager = resourceManager;
|
||||
_resourceLoader = resourceLoader;
|
||||
_collectionResolver = collectionResolver;
|
||||
_drawObjectState = drawObjectState;
|
||||
_pathState = pathState;
|
||||
|
|
@ -191,6 +193,7 @@ public class DebugTab : Window, ITab, IUiService
|
|||
DrawShaderReplacementFixer();
|
||||
DrawData();
|
||||
DrawCrcCache();
|
||||
DrawResourceLoader();
|
||||
DrawResourceProblems();
|
||||
_renderTargetDrawer.Draw();
|
||||
_hookOverrides.Draw();
|
||||
|
|
@ -1099,6 +1102,38 @@ public class DebugTab : Window, ITab, IUiService
|
|||
}
|
||||
}
|
||||
|
||||
private unsafe void DrawResourceLoader()
|
||||
{
|
||||
if (!ImGui.CollapsingHeader("Resource Loader"))
|
||||
return;
|
||||
|
||||
var ongoingLoads = _resourceLoader.OngoingLoads;
|
||||
var ongoingLoadCount = ongoingLoads.Count;
|
||||
ImUtf8.Text($"Ongoing Loads: {ongoingLoadCount}");
|
||||
|
||||
if (ongoingLoadCount == 0)
|
||||
return;
|
||||
|
||||
using var table = ImUtf8.Table("ongoingLoadTable"u8, 3);
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
ImUtf8.TableSetupColumn("Resource Handle"u8, ImGuiTableColumnFlags.WidthStretch, 0.2f);
|
||||
ImUtf8.TableSetupColumn("Actual Path"u8, ImGuiTableColumnFlags.WidthStretch, 0.4f);
|
||||
ImUtf8.TableSetupColumn("Original Path"u8, ImGuiTableColumnFlags.WidthStretch, 0.4f);
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
foreach (var (handle, original) in ongoingLoads)
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
ImUtf8.Text($"0x{handle:X}");
|
||||
ImGui.TableNextColumn();
|
||||
ImUtf8.Text(((ResourceHandle*)handle)->CsHandle.FileName);
|
||||
ImGui.TableNextColumn();
|
||||
ImUtf8.Text(original.Path.Span);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Draw resources with unusual reference count. </summary>
|
||||
private unsafe void DrawResourceProblems()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue