From 2e3153c502bd0d46054361d1a8522834678b06df Mon Sep 17 00:00:00 2001 From: Blair Date: Sat, 29 Jun 2024 08:00:57 +1000 Subject: [PATCH] Make DalamudPluginInterface into IDalamudPluginInterface (#1807) * Make DalamudPluginInterface into IDalamudPluginInterface * Interface UiBuilder --- Dalamud.CorePlugin/PluginImpl.cs | 4 +- Dalamud/Interface/Internal/DalamudCommands.cs | 4 +- .../PluginInstaller/PluginInstallerWindow.cs | 8 +- .../Internal/Windows/PluginStatWindow.cs | 26 +- Dalamud/Interface/UiBuilder.cs | 239 +++++++++++-- Dalamud/Plugin/DalamudPluginInterface.cs | 45 +-- Dalamud/Plugin/IDalamudPluginInterface.cs | 323 ++++++++++++++++++ Dalamud/Plugin/Internal/PluginValidator.cs | 4 +- Dalamud/Plugin/Internal/Types/LocalPlugin.cs | 12 +- 9 files changed, 583 insertions(+), 82 deletions(-) create mode 100644 Dalamud/Plugin/IDalamudPluginInterface.cs diff --git a/Dalamud.CorePlugin/PluginImpl.cs b/Dalamud.CorePlugin/PluginImpl.cs index 15b5ac1e3..5f461b6df 100644 --- a/Dalamud.CorePlugin/PluginImpl.cs +++ b/Dalamud.CorePlugin/PluginImpl.cs @@ -55,7 +55,7 @@ namespace Dalamud.CorePlugin /// /// Dalamud plugin interface. /// Logging service. - public PluginImpl(DalamudPluginInterface pluginInterface, IPluginLog log) + public PluginImpl(IDalamudPluginInterface pluginInterface, IPluginLog log) { try { @@ -86,7 +86,7 @@ namespace Dalamud.CorePlugin /// /// Gets the plugin interface. /// - internal DalamudPluginInterface Interface { get; private set; } + internal IDalamudPluginInterface Interface { get; private set; } /// public void Dispose() diff --git a/Dalamud/Interface/Internal/DalamudCommands.cs b/Dalamud/Interface/Internal/DalamudCommands.cs index cc6f1b64c..6ad499ad7 100644 --- a/Dalamud/Interface/Internal/DalamudCommands.cs +++ b/Dalamud/Interface/Internal/DalamudCommands.cs @@ -401,11 +401,11 @@ internal class DalamudCommands : IServiceType { if (im.IsDispatchingEvents) { - plugin.DalamudInterface?.UiBuilder.NotifyShowUi(); + plugin.DalamudInterface?.LocalUiBuilder.NotifyShowUi(); } else { - plugin.DalamudInterface?.UiBuilder.NotifyHideUi(); + plugin.DalamudInterface?.LocalUiBuilder.NotifyHideUi(); } } } diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs index 2d61dc65c..870795148 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs @@ -3052,8 +3052,8 @@ internal class PluginInstallerWindow : Window, IDisposable private void DrawOpenPluginSettingsButton(LocalPlugin plugin) { - var hasMainUi = plugin.DalamudInterface?.UiBuilder.HasMainUi ?? false; - var hasConfig = plugin.DalamudInterface?.UiBuilder.HasConfigUi ?? false; + var hasMainUi = plugin.DalamudInterface?.LocalUiBuilder.HasMainUi ?? false; + var hasConfig = plugin.DalamudInterface?.LocalUiBuilder.HasConfigUi ?? false; if (hasMainUi) { ImGui.SameLine(); @@ -3061,7 +3061,7 @@ internal class PluginInstallerWindow : Window, IDisposable { try { - plugin.DalamudInterface.UiBuilder.OpenMain(); + plugin.DalamudInterface.LocalUiBuilder.OpenMain(); } catch (Exception ex) { @@ -3088,7 +3088,7 @@ internal class PluginInstallerWindow : Window, IDisposable { try { - plugin.DalamudInterface.UiBuilder.OpenConfig(); + plugin.DalamudInterface.LocalUiBuilder.OpenConfig(); } catch (Exception ex) { diff --git a/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs b/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs index 0df456dfb..314f023da 100644 --- a/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginStatWindow.cs @@ -65,16 +65,16 @@ internal class PluginStatWindow : Window { if (plugin.DalamudInterface != null) { - plugin.DalamudInterface.UiBuilder.LastDrawTime = -1; - plugin.DalamudInterface.UiBuilder.MaxDrawTime = -1; - plugin.DalamudInterface.UiBuilder.DrawTimeHistory.Clear(); + plugin.DalamudInterface.LocalUiBuilder.LastDrawTime = -1; + plugin.DalamudInterface.LocalUiBuilder.MaxDrawTime = -1; + plugin.DalamudInterface.LocalUiBuilder.DrawTimeHistory.Clear(); } } } var loadedPlugins = pluginManager.InstalledPlugins.Where(plugin => plugin.State == PluginState.Loaded); - var totalLast = loadedPlugins.Sum(plugin => plugin.DalamudInterface?.UiBuilder.LastDrawTime ?? 0); - var totalAverage = loadedPlugins.Sum(plugin => plugin.DalamudInterface?.UiBuilder.DrawTimeHistory.DefaultIfEmpty().Average() ?? 0); + var totalLast = loadedPlugins.Sum(plugin => plugin.DalamudInterface?.LocalUiBuilder.LastDrawTime ?? 0); + var totalAverage = loadedPlugins.Sum(plugin => plugin.DalamudInterface?.LocalUiBuilder.DrawTimeHistory.DefaultIfEmpty().Average() ?? 0); ImGuiComponents.TextWithLabel("Total Last", $"{totalLast / 10000f:F4}ms", "All last draw times added together"); ImGui.SameLine(); @@ -113,11 +113,11 @@ internal class PluginStatWindow : Window ? loadedPlugins.OrderBy(plugin => plugin.Name) : loadedPlugins.OrderByDescending(plugin => plugin.Name), 2 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending - ? loadedPlugins.OrderBy(plugin => plugin.DalamudInterface?.UiBuilder.MaxDrawTime ?? 0) - : loadedPlugins.OrderByDescending(plugin => plugin.DalamudInterface?.UiBuilder.MaxDrawTime ?? 0), + ? loadedPlugins.OrderBy(plugin => plugin.DalamudInterface?.LocalUiBuilder.MaxDrawTime ?? 0) + : loadedPlugins.OrderByDescending(plugin => plugin.DalamudInterface?.LocalUiBuilder.MaxDrawTime ?? 0), 3 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending - ? loadedPlugins.OrderBy(plugin => plugin.DalamudInterface?.UiBuilder.DrawTimeHistory.DefaultIfEmpty().Average() ?? 0) - : loadedPlugins.OrderByDescending(plugin => plugin.DalamudInterface?.UiBuilder.DrawTimeHistory.DefaultIfEmpty().Average() ?? 0), + ? loadedPlugins.OrderBy(plugin => plugin.DalamudInterface?.LocalUiBuilder.DrawTimeHistory.DefaultIfEmpty().Average() ?? 0) + : loadedPlugins.OrderByDescending(plugin => plugin.DalamudInterface?.LocalUiBuilder.DrawTimeHistory.DefaultIfEmpty().Average() ?? 0), _ => loadedPlugins, }; @@ -137,14 +137,14 @@ internal class PluginStatWindow : Window if (plugin.DalamudInterface != null) { ImGui.TableNextColumn(); - ImGui.Text($"{plugin.DalamudInterface.UiBuilder.LastDrawTime / 10000f:F4}ms"); + ImGui.Text($"{plugin.DalamudInterface.LocalUiBuilder.LastDrawTime / 10000f:F4}ms"); ImGui.TableNextColumn(); - ImGui.Text($"{plugin.DalamudInterface.UiBuilder.MaxDrawTime / 10000f:F4}ms"); + ImGui.Text($"{plugin.DalamudInterface.LocalUiBuilder.MaxDrawTime / 10000f:F4}ms"); ImGui.TableNextColumn(); - ImGui.Text(plugin.DalamudInterface.UiBuilder.DrawTimeHistory.Count > 0 - ? $"{plugin.DalamudInterface.UiBuilder.DrawTimeHistory.Average() / 10000f:F4}ms" + ImGui.Text(plugin.DalamudInterface.LocalUiBuilder.DrawTimeHistory.Count > 0 + ? $"{plugin.DalamudInterface.LocalUiBuilder.DrawTimeHistory.Average() / 10000f:F4}ms" : "-"); } } diff --git a/Dalamud/Interface/UiBuilder.cs b/Dalamud/Interface/UiBuilder.cs index 7311b0b91..8626ed56f 100644 --- a/Dalamud/Interface/UiBuilder.cs +++ b/Dalamud/Interface/UiBuilder.cs @@ -23,11 +23,221 @@ using SharpDX.Direct3D11; namespace Dalamud.Interface; +/// +/// This interface represents the Dalamud UI that is drawn on top of the game. +/// It can be used to draw custom windows and overlays. +/// +public interface IUiBuilder +{ + /// + /// The event that gets called when Dalamud is ready to draw your windows or overlays. + /// When it is called, you can use static ImGui calls. + /// + event Action? Draw; + + /// + /// The event that is called when the game's DirectX device is requesting you to resize your buffers. + /// + event Action? ResizeBuffers; + + /// + /// Event that is fired when the plugin should open its configuration interface. + /// + event Action? OpenConfigUi; + + /// + /// Event that is fired when the plugin should open its main interface. + /// + event Action? OpenMainUi; + + /// + /// Gets or sets an action that is called when plugin UI or interface modifications are supposed to be shown. + /// These may be fired consecutively. + /// + event Action? ShowUi; + + /// + /// Gets or sets an action that is called when plugin UI or interface modifications are supposed to be hidden. + /// These may be fired consecutively. + /// + event Action? HideUi; + + /// + /// Gets the handle to the default Dalamud font - supporting all game languages and icons. + /// + /// + /// A font handle corresponding to this font can be obtained with: + /// + /// fontAtlas.NewDelegateFontHandle( + /// e => e.OnPreBuild( + /// tk => tk.AddDalamudDefaultFont(UiBuilder.DefaultFontSizePx))); + /// + /// + IFontHandle DefaultFontHandle { get; } + + /// + /// Gets the default Dalamud icon font based on FontAwesome 5 Free solid. + /// + /// + /// A font handle corresponding to this font can be obtained with: + /// + /// fontAtlas.NewDelegateFontHandle( + /// e => e.OnPreBuild( + /// tk => tk.AddFontAwesomeIconFont(new() { SizePt = UiBuilder.DefaultFontSizePt }))); + /// // or use + /// tk => tk.AddFontAwesomeIconFont(new() { SizePx = UiBuilder.DefaultFontSizePx }))); + /// + /// + IFontHandle IconFontHandle { get; } + + /// + /// Gets the default Dalamud monospaced font based on Inconsolata Regular. + /// + /// + /// A font handle corresponding to this font can be obtained with: + /// + /// fontAtlas.NewDelegateFontHandle( + /// e => e.OnPreBuild( + /// tk => tk.AddDalamudAssetFont( + /// DalamudAsset.InconsolataRegular, + /// new() { SizePt = UiBuilder.DefaultFontSizePt }))); + /// // or use + /// new() { SizePx = UiBuilder.DefaultFontSizePx }))); + /// + /// + IFontHandle MonoFontHandle { get; } + + /// + /// Gets the default Dalamud icon font based on FontAwesome 5 free solid with a fixed width and vertically centered glyphs. + /// + IFontHandle IconFontFixedWidthHandle { get; } + + /// + /// Gets the default font specifications. + /// + IFontSpec DefaultFontSpec { get; } + + /// + /// Gets the game's active Direct3D device. + /// + Device Device { get; } + + /// + /// Gets the game's main window handle. + /// + IntPtr WindowHandlePtr { get; } + + /// + /// Gets or sets a value indicating whether this plugin should hide its UI automatically when the game's UI is hidden. + /// + bool DisableAutomaticUiHide { get; set; } + + /// + /// Gets or sets a value indicating whether this plugin should hide its UI automatically when the user toggles the UI. + /// + bool DisableUserUiHide { get; set; } + + /// + /// Gets or sets a value indicating whether this plugin should hide its UI automatically during cutscenes. + /// + bool DisableCutsceneUiHide { get; set; } + + /// + /// Gets or sets a value indicating whether this plugin should hide its UI automatically while gpose is active. + /// + bool DisableGposeUiHide { get; set; } + + /// + /// Gets or sets a value indicating whether or not the game's cursor should be overridden with the ImGui cursor. + /// + bool OverrideGameCursor { get; set; } + + /// + /// Gets the count of Draw calls made since plugin creation. + /// + ulong FrameCount { get; } + + /// + /// Gets a value indicating whether or not a cutscene is playing. + /// + bool CutsceneActive { get; } + + /// + /// Gets a value indicating whether this plugin should modify the game's interface at this time. + /// + bool ShouldModifyUi { get; } + + /// + /// Gets a value indicating whether UI functions can be used. + /// + bool UiPrepared { get; } + + /// + /// Gets the plugin-private font atlas. + /// + IFontAtlas FontAtlas { get; } + + /// + /// Gets a value indicating whether or not to use "reduced motion". This usually means that you should use less + /// intrusive animations, or disable them entirely. + /// + bool ShouldUseReducedMotion { get; } + + /// + /// Loads an ULD file that can load textures containing multiple icons in a single texture. + /// + /// The path of the requested ULD file. + /// A wrapper around said ULD file. + UldWrapper LoadUld(string uldPath); + + /// + /// Waits for UI to become available for use. + /// + /// A task that completes when the game's Present has been called at least once. + Task WaitForUi(); + + /// + /// Waits for UI to become available for use. + /// + /// Function to call. + /// Specifies whether to call the function from the framework thread. + /// A task that completes when the game's Present has been called at least once. + /// Return type. + Task RunWhenUiPrepared(Func func, bool runInFrameworkThread = false); + + /// + /// Waits for UI to become available for use. + /// + /// Function to call. + /// Specifies whether to call the function from the framework thread. + /// A task that completes when the game's Present has been called at least once. + /// Return type. + Task RunWhenUiPrepared(Func> func, bool runInFrameworkThread = false); + + /// + /// Creates an isolated . + /// + /// Specify when and how to rebuild this atlas. + /// Whether the fonts in the atlas is global scaled. + /// Name for debugging purposes. + /// A new instance of . + /// + /// Use this to create extra font atlases, if you want to create and dispose fonts without having to rebuild all + /// other fonts together.
+ /// If is not , + /// the font rebuilding functions must be called manually. + ///
+ IFontAtlas CreateFontAtlas( + FontAtlasAutoRebuildMode autoRebuildMode, + bool isGlobalScaled = true, + string? debugName = null); +} + /// /// This class represents the Dalamud UI that is drawn on top of the game. /// It can be used to draw custom windows and overlays. /// -public sealed class UiBuilder : IDisposable +public sealed class UiBuilder : IDisposable, IUiBuilder { private readonly LocalPlugin plugin; private readonly Stopwatch stopwatch; @@ -84,37 +294,22 @@ public sealed class UiBuilder : IDisposable } } - /// - /// The event that gets called when Dalamud is ready to draw your windows or overlays. - /// When it is called, you can use static ImGui calls. - /// + /// public event Action? Draw; - /// - /// The event that is called when the game's DirectX device is requesting you to resize your buffers. - /// + /// public event Action? ResizeBuffers; - /// - /// Event that is fired when the plugin should open its configuration interface. - /// + /// public event Action? OpenConfigUi; - /// - /// Event that is fired when the plugin should open its main interface. - /// + /// public event Action? OpenMainUi; - /// - /// Gets or sets an action that is called when plugin UI or interface modifications are supposed to be shown. - /// These may be fired consecutively. - /// + /// public event Action? ShowUi; - /// - /// Gets or sets an action that is called when plugin UI or interface modifications are supposed to be hidden. - /// These may be fired consecutively. - /// + /// public event Action? HideUi; /// diff --git a/Dalamud/Plugin/DalamudPluginInterface.cs b/Dalamud/Plugin/DalamudPluginInterface.cs index 5eaae84a7..c443425f5 100644 --- a/Dalamud/Plugin/DalamudPluginInterface.cs +++ b/Dalamud/Plugin/DalamudPluginInterface.cs @@ -32,10 +32,11 @@ namespace Dalamud.Plugin; /// /// This class acts as an interface to various objects needed to interact with Dalamud and the game. /// -public sealed class DalamudPluginInterface : IDisposable +public sealed class DalamudPluginInterface : IDalamudPluginInterface, IDisposable { private readonly LocalPlugin plugin; private readonly PluginConfigurations configs; + private readonly UiBuilder uiBuilder; /// /// Initializes a new instance of the class. @@ -52,7 +53,7 @@ public sealed class DalamudPluginInterface : IDisposable var dataManager = Service.Get(); var localization = Service.Get(); - this.UiBuilder = new(plugin, plugin.Name); + this.UiBuilder = this.uiBuilder = new(plugin, plugin.Name); this.configs = Service.Get().PluginConfigs; this.Reason = reason; @@ -81,28 +82,15 @@ public sealed class DalamudPluginInterface : IDisposable configuration.DalamudConfigurationSaved += this.OnDalamudConfigurationSaved; } - /// - /// Delegate for localization change with two-letter iso lang code. - /// - /// The new language code. - public delegate void LanguageChangedDelegate(string langCode); - - /// - /// Delegate for events that listen to changes to the list of active plugins. - /// - /// What action caused this event to be fired. - /// If this plugin was affected by the change. - public delegate void ActivePluginsChangedDelegate(PluginListInvalidationKind kind, bool affectedThisPlugin); - /// /// Event that gets fired when loc is changed /// - public event LanguageChangedDelegate LanguageChanged; + public event IDalamudPluginInterface.LanguageChangedDelegate? LanguageChanged; /// /// Event that is fired when the active list of plugins is changed. /// - public event ActivePluginsChangedDelegate ActivePluginsChanged; + public event IDalamudPluginInterface.ActivePluginsChangedDelegate? ActivePluginsChanged; /// /// Gets the reason this plugin was loaded. @@ -184,7 +172,7 @@ public sealed class DalamudPluginInterface : IDisposable /// /// Gets the instance which allows you to draw UI into the game via ImGui draw calls. /// - public UiBuilder UiBuilder { get; private set; } + public IUiBuilder UiBuilder { get; private set; } /// /// Gets a value indicating whether Dalamud is running in Debug mode or the /xldev menu is open. This can occur on release builds. @@ -216,6 +204,11 @@ public sealed class DalamudPluginInterface : IDisposable /// public IEnumerable InstalledPlugins => Service.Get().InstalledPlugins.Select(p => new InstalledPluginState(p.Name, p.Manifest.InternalName, p.IsLoaded, p.EffectiveVersion)); + /// + /// Gets the internal implementation. + /// + internal UiBuilder LocalUiBuilder => this.uiBuilder; + /// /// Opens the with the plugin name set as search target. /// @@ -505,26 +498,14 @@ public sealed class DalamudPluginInterface : IDisposable #endregion - /// - void IDisposable.Dispose() - { - } - - /// This function will do nothing. Dalamud will dispose this object on plugin unload. - [Obsolete("This function will do nothing. Dalamud will dispose this object on plugin unload.", true)] - public void Dispose() - { - // ignored - } - /// Unregister the plugin and dispose all references. /// Dalamud internal use only. - internal void DisposeInternal() + public void Dispose() { Service.Get().RemoveChatLinkHandler(this.plugin.InternalName); Service.Get().LocalizationChanged -= this.OnLocalizationChanged; Service.Get().DalamudConfigurationSaved -= this.OnDalamudConfigurationSaved; - this.UiBuilder.DisposeInternal(); + this.uiBuilder.DisposeInternal(); } /// diff --git a/Dalamud/Plugin/IDalamudPluginInterface.cs b/Dalamud/Plugin/IDalamudPluginInterface.cs new file mode 100644 index 000000000..227dbc9d3 --- /dev/null +++ b/Dalamud/Plugin/IDalamudPluginInterface.cs @@ -0,0 +1,323 @@ +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; + +using Dalamud.Configuration; +using Dalamud.Game.Text; +using Dalamud.Game.Text.Sanitizer; +using Dalamud.Game.Text.SeStringHandling; +using Dalamud.Game.Text.SeStringHandling.Payloads; +using Dalamud.Interface; +using Dalamud.Interface.Internal.Windows.PluginInstaller; +using Dalamud.Interface.Internal.Windows.Settings; +using Dalamud.Plugin.Internal.Types.Manifest; +using Dalamud.Plugin.Ipc; +using Dalamud.Plugin.Ipc.Exceptions; +using Dalamud.Plugin.Ipc.Internal; + +namespace Dalamud.Plugin; + +/// +/// This interface acts as an interface to various objects needed to interact with Dalamud and the game. +/// +public interface IDalamudPluginInterface +{ + /// + /// Delegate for localization change with two-letter iso lang code. + /// + /// The new language code. + public delegate void LanguageChangedDelegate(string langCode); + + /// + /// Delegate for events that listen to changes to the list of active plugins. + /// + /// What action caused this event to be fired. + /// If this plugin was affected by the change. + public delegate void ActivePluginsChangedDelegate(PluginListInvalidationKind kind, bool affectedThisPlugin); + + /// + /// Event that gets fired when loc is changed + /// + event LanguageChangedDelegate LanguageChanged; + + /// + /// Event that is fired when the active list of plugins is changed. + /// + event ActivePluginsChangedDelegate ActivePluginsChanged; + + /// + /// Gets the reason this plugin was loaded. + /// + PluginLoadReason Reason { get; } + + /// + /// Gets a value indicating whether or not auto-updates have already completed this session. + /// + bool IsAutoUpdateComplete { get; } + + /// + /// Gets the repository from which this plugin was installed. + /// + /// If a plugin was installed from the official/main repository, this will return the value of + /// . Developer plugins will return the value of + /// . + /// + string SourceRepository { get; } + + /// + /// Gets the current internal plugin name. + /// + string InternalName { get; } + + /// + /// Gets the plugin's manifest. + /// + IPluginManifest Manifest { get; } + + /// + /// Gets a value indicating whether this is a dev plugin. + /// + bool IsDev { get; } + + /// + /// Gets a value indicating whether this is a testing release of a plugin. + /// + /// + /// Dev plugins have undefined behavior for this value, but can be expected to return false. + /// + bool IsTesting { get; } + + /// + /// Gets the time that this plugin was loaded. + /// + DateTime LoadTime { get; } + + /// + /// Gets the UTC time that this plugin was loaded. + /// + DateTime LoadTimeUTC { get; } + + /// + /// Gets the timespan delta from when this plugin was loaded. + /// + TimeSpan LoadTimeDelta { get; } + + /// + /// Gets the directory Dalamud assets are stored in. + /// + DirectoryInfo DalamudAssetDirectory { get; } + + /// + /// Gets the location of your plugin assembly. + /// + FileInfo AssemblyLocation { get; } + + /// + /// Gets the directory your plugin configurations are stored in. + /// + DirectoryInfo ConfigDirectory { get; } + + /// + /// Gets the config file of your plugin. + /// + FileInfo ConfigFile { get; } + + /// + /// Gets the instance which allows you to draw UI into the game via ImGui draw calls. + /// + IUiBuilder UiBuilder { get; } + + /// + /// Gets a value indicating whether Dalamud is running in Debug mode or the /xldev menu is open. This can occur on release builds. + /// + bool IsDevMenuOpen { get; } + + /// + /// Gets a value indicating whether a debugger is attached. + /// + bool IsDebugging { get; } + + /// + /// Gets the current UI language in two-letter iso format. + /// + string UiLanguage { get; } + + /// + /// Gets serializer class with functions to remove special characters from strings. + /// + ISanitizer Sanitizer { get; } + + /// + /// Gets the chat type used by default for plugin messages. + /// + XivChatType GeneralChatType { get; } + + /// + /// Gets a list of installed plugins along with their current state. + /// + IEnumerable InstalledPlugins { get; } + + /// + /// Opens the with the plugin name set as search target. + /// + /// Returns false if the DalamudInterface was null. + bool OpenPluginInstaller(); + + /// + /// Opens the , with an optional search term. + /// + /// The page to open the installer to. Defaults to the "All Plugins" page. + /// An optional search text to input in the search box. + /// Returns false if the DalamudInterface was null. + bool OpenPluginInstallerTo(PluginInstallerOpenKind openTo = PluginInstallerOpenKind.AllPlugins, string searchText = null); + + /// + /// Opens the , with an optional search term. + /// + /// The tab to open the settings to. Defaults to the "General" tab. + /// An optional search text to input in the search box. + /// Returns false if the DalamudInterface was null. + bool OpenDalamudSettingsTo(SettingsOpenKind openTo = SettingsOpenKind.General, string searchText = null); + + /// + /// Opens the dev menu bar. + /// + /// Returns false if the DalamudInterface was null. + bool OpenDeveloperMenu(); + + /// + T GetOrCreateData(string tag, Func dataGenerator) where T : class; + + /// + void RelinquishData(string tag); + + /// + bool TryGetData(string tag, [NotNullWhen(true)] out T? data) where T : class; + + /// + T? GetData(string tag) where T : class; + + /// + /// Gets an IPC provider. + /// + /// The return type for funcs. Use object if this is unused. + /// The name of the IPC registration. + /// An IPC provider. + /// This is thrown when the requested types do not match the previously registered types are different. + ICallGateProvider GetIpcProvider(string name); + + /// + ICallGateProvider GetIpcProvider(string name); + + /// + ICallGateProvider GetIpcProvider(string name); + + /// + ICallGateProvider GetIpcProvider(string name); + + /// + ICallGateProvider GetIpcProvider(string name); + + /// + ICallGateProvider GetIpcProvider(string name); + + /// + ICallGateProvider GetIpcProvider(string name); + + /// + ICallGateProvider GetIpcProvider(string name); + + /// + ICallGateProvider GetIpcProvider(string name); + + /// + /// Gets an IPC subscriber. + /// + /// The return type for funcs. Use object if this is unused. + /// The name of the IPC registration. + /// An IPC subscriber. + ICallGateSubscriber GetIpcSubscriber(string name); + + /// + ICallGateSubscriber GetIpcSubscriber(string name); + + /// + ICallGateSubscriber GetIpcSubscriber(string name); + + /// + ICallGateSubscriber GetIpcSubscriber(string name); + + /// + ICallGateSubscriber GetIpcSubscriber(string name); + + /// + ICallGateSubscriber GetIpcSubscriber(string name); + + /// + ICallGateSubscriber GetIpcSubscriber(string name); + + /// + ICallGateSubscriber GetIpcSubscriber(string name); + + /// + ICallGateSubscriber GetIpcSubscriber(string name); + + /// + /// Save a plugin configuration(inheriting IPluginConfiguration). + /// + /// The current configuration. + void SavePluginConfig(IPluginConfiguration? currentConfig); + + /// + /// Get a previously saved plugin configuration or null if none was saved before. + /// + /// A previously saved config or null if none was saved before. + IPluginConfiguration? GetPluginConfig(); + + /// + /// Get the config directory. + /// + /// directory with path of AppData/XIVLauncher/pluginConfig/PluginInternalName. + string GetPluginConfigDirectory(); + + /// + /// Get the loc directory. + /// + /// directory with path of AppData/XIVLauncher/pluginConfig/PluginInternalName/loc. + string GetPluginLocDirectory(); + + /// + /// Register a chat link handler. + /// + /// The ID of the command. + /// The action to be executed. + /// Returns an SeString payload for the link. + DalamudLinkPayload AddChatLinkHandler(uint commandId, Action commandAction); + + /// + /// Remove a chat link handler. + /// + /// The ID of the command. + void RemoveChatLinkHandler(uint commandId); + + /// + /// Removes all chat link handlers registered by the plugin. + /// + void RemoveChatLinkHandler(); + + /// + /// Create a new object of the provided type using its default constructor, then inject objects and properties. + /// + /// Objects to inject additionally. + /// The type to create. + /// The created and initialized type. + T? Create(params object[] scopedObjects) where T : class; + + /// + /// Inject services into properties on the provided object instance. + /// + /// The instance to inject services into. + /// Objects to inject additionally. + /// Whether or not the injection succeeded. + bool Inject(object instance, params object[] scopedObjects); +} diff --git a/Dalamud/Plugin/Internal/PluginValidator.cs b/Dalamud/Plugin/Internal/PluginValidator.cs index 9ca6b4efc..b7d403b01 100644 --- a/Dalamud/Plugin/Internal/PluginValidator.cs +++ b/Dalamud/Plugin/Internal/PluginValidator.cs @@ -64,10 +64,10 @@ internal static class PluginValidator if (!plugin.IsLoaded) throw new InvalidOperationException("Plugin must be loaded to validate."); - if (!plugin.DalamudInterface!.UiBuilder.HasConfigUi) + if (!plugin.DalamudInterface!.LocalUiBuilder.HasConfigUi) problems.Add(new NoConfigUiProblem()); - if (!plugin.DalamudInterface.UiBuilder.HasMainUi) + if (!plugin.DalamudInterface.LocalUiBuilder.HasMainUi) problems.Add(new NoMainUiProblem()); var cmdManager = Service.Get(); diff --git a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs index 21713c458..25cdb2ef4 100644 --- a/Dalamud/Plugin/Internal/Types/LocalPlugin.cs +++ b/Dalamud/Plugin/Internal/Types/LocalPlugin.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Dalamud.Configuration.Internal; using Dalamud.Game; +using Dalamud.Game.Gui; using Dalamud.Game.Gui.Dtr; using Dalamud.Interface.Internal; using Dalamud.IoC.Internal; @@ -242,7 +243,8 @@ internal class LocalPlugin : IDisposable this.instance = null; } - this.DalamudInterface?.DisposeInternal(); + this.DalamudInterface?.Dispose(); + this.DalamudInterface = null; this.ServiceScope?.Dispose(); @@ -438,7 +440,7 @@ internal class LocalPlugin : IDisposable { this.State = PluginState.LoadError; this.UnloadAndDisposeState(); - + Log.Error( "Error while loading {PluginName}, failed to bind and call the plugin constructor", this.InternalName); return; @@ -691,13 +693,13 @@ internal class LocalPlugin : IDisposable throw new InvalidPluginException(this.DllFile); } } - + private void UnloadAndDisposeState() { if (this.instance != null) throw new InvalidOperationException("Plugin instance should be disposed at this point"); - - this.DalamudInterface?.DisposeInternal(); + + this.DalamudInterface?.Dispose(); this.DalamudInterface = null; this.ServiceScope?.Dispose();