A comment that reads "MUST stay in lockstep with TryGetActiveCrossfade (K8)" helps nobody outside the plan that used to have a K8 in it, and the plans are not in this repo. Same for "Spec FR-4", "plan §B.2", "Sub-Task 4.4" and the F/R/M/A/S round codes scattered through the style engine and the self-tests. Personal names go too. "tester feedback from Jin (v1.4.7)" and "Flo decision 2026-06-15" carry the reason fine without naming anyone -- the version and the reason are the parts a reader can act on, and a public repo should not need a cast list to be read. The rule applied throughout: keep the why, drop the reference. Version numbers stay, since those resolve through the changelog. 77 files. ChunkUtil also carried 281 lines of commented-out code -- an older ToChunks variant and two helpers with no callers, inherited and never removed. Deleted; git remembers them.
481 lines
23 KiB
C#
481 lines
23 KiB
C#
using Dalamud.Interface.ImGuiFileDialog;
|
|
using Dalamud.Plugin;
|
|
using Dalamud.Plugin.Services;
|
|
using HellionChat.Infrastructure.Hosting;
|
|
using HellionChat.Infrastructure.Logging;
|
|
using HellionChat.Ipc;
|
|
using HellionChat.Themes;
|
|
using HellionChat.Ui;
|
|
using HellionChat.Util;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace HellionChat;
|
|
|
|
// Builds the generic-host DI container that drives v1.5.0+. The factory is
|
|
// invoked synchronously from Plugin.ctor (after the schema gate clears) so the
|
|
// container exists before PluginLifecycle.LoadAsync runs. For the
|
|
// deliberate divergence from Lightless' deferred Func-delegate pattern.
|
|
internal static class PluginHostFactory
|
|
{
|
|
public static IHost Build(Plugin plugin, PluginHostDependencies dependencies)
|
|
{
|
|
return new HostBuilder()
|
|
.UseContentRoot(dependencies.PluginInterface.ConfigDirectory.FullName)
|
|
.ConfigureLogging(logging =>
|
|
{
|
|
logging.ClearProviders();
|
|
logging.AddDalamudLogging(dependencies.PluginLog);
|
|
logging.SetMinimumLevel(LogLevel.Trace);
|
|
})
|
|
// ValidateOnBuild eagerly instantiates every singleton at Build time
|
|
// so missing registrations / ConstructorCallSite cycles throw on
|
|
// load instead of producing a silent hang. ValidateScopes is cheap
|
|
// (we only use singletons) but guards against future Scoped misuse.
|
|
.UseDefaultServiceProvider(o =>
|
|
{
|
|
o.ValidateOnBuild = true;
|
|
o.ValidateScopes = true;
|
|
})
|
|
.ConfigureServices(services => ConfigureServices(services, plugin, dependencies))
|
|
.Build();
|
|
}
|
|
|
|
private static void ConfigureServices(
|
|
IServiceCollection services,
|
|
Plugin plugin,
|
|
PluginHostDependencies dependencies
|
|
)
|
|
{
|
|
// Dalamud services (21 [PluginService] singletons).
|
|
services.AddSingleton(dependencies);
|
|
services.AddSingleton(dependencies.PluginInterface);
|
|
services.AddSingleton(dependencies.PluginLog);
|
|
services.AddSingleton(dependencies.ChatGui);
|
|
services.AddSingleton(dependencies.ClientState);
|
|
services.AddSingleton(dependencies.CommandManager);
|
|
services.AddSingleton(dependencies.Condition);
|
|
services.AddSingleton(dependencies.DataManager);
|
|
services.AddSingleton(dependencies.Framework);
|
|
services.AddSingleton(dependencies.GameGui);
|
|
services.AddSingleton(dependencies.KeyState);
|
|
services.AddSingleton(dependencies.ObjectTable);
|
|
services.AddSingleton(dependencies.PartyList);
|
|
services.AddSingleton(dependencies.TargetManager);
|
|
services.AddSingleton(dependencies.TextureProvider);
|
|
services.AddSingleton(dependencies.GameInteropProvider);
|
|
services.AddSingleton(dependencies.GameConfig);
|
|
services.AddSingleton(dependencies.Notification);
|
|
services.AddSingleton(dependencies.AddonLifecycle);
|
|
services.AddSingleton(dependencies.PlayerState);
|
|
services.AddSingleton(dependencies.Evaluator);
|
|
services.AddSingleton(dependencies.SelfTestRegistry);
|
|
|
|
// Self-references: Plugin and its WindowSystem already exist.
|
|
services.AddSingleton(plugin);
|
|
services.AddSingleton(plugin.WindowSystem);
|
|
services.AddSingleton<PluginLifecycle>();
|
|
|
|
// HellionChat singletons. Factory lambdas because most
|
|
// classes are internal-sealed and the default activator only sees
|
|
// public ctors.
|
|
services.AddSingleton<IPlatformUtil>(_ => new DalamudPlatformUtil());
|
|
services.AddSingleton<IPluginLogProxy>(sp => new DalamudPluginLogProxy(
|
|
sp.GetRequiredService<IPluginLog>()
|
|
));
|
|
services.AddSingleton<FileDialogManager>(_ => new FileDialogManager());
|
|
services.AddSingleton(sp => new Commands(sp.GetRequiredService<ILogger<Commands>>()));
|
|
services.AddSingleton(sp => new FontManager(
|
|
sp.GetRequiredService<IDalamudPluginInterface>()
|
|
));
|
|
services.AddSingleton(sp => new IpcManager(sp.GetRequiredService<ILogger<IpcManager>>()));
|
|
services.AddSingleton(sp => new ExtraChat(sp.GetRequiredService<ILogger<ExtraChat>>()));
|
|
|
|
services.AddSingleton(sp => new ThemeRegistry(
|
|
Path.Combine(
|
|
sp.GetRequiredService<IDalamudPluginInterface>().ConfigDirectory.FullName,
|
|
"themes"
|
|
),
|
|
sp.GetRequiredService<ILogger<ThemeRegistry>>()
|
|
));
|
|
|
|
services.AddSingleton(_ => new Ui.StyleEngine.TokenResolver());
|
|
|
|
// Transient: each surface owns its motes, so two backdrops on screen do
|
|
// not drift in lockstep.
|
|
services.AddSingleton(sp => new Ui.Components.Settings.SectionRenderer(
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
|
));
|
|
|
|
services.AddTransient(sp => new Ui.StyleEngine.SurfaceBackdrop(
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.StyleEngine.PushStack(
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
|
));
|
|
|
|
services.AddSingleton(sp => new GameFunctions.GameFunctions(
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<ILogger<GameFunctions.GameFunctions>>(),
|
|
sp.GetRequiredService<ILoggerFactory>()
|
|
));
|
|
services.AddSingleton(sp => new TypingIpc(
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<Ui.Components.InputBar>(),
|
|
sp.GetRequiredService<ILogger<TypingIpc>>()
|
|
));
|
|
|
|
services.AddSingleton(sp => new Integrations.HonorificService(
|
|
sp.GetRequiredService<IDalamudPluginInterface>(),
|
|
sp.GetRequiredService<ILogger<Integrations.HonorificService>>(),
|
|
sp.GetRequiredService<IFramework>()
|
|
));
|
|
services.AddSingleton(sp => new Services.TellRouterService(
|
|
sp.GetRequiredService<MessageManager>(),
|
|
sp.GetRequiredService<ILogger<Services.TellRouterService>>()
|
|
));
|
|
|
|
services.AddSingleton(sp => new Ui.Components.HonorificHeader(
|
|
sp.GetRequiredService<Integrations.HonorificService>(),
|
|
sp.GetRequiredService<FontManager>(),
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Sidebar(
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>(),
|
|
sp.GetRequiredService<FontManager>(),
|
|
sp.GetRequiredService<ILogger<Ui.Components.Sidebar>>(),
|
|
sp.GetRequiredService<Ui.Windows.ChannelPopoutPool>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.MessageList(
|
|
sp.GetRequiredService<FontManager>(),
|
|
sp.GetRequiredService<Ui.Components.ChunkRenderer>()
|
|
));
|
|
services.AddSingleton(_ => new Ui.Components.SymbolPicker());
|
|
services.AddSingleton(sp => new Ui.Components.ThemeQuickPicker(
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<Plugin>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.InputBar(
|
|
sp.GetRequiredService<Ui.Components.SymbolPicker>(),
|
|
sp.GetRequiredService<FontManager>(),
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>(),
|
|
sp.GetRequiredService<ILogger<Ui.Components.InputBar>>(),
|
|
() => sp.GetRequiredService<Plugin>().SettingsWindow.Toggle(),
|
|
sp.GetRequiredService<Ui.CommandHelpWindow>(),
|
|
sp.GetRequiredService<Ui.Components.ThemeQuickPicker>(),
|
|
() => sp.GetRequiredService<Plugin>().MainWindow.UserHide()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Settings.TabSidebar(
|
|
sp.GetRequiredService<FontManager>(),
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Settings.ContentArea(
|
|
sp.GetRequiredService<Ui.StyleEngine.SurfaceBackdrop>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Settings.ThemePicker(
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.SectionRenderer>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Settings.ColorPicker(
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.SectionRenderer>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Settings.LivePreviewPanel(
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>(),
|
|
sp.GetRequiredService<FontManager>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Settings.ThemeImportExportRow(
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<ILogger<Ui.Components.Settings.ThemeImportExportRow>>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Settings.FontsSection(
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<FontManager>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.SectionRenderer>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Settings.ChatColourPicker(
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.SectionRenderer>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.AppearanceTab(
|
|
sp.GetRequiredService<Ui.Components.Settings.ThemePicker>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.ColorPicker>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.LivePreviewPanel>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.ThemeImportExportRow>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.FontsSection>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.ChatColourPicker>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.GeneralTab(
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<FontManager>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.ChatTab(
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.WindowTab(
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.ChannelsTab(
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.DataPrivacyTab(
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>(),
|
|
sp.GetRequiredService<ILogger<Ui.Components.Settings.Tabs.DataPrivacyTab>>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.AboutTab(
|
|
sp.GetRequiredService<FontManager>(),
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<Integrations.HonorificService>(),
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<IPlatformUtil>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.StatusBar(
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<FontManager>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Components.TopTabBar(
|
|
sp.GetRequiredService<Ui.Windows.ChannelPopoutPool>(),
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
|
));
|
|
services.AddSingleton(sp => new Ui.Windows.MainWindow(
|
|
sp.GetRequiredService<Ui.Components.HonorificHeader>(),
|
|
sp.GetRequiredService<Ui.Components.Sidebar>(),
|
|
sp.GetRequiredService<Ui.Components.TopTabBar>(),
|
|
sp.GetRequiredService<Ui.Components.MessageList>(),
|
|
sp.GetRequiredService<Ui.Components.InputBar>(),
|
|
sp.GetRequiredService<Ui.Components.StatusBar>(),
|
|
sp.GetRequiredService<Lender<PayloadHandler>>(),
|
|
sp.GetRequiredService<Ui.Windows.ChannelPopoutPool>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.SurfaceBackdrop>()
|
|
));
|
|
services.AddSingleton(sp => new Integrations.FailedTellNotifier(
|
|
sp.GetRequiredService<ILogger<Integrations.FailedTellNotifier>>()
|
|
));
|
|
services.AddSingleton(sp => new Integrations.CustomAudioPlayer(
|
|
sp.GetRequiredService<ILogger<Integrations.CustomAudioPlayer>>()
|
|
));
|
|
|
|
services.AddSingleton(sp => new MessageManager(
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<ILogger<MessageManager>>(),
|
|
sp.GetRequiredService<ILoggerFactory>()
|
|
));
|
|
|
|
// MessageStore is allocated inside MessageManager.ctor; a separate
|
|
// container singleton would double-construct the SQLite handle.
|
|
services.AddSingleton(sp =>
|
|
{
|
|
var pluginRef = sp.GetRequiredService<Plugin>();
|
|
var manager = sp.GetRequiredService<MessageManager>();
|
|
return new AutoTellTabsService(
|
|
pluginRef,
|
|
manager,
|
|
manager.Store,
|
|
sp.GetRequiredService<ILogger<AutoTellTabsService>>()
|
|
);
|
|
});
|
|
|
|
// Factory-lambdas for ChunkRenderer, PayloadHandler, and Lender<PayloadHandler>
|
|
// because all three are internal-sealed (ActivatorUtilities can't reflect into
|
|
// internal ctors) and Lender<T> has an internal ctor by design.
|
|
// PayloadHandler registered twice: once as singleton for G/H, once via Lender<T> for per-frame isolation (I/J/K).
|
|
services.AddSingleton(sp => new Ui.Components.ChunkRenderer(
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<FontManager>(),
|
|
sp.GetRequiredService<ILogger<Ui.Components.ChunkRenderer>>(),
|
|
sp.GetRequiredService<GameFunctions.GameFunctions>()
|
|
));
|
|
services.AddSingleton(sp => MakePayloadHandler(sp));
|
|
services.AddSingleton(sp => new Lender<PayloadHandler>(() => MakePayloadHandler(sp)));
|
|
|
|
// Pop-out windows: each gets its OWN MessageList + InputBar so the
|
|
// channel pill and message scroll are per-window. The PayloadHandler is
|
|
// attached post-build (ChannelPopoutInitHostedService), NEVER via ctor
|
|
// (would close a silent FactoryCallSite cycle).
|
|
services.AddSingleton<Func<int, Ui.Windows.ChannelPopoutWindow>>(sp =>
|
|
slot => new Ui.Windows.ChannelPopoutWindow(
|
|
slot,
|
|
new Ui.Components.MessageList(
|
|
sp.GetRequiredService<FontManager>(),
|
|
sp.GetRequiredService<Ui.Components.ChunkRenderer>()
|
|
),
|
|
new Ui.Components.InputBar(
|
|
sp.GetRequiredService<Ui.Components.SymbolPicker>(),
|
|
sp.GetRequiredService<FontManager>(),
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>(),
|
|
sp.GetRequiredService<ILogger<Ui.Components.InputBar>>(),
|
|
() => sp.GetRequiredService<Plugin>().SettingsWindow.Toggle(),
|
|
sp.GetRequiredService<Ui.CommandHelpWindow>()
|
|
),
|
|
sp.GetRequiredService<ILogger<Ui.Windows.ChannelPopoutWindow>>(),
|
|
sp.GetRequiredService<FontManager>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.SurfaceBackdrop>(),
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
|
)
|
|
);
|
|
services.AddSingleton(sp => new Ui.Windows.ChannelPopoutPool(
|
|
sp.GetRequiredService<Func<int, Ui.Windows.ChannelPopoutWindow>>(),
|
|
sp.GetRequiredService<ILogger<Ui.Windows.ChannelPopoutPool>>()
|
|
));
|
|
|
|
// Windows. WindowSystem.AddWindow is called from
|
|
// PluginLifecycle.LoadAsync on the framework thread.
|
|
services.AddSingleton(sp => new Ui.Windows.SettingsWindow(
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.TabSidebar>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.ContentArea>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.ThemePicker>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.ColorPicker>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.LivePreviewPanel>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.Tabs.AppearanceTab>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.Tabs.GeneralTab>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.Tabs.ChatTab>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.Tabs.WindowTab>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.Tabs.ChannelsTab>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.Tabs.DataPrivacyTab>(),
|
|
sp.GetRequiredService<Ui.Components.Settings.Tabs.AboutTab>(),
|
|
sp.GetRequiredService<ILoggerFactory>()
|
|
));
|
|
services.AddSingleton(sp => new DbViewer(
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<ILogger<DbViewer>>()
|
|
));
|
|
services.AddSingleton(sp => new InputPreview(
|
|
sp.GetRequiredService<Ui.Components.ChunkRenderer>(),
|
|
sp.GetRequiredService<Lender<PayloadHandler>>(),
|
|
sp.GetRequiredService<Ui.Windows.MainWindow>(),
|
|
sp.GetRequiredService<Ui.Components.InputBar>(),
|
|
sp.GetRequiredService<ILogger<InputPreview>>()
|
|
));
|
|
// No MainWindow ctor-param: breaks the InputBar -> CommandHelpWindow ->
|
|
// MainWindow -> InputBar singleton cycle. MainWindow is wired post-build
|
|
// via CommandHelpWindowInitHostedService.
|
|
services.AddSingleton(sp => new CommandHelpWindow(
|
|
sp.GetRequiredService<Ui.Components.ChunkRenderer>(),
|
|
sp.GetRequiredService<ILogger<CommandHelpWindow>>()
|
|
));
|
|
services.AddSingleton(sp => new SeStringDebugger(sp.GetRequiredService<Plugin>()));
|
|
#if DEBUG
|
|
services.AddSingleton(sp => new Ui.Windows.WidgetGalleryWindow(
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
|
));
|
|
#endif
|
|
// The style lab: variants side by side, in-game, against the live theme.
|
|
// Permanent, and deliberately not behind DEBUG: style decisions get
|
|
// made in the build that actually ships.
|
|
services.AddSingleton(sp => new Ui.Windows.InputBarLabWindow(
|
|
sp.GetRequiredService<Plugin>()
|
|
));
|
|
services.AddSingleton(sp => new DebuggerWindow(
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<PayloadHandler>()
|
|
));
|
|
services.AddSingleton(sp => new FirstRunWizard(
|
|
sp.GetRequiredService<Plugin>(),
|
|
sp.GetRequiredService<Ui.StyleEngine.SurfaceBackdrop>()
|
|
));
|
|
|
|
// Hosted-service adapters: thin wrappers around the existing init
|
|
// methods so the service class bodies stay unchanged. FontManager
|
|
// does not need one — its ctor runs the init inline inside a single
|
|
// SuppressAutoRebuild block on eager resolve.
|
|
services.AddHostedService(sp => new ThemeRegistryInitHostedService(
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<FontManager>()
|
|
));
|
|
services.AddHostedService(sp => new IpcManagerInitHostedService(
|
|
sp.GetRequiredService<IpcManager>()
|
|
));
|
|
services.AddHostedService(sp => new TypingIpcInitHostedService(
|
|
sp.GetRequiredService<TypingIpc>()
|
|
));
|
|
services.AddHostedService(sp => new ExtraChatInitHostedService(
|
|
sp.GetRequiredService<ExtraChat>()
|
|
));
|
|
services.AddHostedService(sp => new MessageManagerInitHostedService(
|
|
sp.GetRequiredService<IDalamudPluginInterface>(),
|
|
sp.GetRequiredService<MessageManager>()
|
|
));
|
|
services.AddHostedService(sp => new AutoTellTabsServiceInitHostedService(
|
|
sp.GetRequiredService<AutoTellTabsService>()
|
|
));
|
|
// Must come AFTER AutoTell's registration: both subscribe MessageProcessed,
|
|
// and AutoTell subscribing first lets the router's IsOpen-guard see the
|
|
// already-opened pop-out (FIFO framework-tick ordering, no double-pop).
|
|
services.AddHostedService(sp => new TellRouterServiceInitHostedService(
|
|
sp.GetRequiredService<Services.TellRouterService>()
|
|
));
|
|
services.AddHostedService(
|
|
sp => new Infrastructure.Hosting.FailedTellNotifierInitHostedService(
|
|
sp.GetRequiredService<Integrations.FailedTellNotifier>()
|
|
)
|
|
);
|
|
services.AddHostedService(sp => new PayloadHandlerInitHostedService(
|
|
sp.GetRequiredService<PayloadHandler>(),
|
|
sp.GetRequiredService<Ui.Components.MessageList>()
|
|
));
|
|
services.AddHostedService(sp => new CommandHelpWindowInitHostedService(
|
|
sp.GetRequiredService<Ui.CommandHelpWindow>(),
|
|
sp.GetRequiredService<Ui.Windows.MainWindow>()
|
|
));
|
|
services.AddHostedService(sp => new ChannelPopoutInitHostedService(
|
|
sp.GetRequiredService<Ui.Windows.ChannelPopoutPool>(),
|
|
sp.GetRequiredService<PayloadHandler>()
|
|
));
|
|
}
|
|
|
|
private static PayloadHandler MakePayloadHandler(IServiceProvider sp) =>
|
|
new(
|
|
sp.GetRequiredService<ThemeRegistry>(),
|
|
sp.GetRequiredService<IpcManager>(),
|
|
sp.GetRequiredService<GameFunctions.GameFunctions>(),
|
|
sp.GetRequiredService<Ui.Components.InputBar>(),
|
|
sp.GetRequiredService<Ui.Windows.MainWindow>(),
|
|
sp.GetRequiredService<Ui.Components.ChunkRenderer>(),
|
|
sp.GetRequiredService<ILogger<PayloadHandler>>()
|
|
);
|
|
}
|
|
|
|
internal sealed record PluginHostDependencies(
|
|
IDalamudPluginInterface PluginInterface,
|
|
IPluginLog PluginLog,
|
|
IChatGui ChatGui,
|
|
IClientState ClientState,
|
|
ICommandManager CommandManager,
|
|
ICondition Condition,
|
|
IDataManager DataManager,
|
|
IFramework Framework,
|
|
IGameGui GameGui,
|
|
IKeyState KeyState,
|
|
IObjectTable ObjectTable,
|
|
IPartyList PartyList,
|
|
ITargetManager TargetManager,
|
|
ITextureProvider TextureProvider,
|
|
IGameInteropProvider GameInteropProvider,
|
|
IGameConfig GameConfig,
|
|
INotificationManager Notification,
|
|
IAddonLifecycle AddonLifecycle,
|
|
IPlayerState PlayerState,
|
|
ISeStringEvaluator Evaluator,
|
|
ISelfTestRegistry SelfTestRegistry
|
|
);
|