Add IPC test, optimize tester a little, only call event when game object available.

This commit is contained in:
Ottermandias 2022-09-05 14:01:12 +02:00
parent d12a3dd152
commit 0f35dd69f9
5 changed files with 87 additions and 36 deletions

View file

@ -80,7 +80,9 @@ public interface IPenumbraApi : IPenumbraApiBase
// so you can apply flag changes after finishing. // so you can apply flag changes after finishing.
public event CreatedCharacterBaseDelegate? CreatedCharacterBase; public event CreatedCharacterBaseDelegate? CreatedCharacterBase;
public event GameObjectResourceResolvedDelegate GameObjectResourceResolved; // Triggered whenever a resource is redirected by Penumbra for a specific, identified game object.
// Does not trigger if the resource is not requested for a known game object.
public event GameObjectResourceResolvedDelegate? GameObjectResourceResolved;
// Queue redrawing of all actors of the given name with the given RedrawType. // Queue redrawing of all actors of the given name with the given RedrawType.
public void RedrawObject( string name, RedrawType setting ); public void RedrawObject( string name, RedrawType setting );

View file

@ -33,9 +33,12 @@ public class IpcTester : IDisposable
private readonly ICallGateSubscriber< ModSettingChange, string, string, bool, object? > _settingChanged; private readonly ICallGateSubscriber< ModSettingChange, string, string, bool, object? > _settingChanged;
private readonly ICallGateSubscriber< IntPtr, string, IntPtr, IntPtr, IntPtr, object? > _characterBaseCreating; private readonly ICallGateSubscriber< IntPtr, string, IntPtr, IntPtr, IntPtr, object? > _characterBaseCreating;
private readonly ICallGateSubscriber< IntPtr, string, IntPtr, object? > _characterBaseCreated; private readonly ICallGateSubscriber< IntPtr, string, IntPtr, object? > _characterBaseCreated;
private readonly ICallGateSubscriber< IntPtr, string, string, object? > _gameObjectResourcePathResolved;
private readonly List< DateTimeOffset > _initializedList = new(); private readonly List< DateTimeOffset > _initializedList = new();
private readonly List< DateTimeOffset > _disposedList = new(); private readonly List< DateTimeOffset > _disposedList = new();
private bool _subscribed = false;
public IpcTester( DalamudPluginInterface pi, PenumbraIpc ipc ) public IpcTester( DalamudPluginInterface pi, PenumbraIpc ipc )
{ {
@ -51,31 +54,51 @@ public class IpcTester : IDisposable
_characterBaseCreating = _characterBaseCreating =
_pi.GetIpcSubscriber< IntPtr, string, IntPtr, IntPtr, IntPtr, object? >( PenumbraIpc.LabelProviderCreatingCharacterBase ); _pi.GetIpcSubscriber< IntPtr, string, IntPtr, IntPtr, IntPtr, object? >( PenumbraIpc.LabelProviderCreatingCharacterBase );
_characterBaseCreated = _pi.GetIpcSubscriber< IntPtr, string, IntPtr, object? >( PenumbraIpc.LabelProviderCreatedCharacterBase ); _characterBaseCreated = _pi.GetIpcSubscriber< IntPtr, string, IntPtr, object? >( PenumbraIpc.LabelProviderCreatedCharacterBase );
_initialized.Subscribe( AddInitialized ); _gameObjectResourcePathResolved =
_disposed.Subscribe( AddDisposed ); _pi.GetIpcSubscriber< IntPtr, string, string, object? >( PenumbraIpc.LabelProviderGameObjectResourcePathResolved );
_redrawn.Subscribe( SetLastRedrawn ); }
_preSettingsDraw.Subscribe( UpdateLastDrawnMod );
_postSettingsDraw.Subscribe( UpdateLastDrawnMod ); private void SubscribeEvents()
_settingChanged.Subscribe( UpdateLastModSetting ); {
_characterBaseCreating.Subscribe( UpdateLastCreated ); if( !_subscribed )
_characterBaseCreated.Subscribe( UpdateLastCreated2 ); {
_modDirectoryChanged.Subscribe( UpdateModDirectoryChanged );
_initialized.Subscribe( AddInitialized );
_disposed.Subscribe( AddDisposed );
_redrawn.Subscribe( SetLastRedrawn );
_preSettingsDraw.Subscribe( UpdateLastDrawnMod );
_postSettingsDraw.Subscribe( UpdateLastDrawnMod );
_settingChanged.Subscribe( UpdateLastModSetting );
_characterBaseCreating.Subscribe( UpdateLastCreated );
_characterBaseCreated.Subscribe( UpdateLastCreated2 );
_modDirectoryChanged.Subscribe( UpdateModDirectoryChanged );
_gameObjectResourcePathResolved.Subscribe( UpdateGameObjectResourcePath );
_subscribed = true;
}
}
public void UnsubscribeEvents()
{
if( _subscribed )
{
_initialized.Unsubscribe( AddInitialized );
_disposed.Unsubscribe( AddDisposed );
_redrawn.Subscribe( SetLastRedrawn );
_tooltip?.Unsubscribe( AddedTooltip );
_click?.Unsubscribe( AddedClick );
_preSettingsDraw.Unsubscribe( UpdateLastDrawnMod );
_postSettingsDraw.Unsubscribe( UpdateLastDrawnMod );
_settingChanged.Unsubscribe( UpdateLastModSetting );
_characterBaseCreating.Unsubscribe( UpdateLastCreated );
_characterBaseCreated.Unsubscribe( UpdateLastCreated2 );
_modDirectoryChanged.Unsubscribe( UpdateModDirectoryChanged );
_gameObjectResourcePathResolved.Unsubscribe( UpdateGameObjectResourcePath );
_subscribed = false;
}
} }
public void Dispose() public void Dispose()
{ => UnsubscribeEvents();
_initialized.Unsubscribe( AddInitialized );
_disposed.Unsubscribe( AddDisposed );
_redrawn.Subscribe( SetLastRedrawn );
_tooltip?.Unsubscribe( AddedTooltip );
_click?.Unsubscribe( AddedClick );
_preSettingsDraw.Unsubscribe( UpdateLastDrawnMod );
_postSettingsDraw.Unsubscribe( UpdateLastDrawnMod );
_settingChanged.Unsubscribe( UpdateLastModSetting );
_characterBaseCreating.Unsubscribe( UpdateLastCreated );
_characterBaseCreated.Unsubscribe( UpdateLastCreated2 );
_modDirectoryChanged.Unsubscribe( UpdateModDirectoryChanged );
}
private void AddInitialized() private void AddInitialized()
=> _initializedList.Add( DateTimeOffset.UtcNow ); => _initializedList.Add( DateTimeOffset.UtcNow );
@ -87,6 +110,7 @@ public class IpcTester : IDisposable
{ {
try try
{ {
SubscribeEvents();
DrawAvailable(); DrawAvailable();
DrawGeneral(); DrawGeneral();
DrawResolve(); DrawResolve();
@ -224,6 +248,10 @@ public class IpcTester : IDisposable
private string _lastCreatedGameObjectName = string.Empty; private string _lastCreatedGameObjectName = string.Empty;
private IntPtr _lastCreatedDrawObject = IntPtr.Zero; private IntPtr _lastCreatedDrawObject = IntPtr.Zero;
private DateTimeOffset _lastCreatedGameObjectTime = DateTimeOffset.MaxValue; private DateTimeOffset _lastCreatedGameObjectTime = DateTimeOffset.MaxValue;
private string _lastResolvedGamePath = string.Empty;
private string _lastResolvedFullPath = string.Empty;
private string _lastResolvedObject = string.Empty;
private DateTimeOffset _lastResolvedGamePathTime = DateTimeOffset.MaxValue;
private unsafe void UpdateLastCreated( IntPtr gameObject, string _, IntPtr _2, IntPtr _3, IntPtr _4 ) private unsafe void UpdateLastCreated( IntPtr gameObject, string _, IntPtr _2, IntPtr _3, IntPtr _4 )
{ {
@ -241,6 +269,15 @@ public class IpcTester : IDisposable
_lastCreatedDrawObject = drawObject; _lastCreatedDrawObject = drawObject;
} }
private unsafe void UpdateGameObjectResourcePath( IntPtr gameObject, string gamePath, string fullPath )
{
var obj = ( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* )gameObject;
_lastResolvedObject = obj != null ? new Utf8String( obj->GetName() ).ToString() : "Unknown";
_lastResolvedGamePath = gamePath;
_lastResolvedFullPath = fullPath;
_lastResolvedGamePathTime = DateTimeOffset.Now;
}
private void DrawResolve() private void DrawResolve()
{ {
using var _ = ImRaii.TreeNode( "Resolve IPC" ); using var _ = ImRaii.TreeNode( "Resolve IPC" );
@ -336,6 +373,13 @@ public class IpcTester : IDisposable
? $"0x{_lastCreatedDrawObject:X} for <{_lastCreatedGameObjectName}> at {_lastCreatedGameObjectTime}" ? $"0x{_lastCreatedDrawObject:X} for <{_lastCreatedGameObjectName}> at {_lastCreatedGameObjectTime}"
: $"NULL for <{_lastCreatedGameObjectName}> at {_lastCreatedGameObjectTime}" ); : $"NULL for <{_lastCreatedGameObjectName}> at {_lastCreatedGameObjectTime}" );
} }
DrawIntro( PenumbraIpc.LabelProviderGameObjectResourcePathResolved, "Last GamePath resolved" );
if( _lastResolvedGamePathTime < DateTimeOffset.Now )
{
ImGui.TextUnformatted(
$"{_lastResolvedGamePath} -> {_lastResolvedFullPath} for <{_lastResolvedObject}> at {_lastResolvedGamePathTime}" );
}
} }
private string _redrawName = string.Empty; private string _redrawName = string.Empty;

View file

@ -96,8 +96,11 @@ public class PenumbraApi : IDisposable, IPenumbraApi
private unsafe void OnResourceLoaded( ResourceHandle* _, Utf8GamePath originalPath, FullPath? manipulatedPath, private unsafe void OnResourceLoaded( ResourceHandle* _, Utf8GamePath originalPath, FullPath? manipulatedPath,
ResolveData resolveData ) ResolveData resolveData )
{ {
GameObjectResourceResolved?.Invoke( resolveData.AssociatedGameObject, originalPath.ToString(), if( resolveData.AssociatedGameObject != IntPtr.Zero )
manipulatedPath?.ToString() ?? originalPath.ToString() ); {
GameObjectResourceResolved?.Invoke( resolveData.AssociatedGameObject, originalPath.ToString(),
manipulatedPath?.ToString() ?? originalPath.ToString() );
}
} }
public event Action< string, bool >? ModDirectoryChanged public event Action< string, bool >? ModDirectoryChanged

View file

@ -274,15 +274,15 @@ public partial class PenumbraIpc
public partial class PenumbraIpc public partial class PenumbraIpc
{ {
public const string LabelProviderResolveDefault = "Penumbra.ResolveDefaultPath"; public const string LabelProviderResolveDefault = "Penumbra.ResolveDefaultPath";
public const string LabelProviderResolveCharacter = "Penumbra.ResolveCharacterPath"; public const string LabelProviderResolveCharacter = "Penumbra.ResolveCharacterPath";
public const string LabelProviderResolvePlayer = "Penumbra.ResolvePlayerPath"; public const string LabelProviderResolvePlayer = "Penumbra.ResolvePlayerPath";
public const string LabelProviderGetDrawObjectInfo = "Penumbra.GetDrawObjectInfo"; public const string LabelProviderGetDrawObjectInfo = "Penumbra.GetDrawObjectInfo";
public const string LabelProviderGetCutsceneParentIndex = "Penumbra.GetCutsceneParentIndex"; public const string LabelProviderGetCutsceneParentIndex = "Penumbra.GetCutsceneParentIndex";
public const string LabelProviderReverseResolvePath = "Penumbra.ReverseResolvePath"; public const string LabelProviderReverseResolvePath = "Penumbra.ReverseResolvePath";
public const string LabelProviderReverseResolvePlayerPath = "Penumbra.ReverseResolvePlayerPath"; public const string LabelProviderReverseResolvePlayerPath = "Penumbra.ReverseResolvePlayerPath";
public const string LabelProviderCreatingCharacterBase = "Penumbra.CreatingCharacterBase"; public const string LabelProviderCreatingCharacterBase = "Penumbra.CreatingCharacterBase";
public const string LabelProviderCreatedCharacterBase = "Penumbra.CreatedCharacterBase"; public const string LabelProviderCreatedCharacterBase = "Penumbra.CreatedCharacterBase";
public const string LabelProviderGameObjectResourcePathResolved = "Penumbra.GameObjectResourcePathResolved"; public const string LabelProviderGameObjectResourcePathResolved = "Penumbra.GameObjectResourcePathResolved";
internal ICallGateProvider< string, string >? ProviderResolveDefault; internal ICallGateProvider< string, string >? ProviderResolveDefault;
@ -294,7 +294,7 @@ public partial class PenumbraIpc
internal ICallGateProvider< string, string[] >? ProviderReverseResolvePathPlayer; internal ICallGateProvider< string, string[] >? ProviderReverseResolvePathPlayer;
internal ICallGateProvider< IntPtr, string, IntPtr, IntPtr, IntPtr, object? >? ProviderCreatingCharacterBase; internal ICallGateProvider< IntPtr, string, IntPtr, IntPtr, IntPtr, object? >? ProviderCreatingCharacterBase;
internal ICallGateProvider< IntPtr, string, IntPtr, object? >? ProviderCreatedCharacterBase; internal ICallGateProvider< IntPtr, string, IntPtr, object? >? ProviderCreatedCharacterBase;
internal ICallGateProvider<IntPtr, string, string, object?>? ProviderGameObjectResourcePathResolved; internal ICallGateProvider< IntPtr, string, string, object? >? ProviderGameObjectResourcePathResolved;
private void InitializeResolveProviders( DalamudPluginInterface pi ) private void InitializeResolveProviders( DalamudPluginInterface pi )
{ {
@ -392,7 +392,8 @@ public partial class PenumbraIpc
try try
{ {
ProviderGameObjectResourcePathResolved = pi.GetIpcProvider<IntPtr, string, string, object?>( LabelProviderGameObjectResourcePathResolved ); ProviderGameObjectResourcePathResolved =
pi.GetIpcProvider< IntPtr, string, string, object? >( LabelProviderGameObjectResourcePathResolved );
Api.GameObjectResourceResolved += GameObjectResourceResolvdedEvent; Api.GameObjectResourceResolved += GameObjectResourceResolvdedEvent;
} }
catch( Exception e ) catch( Exception e )

View file

@ -422,6 +422,7 @@ public partial class ConfigWindow
{ {
if( !ImGui.CollapsingHeader( "IPC" ) ) if( !ImGui.CollapsingHeader( "IPC" ) )
{ {
_window._penumbra.Ipc.Tester.UnsubscribeEvents();
return; return;
} }