Add some startup information in debug mode.

This commit is contained in:
Ottermandias 2023-02-04 14:57:34 +01:00
parent e34aca68aa
commit 98bc14882b
4 changed files with 118 additions and 47 deletions

@ -1 +1 @@
Subproject commit 4e730a0d5a86a9819bcea0b766134c02f35ac27e Subproject commit aee8a3dc8e7eb1145c328a7c50f7e5bbcdd234f8

View file

@ -26,6 +26,7 @@ using Penumbra.GameData.Data;
using Penumbra.Interop.Loader; using Penumbra.Interop.Loader;
using Penumbra.Interop.Resolver; using Penumbra.Interop.Resolver;
using Penumbra.Mods; using Penumbra.Mods;
using Action = System.Action;
using CharacterUtility = Penumbra.Interop.CharacterUtility; using CharacterUtility = Penumbra.Interop.CharacterUtility;
using ResidentResourceManager = Penumbra.Interop.ResidentResourceManager; using ResidentResourceManager = Penumbra.Interop.ResidentResourceManager;
@ -66,8 +67,12 @@ public class Penumbra : IDalamudPlugin
public static IGamePathParser GamePathParser { get; private set; } = null!; public static IGamePathParser GamePathParser { get; private set; } = null!;
public static StainManager StainManager { get; private set; } = null!; public static StainManager StainManager { get; private set; } = null!;
public static ItemData ItemData { get; private set; } = null!; public static ItemData ItemData { get; private set; } = null!;
public static PerformanceTracker< PerformanceType > Performance { get; private set; } = null!; public static PerformanceTracker< PerformanceType > Performance { get; private set; } = null!;
public static StartTimeTracker< StartTimeType > StartTimer = new();
public static readonly List< Exception > ImcExceptions = new(); public static readonly List< Exception > ImcExceptions = new();
public readonly ResourceLogger ResourceLogger; public readonly ResourceLogger ResourceLogger;
@ -84,27 +89,39 @@ public class Penumbra : IDalamudPlugin
internal WebServer? WebServer; internal WebServer? WebServer;
private static void Timed( StartTimeType type, Action action )
{
using var t = StartTimer.Measure( type );
action();
}
public Penumbra( DalamudPluginInterface pluginInterface ) public Penumbra( DalamudPluginInterface pluginInterface )
{ {
using var time = StartTimer.Measure( StartTimeType.Total );
try try
{ {
Dalamud.Initialize( pluginInterface ); Dalamud.Initialize( pluginInterface );
Performance = new PerformanceTracker< PerformanceType >( Dalamud.Framework ); Performance = new PerformanceTracker< PerformanceType >( Dalamud.Framework );
Log = new Logger(); Log = new Logger();
DevPenumbraExists = CheckDevPluginPenumbra(); DevPenumbraExists = CheckDevPluginPenumbra();
IsNotInstalledPenumbra = CheckIsNotInstalled(); IsNotInstalledPenumbra = CheckIsNotInstalled();
IsValidSourceRepo = CheckSourceRepo(); IsValidSourceRepo = CheckSourceRepo();
GameEvents = new GameEventManager();
Identifier = GameData.GameData.GetIdentifier( Dalamud.PluginInterface, Dalamud.GameData );
GamePathParser = GameData.GameData.GetGamePathParser();
StainManager = new StainManager( Dalamud.PluginInterface, Dalamud.GameData );
ItemData = new ItemData( Dalamud.PluginInterface, Dalamud.GameData, Dalamud.GameData.Language );
Actors = new ActorManager( Dalamud.PluginInterface, Dalamud.Objects, Dalamud.ClientState, Dalamud.Framework, Dalamud.GameData, Dalamud.GameGui, ResolveCutscene );
Framework = new FrameworkManager(Dalamud.Framework, Log); GameEvents = new GameEventManager();
StartTimer.Measure( StartTimeType.Identifier, () => Identifier = GameData.GameData.GetIdentifier( Dalamud.PluginInterface, Dalamud.GameData ) );
StartTimer.Measure( StartTimeType.GamePathParser, () => GamePathParser = GameData.GameData.GetGamePathParser() );
StartTimer.Measure( StartTimeType.Stains, () => StainManager = new StainManager( Dalamud.PluginInterface, Dalamud.GameData ) );
StartTimer.Measure( StartTimeType.Items, () => ItemData = new ItemData( Dalamud.PluginInterface, Dalamud.GameData, Dalamud.GameData.Language ) );
StartTimer.Measure( StartTimeType.Actors,
() => Actors = new ActorManager( Dalamud.PluginInterface, Dalamud.Objects, Dalamud.ClientState, Dalamud.Framework, Dalamud.GameData, Dalamud.GameGui,
ResolveCutscene ) );
Framework = new FrameworkManager( Dalamud.Framework, Log );
CharacterUtility = new CharacterUtility(); CharacterUtility = new CharacterUtility();
Backup.CreateBackup( pluginInterface.ConfigDirectory, PenumbraBackupFiles() ); StartTimer.Measure( StartTimeType.Backup, () => Backup.CreateBackup( pluginInterface.ConfigDirectory, PenumbraBackupFiles() ) );
Config = Configuration.Load(); Config = Configuration.Load();
TempMods = new TempModManager(); TempMods = new TempModManager();
@ -113,10 +130,18 @@ public class Penumbra : IDalamudPlugin
ResourceLoader.EnableHooks(); ResourceLoader.EnableHooks();
ResourceLogger = new ResourceLogger( ResourceLoader ); ResourceLogger = new ResourceLogger( ResourceLoader );
ResidentResources = new ResidentResourceManager(); ResidentResources = new ResidentResourceManager();
StartTimer.Measure( StartTimeType.Mods, () =>
{
ModManager = new Mod.Manager( Config.ModDirectory ); ModManager = new Mod.Manager( Config.ModDirectory );
ModManager.DiscoverMods(); ModManager.DiscoverMods();
} );
StartTimer.Measure( StartTimeType.Collections, () =>
{
CollectionManager = new ModCollection.Manager( ModManager ); CollectionManager = new ModCollection.Manager( ModManager );
CollectionManager.CreateNecessaryCaches(); CollectionManager.CreateNecessaryCaches();
} );
ModFileSystem = ModFileSystem.Load(); ModFileSystem = ModFileSystem.Load();
ObjectReloader = new ObjectReloader(); ObjectReloader = new ObjectReloader();
PathResolver = new PathResolver( ResourceLoader ); PathResolver = new PathResolver( ResourceLoader );
@ -146,9 +171,13 @@ public class Penumbra : IDalamudPlugin
ResourceLoader.EnableFullLogging(); ResourceLoader.EnableFullLogging();
} }
using( var tAPI = StartTimer.Measure( StartTimeType.Api ) )
{
Api = new PenumbraApi( this ); Api = new PenumbraApi( this );
IpcProviders = new PenumbraIpcProviders( Dalamud.PluginInterface, Api ); IpcProviders = new PenumbraIpcProviders( Dalamud.PluginInterface, Api );
SubscribeItemLinks(); SubscribeItemLinks();
}
if( ImcExceptions.Count > 0 ) if( ImcExceptions.Count > 0 )
{ {
Log.Error( $"{ImcExceptions} IMC Exceptions thrown. Please repair your game files." ); Log.Error( $"{ImcExceptions} IMC Exceptions thrown. Please repair your game files." );
@ -177,6 +206,7 @@ public class Penumbra : IDalamudPlugin
private void SetupInterface( out ConfigWindow cfg, out LaunchButton btn, out WindowSystem system, out Changelog changelog ) private void SetupInterface( out ConfigWindow cfg, out LaunchButton btn, out WindowSystem system, out Changelog changelog )
{ {
using var tInterface = StartTimer.Measure( StartTimeType.Interface );
cfg = new ConfigWindow( this ); cfg = new ConfigWindow( this );
btn = new LaunchButton( _configWindow ); btn = new LaunchButton( _configWindow );
system = new WindowSystem( Name ); system = new WindowSystem( Name );
@ -341,7 +371,7 @@ public class Penumbra : IDalamudPlugin
sb.Append( $"> **`Free Drive Space: `** {( drive != null ? Functions.HumanReadableSize( drive.AvailableFreeSpace ) : "Unknown" )}\n" ); sb.Append( $"> **`Free Drive Space: `** {( drive != null ? Functions.HumanReadableSize( drive.AvailableFreeSpace ) : "Unknown" )}\n" );
sb.Append( $"> **`Auto-Deduplication: `** {Config.AutoDeduplicateOnImport}\n" ); sb.Append( $"> **`Auto-Deduplication: `** {Config.AutoDeduplicateOnImport}\n" );
sb.Append( $"> **`Debug Mode: `** {Config.DebugMode}\n" ); sb.Append( $"> **`Debug Mode: `** {Config.DebugMode}\n" );
sb.Append( $"> **`Synchronous Load (Dalamud): `** {(Dalamud.GetDalamudConfig( Dalamud.WaitingForPluginsOption, out bool v ) ? v.ToString() : "Unknown")}\n" ); sb.Append( $"> **`Synchronous Load (Dalamud): `** {( Dalamud.GetDalamudConfig( Dalamud.WaitingForPluginsOption, out bool v ) ? v.ToString() : "Unknown" )}\n" );
sb.Append( $"> **`Logging: `** Full: {Config.EnableFullResourceLogging}, Resource: {Config.EnableResourceLogging}\n" ); sb.Append( $"> **`Logging: `** Full: {Config.EnableFullResourceLogging}, Resource: {Config.EnableResourceLogging}\n" );
sb.Append( $"> **`Use Ownership: `** {Config.UseOwnerNameForCharacterCollection}\n" ); sb.Append( $"> **`Use Ownership: `** {Config.UseOwnerNameForCharacterCollection}\n" );
sb.AppendLine( "**Mods**" ); sb.AppendLine( "**Mods**" );

View file

@ -48,13 +48,13 @@ public partial class ConfigWindow
return; return;
} }
using var tab = ImRaii.TabItem( "Debug" ); using var tab = TabItem( "Debug" );
if( !tab ) if( !tab )
{ {
return; return;
} }
using var child = ImRaii.Child( "##DebugTab", -Vector2.One ); using var child = Child( "##DebugTab", -Vector2.One );
if( !child ) if( !child )
{ {
return; return;
@ -93,7 +93,7 @@ public partial class ConfigWindow
return; return;
} }
using var table = ImRaii.Table( "##DebugGeneralTable", 2, ImGuiTableFlags.SizingFixedFit, using var table = Table( "##DebugGeneralTable", 2, ImGuiTableFlags.SizingFixedFit,
new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 1 ) ); new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 1 ) );
if( !table ) if( !table )
{ {
@ -125,7 +125,9 @@ public partial class ConfigWindow
return; return;
} }
Penumbra.Performance.Draw( "##performance", "Enable Performance Tracking", PerformanceTypeExtensions.ToName ); Penumbra.StartTimer.Draw( "##startTimer", TimingExtensions.ToName );
ImGui.NewLine();
Penumbra.Performance.Draw( "##performance", "Enable Runtime Performance Tracking", TimingExtensions.ToName );
} }
// Draw all resources currently replaced by Penumbra and (if existing) the resources they replace. // Draw all resources currently replaced by Penumbra and (if existing) the resources they replace.
@ -144,7 +146,7 @@ public partial class ConfigWindow
return; return;
} }
using var table = ImRaii.Table( "##ReplacedResources", 6, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit, using var table = Table( "##ReplacedResources", 6, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit,
-Vector2.UnitX ); -Vector2.UnitX );
if( !table ) if( !table )
{ {
@ -182,7 +184,7 @@ public partial class ConfigWindow
return; return;
} }
using var table = ImRaii.Table( "##actors", 4, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit, using var table = Table( "##actors", 4, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit,
-Vector2.UnitX ); -Vector2.UnitX );
if( !table ) if( !table )
{ {
@ -229,11 +231,11 @@ public partial class ConfigWindow
ImGui.TextUnformatted( ImGui.TextUnformatted(
$"Last Game Object: 0x{_window._penumbra.PathResolver.LastGameObject:X} ({_window._penumbra.PathResolver.LastGameObjectData.ModCollection.Name})" ); $"Last Game Object: 0x{_window._penumbra.PathResolver.LastGameObject:X} ({_window._penumbra.PathResolver.LastGameObjectData.ModCollection.Name})" );
using( var drawTree = ImRaii.TreeNode( "Draw Object to Object" ) ) using( var drawTree = TreeNode( "Draw Object to Object" ) )
{ {
if( drawTree ) if( drawTree )
{ {
using var table = ImRaii.Table( "###DrawObjectResolverTable", 5, ImGuiTableFlags.SizingFixedFit ); using var table = Table( "###DrawObjectResolverTable", 5, ImGuiTableFlags.SizingFixedFit );
if( table ) if( table )
{ {
foreach( var (ptr, (c, idx)) in _window._penumbra.PathResolver.DrawObjectMap ) foreach( var (ptr, (c, idx)) in _window._penumbra.PathResolver.DrawObjectMap )
@ -256,11 +258,11 @@ public partial class ConfigWindow
} }
} }
using( var pathTree = ImRaii.TreeNode( "Path Collections" ) ) using( var pathTree = TreeNode( "Path Collections" ) )
{ {
if( pathTree ) if( pathTree )
{ {
using var table = ImRaii.Table( "###PathCollectionResolverTable", 3, ImGuiTableFlags.SizingFixedFit ); using var table = Table( "###PathCollectionResolverTable", 3, ImGuiTableFlags.SizingFixedFit );
if( table ) if( table )
{ {
foreach( var (path, collection) in _window._penumbra.PathResolver.PathCollections ) foreach( var (path, collection) in _window._penumbra.PathResolver.PathCollections )
@ -276,11 +278,11 @@ public partial class ConfigWindow
} }
} }
using( var resourceTree = ImRaii.TreeNode( "Subfile Collections" ) ) using( var resourceTree = TreeNode( "Subfile Collections" ) )
{ {
if( resourceTree ) if( resourceTree )
{ {
using var table = ImRaii.Table( "###ResourceCollectionResolverTable", 3, ImGuiTableFlags.SizingFixedFit ); using var table = Table( "###ResourceCollectionResolverTable", 3, ImGuiTableFlags.SizingFixedFit );
if( table ) if( table )
{ {
ImGuiUtil.DrawTableColumn( "Current Mtrl Data" ); ImGuiUtil.DrawTableColumn( "Current Mtrl Data" );
@ -305,11 +307,11 @@ public partial class ConfigWindow
} }
} }
using( var identifiedTree = ImRaii.TreeNode( "Identified Collections" ) ) using( var identifiedTree = TreeNode( "Identified Collections" ) )
{ {
if( identifiedTree ) if( identifiedTree )
{ {
using var table = ImRaii.Table( "##PathCollectionsIdentifiedTable", 3, ImGuiTableFlags.SizingFixedFit ); using var table = Table( "##PathCollectionsIdentifiedTable", 3, ImGuiTableFlags.SizingFixedFit );
if( table ) if( table )
{ {
foreach( var (address, identifier, collection) in PathResolver.IdentifiedCache ) foreach( var (address, identifier, collection) in PathResolver.IdentifiedCache )
@ -322,11 +324,11 @@ public partial class ConfigWindow
} }
} }
using( var cutsceneTree = ImRaii.TreeNode( "Cutscene Actors" ) ) using( var cutsceneTree = TreeNode( "Cutscene Actors" ) )
{ {
if( cutsceneTree ) if( cutsceneTree )
{ {
using var table = ImRaii.Table( "###PCutsceneResolverTable", 2, ImGuiTableFlags.SizingFixedFit ); using var table = Table( "###PCutsceneResolverTable", 2, ImGuiTableFlags.SizingFixedFit );
if( table ) if( table )
{ {
foreach( var (idx, actor) in _window._penumbra.PathResolver.CutsceneActors ) foreach( var (idx, actor) in _window._penumbra.PathResolver.CutsceneActors )
@ -338,11 +340,11 @@ public partial class ConfigWindow
} }
} }
using( var groupTree = ImRaii.TreeNode( "Group" ) ) using( var groupTree = TreeNode( "Group" ) )
{ {
if( groupTree ) if( groupTree )
{ {
using var table = ImRaii.Table( "###PGroupTable", 2, ImGuiTableFlags.SizingFixedFit ); using var table = Table( "###PGroupTable", 2, ImGuiTableFlags.SizingFixedFit );
if( table ) if( table )
{ {
ImGuiUtil.DrawTableColumn( "Group Members" ); ImGuiUtil.DrawTableColumn( "Group Members" );
@ -357,16 +359,19 @@ public partial class ConfigWindow
} }
} }
using( var bannerTree = ImRaii.TreeNode( "Party Banner" ) ) using( var bannerTree = TreeNode( "Party Banner" ) )
{ {
if( bannerTree ) if( bannerTree )
{ {
var agent = &AgentBannerParty.Instance()->AgentBannerInterface; var agent = &AgentBannerParty.Instance()->AgentBannerInterface;
if( agent->Data == null ) if( agent->Data == null )
{
agent = &AgentBannerMIP.Instance()->AgentBannerInterface; agent = &AgentBannerMIP.Instance()->AgentBannerInterface;
}
if( agent->Data != null ) if( agent->Data != null )
{ {
using var table = ImRaii.Table( "###PBannerTable", 2, ImGuiTableFlags.SizingFixedFit ); using var table = Table( "###PBannerTable", 2, ImGuiTableFlags.SizingFixedFit );
if( table ) if( table )
{ {
for( var i = 0; i < 8; ++i ) for( var i = 0; i < 8; ++i )
@ -395,13 +400,13 @@ public partial class ConfigWindow
foreach( var (key, data) in Penumbra.StainManager.StmFile.Entries ) foreach( var (key, data) in Penumbra.StainManager.StmFile.Entries )
{ {
using var tree = ImRaii.TreeNode( $"Template {key}" ); using var tree = TreeNode( $"Template {key}" );
if( !tree ) if( !tree )
{ {
continue; continue;
} }
using var table = ImRaii.Table( "##table", 5, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg ); using var table = Table( "##table", 5, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg );
if( !table ) if( !table )
{ {
continue; continue;
@ -436,7 +441,7 @@ public partial class ConfigWindow
return; return;
} }
using var table = ImRaii.Table( "##CharacterUtility", 6, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit, using var table = Table( "##CharacterUtility", 6, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit,
-Vector2.UnitX ); -Vector2.UnitX );
if( !table ) if( !table )
{ {
@ -491,7 +496,7 @@ public partial class ConfigWindow
return; return;
} }
using var table = ImRaii.Table( "##DebugMetaTable", 3, ImGuiTableFlags.SizingFixedFit ); using var table = Table( "##DebugMetaTable", 3, ImGuiTableFlags.SizingFixedFit );
if( !table ) if( !table )
{ {
return; return;
@ -518,7 +523,7 @@ public partial class ConfigWindow
return; return;
} }
using var table = ImRaii.Table( "##ResidentResources", 2, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit, using var table = Table( "##ResidentResources", 2, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit,
-Vector2.UnitX ); -Vector2.UnitX );
if( !table ) if( !table )
{ {
@ -551,7 +556,7 @@ public partial class ConfigWindow
return; return;
} }
using( var t1 = ImRaii.Table( "##table", 2, ImGuiTableFlags.SizingFixedFit ) ) using( var t1 = Table( "##table", 2, ImGuiTableFlags.SizingFixedFit ) )
{ {
if( t1 ) if( t1 )
{ {
@ -564,7 +569,7 @@ public partial class ConfigWindow
} }
} }
using var table = ImRaii.Table( $"##{name}DrawTable", 5, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit ); using var table = Table( $"##{name}DrawTable", 5, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit );
if( !table ) if( !table )
{ {
return; return;
@ -620,7 +625,7 @@ public partial class ConfigWindow
return; return;
} }
using var table = ImRaii.Table( "##ProblemsTable", 6, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit ); using var table = Table( "##ProblemsTable", 6, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit );
if( !table ) if( !table )
{ {
return; return;

View file

@ -1,5 +1,24 @@
using Lumina.Excel.GeneratedSheets;
using OtterGui.Classes;
using Penumbra.GameData;
namespace Penumbra.Util; namespace Penumbra.Util;
public enum StartTimeType
{
Total,
Identifier,
GamePathParser,
Stains,
Items,
Actors,
Backup,
Mods,
Collections,
Api,
Interface,
}
public enum PerformanceType public enum PerformanceType
{ {
UiMainWindow, UiMainWindow,
@ -28,8 +47,25 @@ public enum PerformanceType
DebugTimes, DebugTimes,
} }
public static class PerformanceTypeExtensions public static class TimingExtensions
{ {
public static string ToName( this StartTimeType type )
=> type switch
{
StartTimeType.Total => "Total Construction",
StartTimeType.Identifier => "Identification Data",
StartTimeType.GamePathParser => "Game Path Data",
StartTimeType.Stains => "Stain Data",
StartTimeType.Items => "Item Data",
StartTimeType.Actors => "Actor Data",
StartTimeType.Backup => "Checking Backups",
StartTimeType.Mods => "Loading Mods",
StartTimeType.Collections => "Loading Collections",
StartTimeType.Api => "Setting Up API",
StartTimeType.Interface => "Setting Up Interface",
_ => $"Unknown {( int )type}",
};
public static string ToName( this PerformanceType type ) public static string ToName( this PerformanceType type )
=> type switch => type switch
{ {