Add load state to resource watcher.

This commit is contained in:
Ottermandias 2023-09-18 18:18:23 +02:00
parent 5506dcc3f3
commit 5067ab2bb2
3 changed files with 107 additions and 0 deletions

View file

@ -34,6 +34,15 @@ public unsafe struct ShaderPackageResourceHandle
public ShaderPackage* ShaderPackage;
}
public enum LoadState : byte
{
Success = 0x07,
Async = 0x03,
Failure = 0x09,
FailedSubResource = 0x0A,
None = 0xFF,
}
[StructLayout(LayoutKind.Explicit)]
public unsafe struct ResourceHandle
{
@ -99,6 +108,9 @@ public unsafe struct ResourceHandle
[FieldOffset(0x58)]
public int FileNameLength;
[FieldOffset(0xA9)]
public LoadState LoadState;
[FieldOffset(0xAC)]
public uint RefCount;

View file

@ -30,6 +30,7 @@ internal unsafe struct Record
public OptionalBool Synchronously;
public OptionalBool ReturnValue;
public OptionalBool CustomLoad;
public LoadState LoadState;
public static Record CreateRequest(ByteString path, bool sync)
=> new()
@ -47,6 +48,7 @@ internal unsafe struct Record
ReturnValue = OptionalBool.Null,
CustomLoad = OptionalBool.Null,
AssociatedGameObject = string.Empty,
LoadState = LoadState.None,
};
public static Record CreateDefaultLoad(ByteString path, ResourceHandle* handle, ModCollection collection, string associatedGameObject)
@ -67,6 +69,7 @@ internal unsafe struct Record
ReturnValue = OptionalBool.Null,
CustomLoad = false,
AssociatedGameObject = associatedGameObject,
LoadState = handle->LoadState,
};
}
@ -87,6 +90,7 @@ internal unsafe struct Record
ReturnValue = OptionalBool.Null,
CustomLoad = true,
AssociatedGameObject = associatedGameObject,
LoadState = handle->LoadState,
};
public static Record CreateDestruction(ResourceHandle* handle)
@ -107,6 +111,7 @@ internal unsafe struct Record
ReturnValue = OptionalBool.Null,
CustomLoad = OptionalBool.Null,
AssociatedGameObject = string.Empty,
LoadState = handle->LoadState,
};
}
@ -126,5 +131,6 @@ internal unsafe struct Record
ReturnValue = ret,
CustomLoad = custom,
AssociatedGameObject = string.Empty,
LoadState = handle->LoadState,
};
}

View file

@ -5,7 +5,9 @@ using OtterGui.Classes;
using OtterGui.Raii;
using OtterGui.Table;
using Penumbra.Enums;
using Penumbra.Interop.Structs;
using Penumbra.String;
using Penumbra.UI.Classes;
namespace Penumbra.UI.ResourceWatcher;
@ -24,6 +26,7 @@ internal sealed class ResourceWatcherTable : Table<Record>
new ResourceCategoryColumn(config) { Label = "Category" },
new ResourceTypeColumn(config) { Label = "Type" },
new HandleColumn { Label = "Resource" },
new LoadStateColumn { Label = "State" },
new RefCountColumn { Label = "#Ref" },
new DateColumn { Label = "Time" }
)
@ -241,6 +244,92 @@ internal sealed class ResourceWatcherTable : Table<Record>
}
}
private sealed class LoadStateColumn : ColumnFlags<LoadStateColumn.LoadStateFlag, Record>
{
public override float Width
=> 50 * UiHelpers.Scale;
[Flags]
public enum LoadStateFlag : byte
{
Success = 0x01,
Async = 0x02,
Failed = 0x04,
FailedSub = 0x08,
Unknown = 0x10,
None = 0xFF,
}
protected override string[] Names
=> new[]
{
"Loaded",
"Loading",
"Failed",
"Dependency Failed",
"Unknown",
"None",
};
public LoadStateColumn()
{
AllFlags = Enum.GetValues<LoadStateFlag>().Aggregate((v, f) => v | f);
_filterValue = AllFlags;
}
private LoadStateFlag _filterValue;
public override LoadStateFlag FilterValue
=> _filterValue;
protected override void SetValue(LoadStateFlag value, bool enable)
{
if (enable)
_filterValue |= value;
else
_filterValue &= ~value;
}
public override bool FilterFunc(Record item)
=> item.LoadState switch
{
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),
};
public override void DrawColumn(Record item, int _)
{
if (item.LoadState == LoadState.None)
return;
var (icon, color, tt) = item.LoadState switch
{
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})."),
};
using (var font = ImRaii.PushFont(UiBuilder.IconFont))
{
using var c = ImRaii.PushColor(ImGuiCol.Text, color);
ImGui.TextUnformatted(icon.ToIconString());
}
ImGuiUtil.HoverTooltip(tt);
}
public override int Compare(Record lhs, Record rhs)
=> lhs.LoadState.CompareTo(rhs.LoadState);
}
private sealed class HandleColumn : ColumnString<Record>
{
public override float Width