feat(infra): wire PayloadHandlerInitHostedService (AddonLifecycle + setter)
G connects PayloadHandler to the runtime — this is the activation point after E1-E6 built the type and F registered it in DI: - StartAsync calls MessageList.AttachPayloadHandler(_payloadHandler) to complete the §6.2 cycle-resolution (ctor-cycle was broken by setter, this is where the setter actually fires) - StartAsync registers AddonLifecycle listener for MoveTooltip on PostUpdate of "ItemDetail" and "ActionDetail" addons - StopAsync unregisters the listener - Both Register/Unregister wrapped in Plugin.Framework.RunOnFrameworkThread as defensive insurance — IAddonLifecycle thread-affinity is not explicitly documented in Dalamud API; wrap keeps the v1.5.6 runtime contract intact (per spec §5-G note) Mirrors existing IpcManagerInitHostedService / TypingIpcInitHostedService pattern in Infrastructure/Hosting/. PluginHostFactory adds the AddHostedService<PayloadHandlerInitHostedService>() registration. After G, the chunked-message-render pipeline is end-to-end functional: MessageList renders via ChunkRenderer, _handler is wired so popups fire on click/hover, MoveTooltip repositions native item-tooltips away from the chat window.
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
using Dalamud.Game.Addon.Lifecycle;
|
||||
using Dalamud.Plugin;
|
||||
using HellionChat.Integrations;
|
||||
using HellionChat.Ipc;
|
||||
using HellionChat.Themes;
|
||||
using HellionChat.Ui.Components;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace HellionChat.Infrastructure.Hosting;
|
||||
@@ -101,3 +103,41 @@ internal sealed class FailedTellNotifierInitHostedService(FailedTellNotifier not
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
}
|
||||
|
||||
internal sealed class PayloadHandlerInitHostedService(
|
||||
PayloadHandler payloadHandler,
|
||||
MessageList messageList
|
||||
) : IHostedService
|
||||
{
|
||||
public async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
// §6.2 cycle-resolution: both singletons exist by the time HostedServices
|
||||
// run, so this is the first safe point to wire the setter.
|
||||
messageList.AttachPayloadHandler(payloadHandler);
|
||||
|
||||
// IAddonLifecycle thread-affinity is not explicitly documented; wrap is
|
||||
// defensive insurance — mirrors the window-registration RunOnFrameworkThread
|
||||
// pattern established in PluginLifecycle.cs.
|
||||
await Plugin.Framework.RunOnFrameworkThread(() =>
|
||||
{
|
||||
Plugin.AddonLifecycle.RegisterListener(
|
||||
AddonEvent.PostUpdate,
|
||||
"ItemDetail",
|
||||
payloadHandler.MoveTooltip
|
||||
);
|
||||
Plugin.AddonLifecycle.RegisterListener(
|
||||
AddonEvent.PostUpdate,
|
||||
"ActionDetail",
|
||||
payloadHandler.MoveTooltip
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public async Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await Plugin.Framework.RunOnFrameworkThread(() =>
|
||||
{
|
||||
Plugin.AddonLifecycle.UnregisterListener(payloadHandler.MoveTooltip);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user