[AddonEventManager] Add Dalamud specific EventListener for internal use

This commit is contained in:
MidoriKami 2023-09-02 13:56:44 -07:00
parent 627a41f236
commit ce4392e109

View file

@ -16,13 +16,16 @@ namespace Dalamud.Game.AddonEventManager;
/// </summary> /// </summary>
[InterfaceVersion("1.0")] [InterfaceVersion("1.0")]
[ServiceManager.EarlyLoadedService] [ServiceManager.EarlyLoadedService]
internal unsafe class AddonEventManager : IDisposable, IServiceType internal unsafe class AddonEventManager : IDisposable, IServiceType, IAddonEventManager
{ {
private static readonly ModuleLog Log = new("AddonEventManager"); private static readonly ModuleLog Log = new("AddonEventManager");
private readonly AddonEventManagerAddressResolver address; private readonly AddonEventManagerAddressResolver address;
private readonly Hook<UpdateCursorDelegate> onUpdateCursor; private readonly Hook<UpdateCursorDelegate> onUpdateCursor;
private readonly AddonEventListener eventListener;
private readonly Dictionary<uint, IAddonEventManager.AddonEventHandler> eventHandlers;
private AddonCursorType? cursorOverride; private AddonCursorType? cursorOverride;
[ServiceManager.ServiceConstructor] [ServiceManager.ServiceConstructor]
@ -31,6 +34,9 @@ internal unsafe class AddonEventManager : IDisposable, IServiceType
this.address = new AddonEventManagerAddressResolver(); this.address = new AddonEventManagerAddressResolver();
this.address.Setup(sigScanner); this.address.Setup(sigScanner);
this.eventHandlers = new Dictionary<uint, IAddonEventManager.AddonEventHandler>();
this.eventListener = new AddonEventListener(this.DalamudAddonEventHandler);
this.cursorOverride = null; this.cursorOverride = null;
this.onUpdateCursor = Hook<UpdateCursorDelegate>.FromAddress(this.address.UpdateCursor, this.UpdateCursorDetour); this.onUpdateCursor = Hook<UpdateCursorDelegate>.FromAddress(this.address.UpdateCursor, this.UpdateCursorDetour);
@ -38,21 +44,53 @@ internal unsafe class AddonEventManager : IDisposable, IServiceType
private delegate nint UpdateCursorDelegate(RaptureAtkModule* module); private delegate nint UpdateCursorDelegate(RaptureAtkModule* module);
/// <inheritdoc/>
public void AddEvent(uint eventId, IntPtr atkUnitBase, IntPtr atkResNode, AddonEventType eventType, IAddonEventManager.AddonEventHandler eventHandler)
{
if (!this.eventHandlers.ContainsKey(eventId))
{
var type = (AtkEventType)eventType;
var node = (AtkResNode*)atkResNode;
var addon = (AtkUnitBase*)atkUnitBase;
this.eventHandlers.Add(eventId, eventHandler);
this.eventListener.RegisterEvent(addon, node, type, eventId);
}
else
{
Log.Warning($"Attempted to register already registered eventId: {eventId}");
}
}
/// <inheritdoc/>
public void RemoveEvent(uint eventId, IntPtr atkResNode, AddonEventType eventType)
{
if (this.eventHandlers.ContainsKey(eventId))
{
var type = (AtkEventType)eventType;
var node = (AtkResNode*)atkResNode;
this.eventListener.UnregisterEvent(node, type, eventId);
this.eventHandlers.Remove(eventId);
}
else
{
Log.Warning($"Attempted to unregister already unregistered eventId: {eventId}");
}
}
/// <inheritdoc/> /// <inheritdoc/>
public void Dispose() public void Dispose()
{ {
this.onUpdateCursor.Dispose(); this.onUpdateCursor.Dispose();
this.eventListener.Dispose();
this.eventHandlers.Clear();
} }
/// <summary> /// <inheritdoc/>
/// Sets the game cursor.
/// </summary>
/// <param name="cursor">Cursor type to set.</param>
public void SetCursor(AddonCursorType cursor) => this.cursorOverride = cursor; public void SetCursor(AddonCursorType cursor) => this.cursorOverride = cursor;
/// <summary> /// <inheritdoc/>
/// Resets and un-forces custom cursor.
/// </summary>
public void ResetCursor() => this.cursorOverride = null; public void ResetCursor() => this.cursorOverride = null;
[ServiceManager.CallWhenServicesReady] [ServiceManager.CallWhenServicesReady]
@ -85,6 +123,22 @@ internal unsafe class AddonEventManager : IDisposable, IServiceType
return this.onUpdateCursor!.Original(module); return this.onUpdateCursor!.Original(module);
} }
private void DalamudAddonEventHandler(AtkEventListener* self, AtkEventType eventType, uint eventParam, AtkEvent* eventData, IntPtr unknown)
{
if (this.eventHandlers.TryGetValue(eventParam, out var handler) && eventData is not null)
{
try
{
// We passed the AtkUnitBase into the EventData.Node field from our AddonEventHandler
handler?.Invoke((AddonEventType)eventType, (nint)eventData->Node, (nint)eventData->Target);
}
catch (Exception exception)
{
Log.Error(exception, "Exception in DalamudAddonEventHandler custom event invoke.");
}
}
}
} }
/// <summary> /// <summary>
@ -149,7 +203,7 @@ internal unsafe class AddonEventManagerPluginScoped : IDisposable, IServiceType,
} }
/// <inheritdoc/> /// <inheritdoc/>
public void RemoveEvent(uint eventId, IntPtr atkUnitBase, IntPtr atkResNode, AddonEventType eventType) public void RemoveEvent(uint eventId, IntPtr atkResNode, AddonEventType eventType)
{ {
if (this.eventHandlers.ContainsKey(eventId)) if (this.eventHandlers.ContainsKey(eventId))
{ {