diff --git a/Dalamud/Interface/ImGuiNotification/INotification.cs b/Dalamud/Interface/ImGuiNotification/INotification.cs index e80ff96c0..d8ac95c22 100644 --- a/Dalamud/Interface/ImGuiNotification/INotification.cs +++ b/Dalamud/Interface/ImGuiNotification/INotification.cs @@ -1,4 +1,4 @@ -using Dalamud.Interface.ImGuiNotification.IconSource; +using Dalamud.Interface.ImGuiNotification.Internal.IconSource; using Dalamud.Interface.Internal.Notifications; namespace Dalamud.Interface.ImGuiNotification; diff --git a/Dalamud/Interface/ImGuiNotification/INotificationIconSource.cs b/Dalamud/Interface/ImGuiNotification/INotificationIconSource.cs index 8a73e2a64..1fee67098 100644 --- a/Dalamud/Interface/ImGuiNotification/INotificationIconSource.cs +++ b/Dalamud/Interface/ImGuiNotification/INotificationIconSource.cs @@ -1,3 +1,10 @@ +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + +using Dalamud.Game.Text; +using Dalamud.Interface.ImGuiNotification.Internal.IconSource; +using Dalamud.Interface.Internal; + namespace Dalamud.Interface.ImGuiNotification; /// Icon source for . @@ -12,6 +19,67 @@ public interface INotificationIconSource : ICloneable, IDisposable INotificationMaterializedIcon Materialize(); } + /// Gets a new instance of that will source the icon from an + /// . + /// The icon character. + /// A new instance of that should be disposed after use. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static INotificationIconSource From(SeIconChar iconChar) => new SeIconCharIconSource(iconChar); + + /// Gets a new instance of that will source the icon from an + /// . + /// The icon character. + /// A new instance of that should be disposed after use. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static INotificationIconSource From(FontAwesomeIcon iconChar) => new FontAwesomeIconIconSource(iconChar); + + /// Gets a new instance of that will source the icon from an + /// . + /// The texture wrap. + /// + /// If true, this class will own the passed , and you must not call + /// on the passed wrap. + /// If false, this class will create a new reference of the passed wrap, and you should call + /// on the passed wrap. + /// In both cases, the returned object must be disposed after use. + /// A new instance of that should be disposed after use. + /// If any errors are thrown or is null, the default icon will be displayed + /// instead. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static INotificationIconSource From(IDalamudTextureWrap? wrap, bool takeOwnership = true) => + new TextureWrapIconSource(wrap, takeOwnership); + + /// Gets a new instance of that will source the icon from an + /// returning a resulting in an + /// . + /// The function that returns a task that results a texture wrap. + /// A new instance of that should be disposed after use. + /// If any errors are thrown or is null, the default icon will be + /// displayed instead.
+ /// Use if you will have a wrap available without waiting.
+ /// should not contain a reference to a resource; if it does, the resource will be + /// released when all instances of derived from the returned object are freed + /// by the garbage collector, which will result in non-deterministic resource releases.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static INotificationIconSource From(Func?>? wrapTaskFunc) => + new TextureWrapTaskIconSource(wrapTaskFunc); + + /// Gets a new instance of that will source the icon from a texture + /// file shipped as a part of the game resources. + /// The path to a texture file in the game virtual file system. + /// A new instance of that should be disposed after use. + /// If any errors are thrown, the default icon will be displayed instead. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static INotificationIconSource FromGame(string gamePath) => new GamePathIconSource(gamePath); + + /// Gets a new instance of that will source the icon from an image + /// file from the file system. + /// The path to an image file in the file system. + /// A new instance of that should be disposed after use. + /// If any errors are thrown, the default icon will be displayed instead. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static INotificationIconSource FromFile(string filePath) => new FilePathIconSource(filePath); + /// new INotificationIconSource Clone(); diff --git a/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs b/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs index 3f14ec50b..53262c08e 100644 --- a/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs +++ b/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs @@ -4,7 +4,7 @@ using System.Runtime.Loader; using Dalamud.Interface.Animation; using Dalamud.Interface.Animation.EasingFunctions; using Dalamud.Interface.Colors; -using Dalamud.Interface.ImGuiNotification.IconSource; +using Dalamud.Interface.ImGuiNotification.Internal.IconSource; using Dalamud.Interface.Internal; using Dalamud.Interface.Internal.Notifications; using Dalamud.Interface.Utility; @@ -18,7 +18,7 @@ using Serilog; namespace Dalamud.Interface.ImGuiNotification.Internal; /// Represents an active notification. -internal sealed class ActiveNotification : IActiveNotification, IDisposable +internal sealed class ActiveNotification : IActiveNotification { private readonly Notification underlyingNotification; diff --git a/Dalamud/Interface/ImGuiNotification/IconSource/FilePathIconSource.cs b/Dalamud/Interface/ImGuiNotification/Internal/IconSource/FilePathIconSource.cs similarity index 74% rename from Dalamud/Interface/ImGuiNotification/IconSource/FilePathIconSource.cs rename to Dalamud/Interface/ImGuiNotification/Internal/IconSource/FilePathIconSource.cs index b1886154a..a741931a5 100644 --- a/Dalamud/Interface/ImGuiNotification/IconSource/FilePathIconSource.cs +++ b/Dalamud/Interface/ImGuiNotification/Internal/IconSource/FilePathIconSource.cs @@ -1,33 +1,32 @@ using System.IO; using System.Numerics; -using Dalamud.Interface.ImGuiNotification.Internal; using Dalamud.Interface.Internal; using Dalamud.Plugin.Internal.Types; -namespace Dalamud.Interface.ImGuiNotification.IconSource; +namespace Dalamud.Interface.ImGuiNotification.Internal.IconSource; /// Represents the use of a texture from a file as the icon of a notification. /// If there was no texture loaded for any reason, the plugin icon will be displayed instead. -public readonly struct FilePathIconSource : INotificationIconSource.IInternal +internal class FilePathIconSource : INotificationIconSource.IInternal { - /// The path to a .tex file inside the game resources. - public readonly string FilePath; - - /// Initializes a new instance of the struct. + /// Initializes a new instance of the class. /// The path to a .tex file inside the game resources. public FilePathIconSource(string filePath) => this.FilePath = filePath; + /// Gets the path to a .tex file inside the game resources. + public string FilePath { get; } + /// public INotificationIconSource Clone() => this; /// - void IDisposable.Dispose() + public void Dispose() { } /// - INotificationMaterializedIcon INotificationIconSource.IInternal.Materialize() => + public INotificationMaterializedIcon Materialize() => new MaterializedIcon(this.FilePath); private sealed class MaterializedIcon : INotificationMaterializedIcon diff --git a/Dalamud/Interface/ImGuiNotification/IconSource/FontAwesomeIconIconSource.cs b/Dalamud/Interface/ImGuiNotification/Internal/IconSource/FontAwesomeIconIconSource.cs similarity index 73% rename from Dalamud/Interface/ImGuiNotification/IconSource/FontAwesomeIconIconSource.cs rename to Dalamud/Interface/ImGuiNotification/Internal/IconSource/FontAwesomeIconIconSource.cs index 8e28940ba..86a6f835c 100644 --- a/Dalamud/Interface/ImGuiNotification/IconSource/FontAwesomeIconIconSource.cs +++ b/Dalamud/Interface/ImGuiNotification/Internal/IconSource/FontAwesomeIconIconSource.cs @@ -1,32 +1,31 @@ using System.Numerics; -using Dalamud.Interface.ImGuiNotification.Internal; using Dalamud.Plugin.Internal.Types; using ImGuiNET; -namespace Dalamud.Interface.ImGuiNotification.IconSource; +namespace Dalamud.Interface.ImGuiNotification.Internal.IconSource; /// Represents the use of as the icon of a notification. -public readonly struct FontAwesomeIconIconSource : INotificationIconSource.IInternal +internal class FontAwesomeIconIconSource : INotificationIconSource.IInternal { - /// The icon character. - public readonly FontAwesomeIcon Char; + /// Initializes a new instance of the class. + /// The character. + public FontAwesomeIconIconSource(FontAwesomeIcon iconChar) => this.IconChar = iconChar; - /// Initializes a new instance of the struct. - /// The character. - public FontAwesomeIconIconSource(FontAwesomeIcon c) => this.Char = c; + /// Gets the icon character. + public FontAwesomeIcon IconChar { get; } /// public INotificationIconSource Clone() => this; /// - void IDisposable.Dispose() + public void Dispose() { } /// - INotificationMaterializedIcon INotificationIconSource.IInternal.Materialize() => new MaterializedIcon(this.Char); + public INotificationMaterializedIcon Materialize() => new MaterializedIcon(this.IconChar); /// Draws the icon. /// The icon string. diff --git a/Dalamud/Interface/ImGuiNotification/IconSource/GamePathIconSource.cs b/Dalamud/Interface/ImGuiNotification/Internal/IconSource/GamePathIconSource.cs similarity index 76% rename from Dalamud/Interface/ImGuiNotification/IconSource/GamePathIconSource.cs rename to Dalamud/Interface/ImGuiNotification/Internal/IconSource/GamePathIconSource.cs index 9b669e62a..974e60ee7 100644 --- a/Dalamud/Interface/ImGuiNotification/IconSource/GamePathIconSource.cs +++ b/Dalamud/Interface/ImGuiNotification/Internal/IconSource/GamePathIconSource.cs @@ -1,34 +1,33 @@ using System.Numerics; -using Dalamud.Interface.ImGuiNotification.Internal; using Dalamud.Interface.Internal; using Dalamud.Plugin.Internal.Types; using Dalamud.Plugin.Services; -namespace Dalamud.Interface.ImGuiNotification.IconSource; +namespace Dalamud.Interface.ImGuiNotification.Internal.IconSource; /// Represents the use of a game-shipped texture as the icon of a notification. /// If there was no texture loaded for any reason, the plugin icon will be displayed instead. -public readonly struct GamePathIconSource : INotificationIconSource.IInternal +internal class GamePathIconSource : INotificationIconSource.IInternal { - /// The path to a .tex file inside the game resources. - public readonly string GamePath; - - /// Initializes a new instance of the struct. + /// Initializes a new instance of the class. /// The path to a .tex file inside the game resources. /// Use to get the game path from icon IDs. public GamePathIconSource(string gamePath) => this.GamePath = gamePath; + /// Gets the path to a .tex file inside the game resources. + public string GamePath { get; } + /// public INotificationIconSource Clone() => this; /// - void IDisposable.Dispose() + public void Dispose() { } /// - INotificationMaterializedIcon INotificationIconSource.IInternal.Materialize() => + public INotificationMaterializedIcon Materialize() => new MaterializedIcon(this.GamePath); private sealed class MaterializedIcon : INotificationMaterializedIcon diff --git a/Dalamud/Interface/ImGuiNotification/IconSource/SeIconCharIconSource.cs b/Dalamud/Interface/ImGuiNotification/Internal/IconSource/SeIconCharIconSource.cs similarity index 70% rename from Dalamud/Interface/ImGuiNotification/IconSource/SeIconCharIconSource.cs rename to Dalamud/Interface/ImGuiNotification/Internal/IconSource/SeIconCharIconSource.cs index d34b776bc..83fd0bef6 100644 --- a/Dalamud/Interface/ImGuiNotification/IconSource/SeIconCharIconSource.cs +++ b/Dalamud/Interface/ImGuiNotification/Internal/IconSource/SeIconCharIconSource.cs @@ -1,33 +1,32 @@ using System.Numerics; using Dalamud.Game.Text; -using Dalamud.Interface.ImGuiNotification.Internal; using Dalamud.Plugin.Internal.Types; using ImGuiNET; -namespace Dalamud.Interface.ImGuiNotification.IconSource; +namespace Dalamud.Interface.ImGuiNotification.Internal.IconSource; /// Represents the use of as the icon of a notification. -public readonly struct SeIconCharIconSource : INotificationIconSource.IInternal +internal class SeIconCharIconSource : INotificationIconSource.IInternal { - /// The icon character. - public readonly SeIconChar Char; - - /// Initializes a new instance of the struct. + /// Initializes a new instance of the class. /// The character. - public SeIconCharIconSource(SeIconChar c) => this.Char = c; + public SeIconCharIconSource(SeIconChar c) => this.IconChar = c; + + /// Gets the icon character. + public SeIconChar IconChar { get; } /// public INotificationIconSource Clone() => this; /// - void IDisposable.Dispose() + public void Dispose() { } /// - INotificationMaterializedIcon INotificationIconSource.IInternal.Materialize() => new MaterializedIcon(this.Char); + public INotificationMaterializedIcon Materialize() => new MaterializedIcon(this.IconChar); private sealed class MaterializedIcon : INotificationMaterializedIcon { diff --git a/Dalamud/Interface/ImGuiNotification/IconSource/TextureWrapIconSource.cs b/Dalamud/Interface/ImGuiNotification/Internal/IconSource/TextureWrapIconSource.cs similarity index 89% rename from Dalamud/Interface/ImGuiNotification/IconSource/TextureWrapIconSource.cs rename to Dalamud/Interface/ImGuiNotification/Internal/IconSource/TextureWrapIconSource.cs index b3d4392cf..a10b09bce 100644 --- a/Dalamud/Interface/ImGuiNotification/IconSource/TextureWrapIconSource.cs +++ b/Dalamud/Interface/ImGuiNotification/Internal/IconSource/TextureWrapIconSource.cs @@ -1,15 +1,14 @@ using System.Numerics; using System.Threading; -using Dalamud.Interface.ImGuiNotification.Internal; using Dalamud.Interface.Internal; using Dalamud.Plugin.Internal.Types; -namespace Dalamud.Interface.ImGuiNotification.IconSource; +namespace Dalamud.Interface.ImGuiNotification.Internal.IconSource; /// Represents the use of future as the icon of a notification. /// If there was no texture loaded for any reason, the plugin icon will be displayed instead. -public sealed class TextureWrapIconSource : INotificationIconSource.IInternal +internal class TextureWrapIconSource : INotificationIconSource.IInternal { private IDalamudTextureWrap? wrap; @@ -38,7 +37,7 @@ public sealed class TextureWrapIconSource : INotificationIconSource.IInternal } /// - INotificationMaterializedIcon INotificationIconSource.IInternal.Materialize() => + public INotificationMaterializedIcon Materialize() => new MaterializedIcon(this.wrap?.CreateWrapSharingLowLevelResource()); private sealed class MaterializedIcon : INotificationMaterializedIcon diff --git a/Dalamud/Interface/ImGuiNotification/IconSource/TextureWrapTaskIconSource.cs b/Dalamud/Interface/ImGuiNotification/Internal/IconSource/TextureWrapTaskIconSource.cs similarity index 80% rename from Dalamud/Interface/ImGuiNotification/IconSource/TextureWrapTaskIconSource.cs rename to Dalamud/Interface/ImGuiNotification/Internal/IconSource/TextureWrapTaskIconSource.cs index 2a5473760..4039b6955 100644 --- a/Dalamud/Interface/ImGuiNotification/IconSource/TextureWrapTaskIconSource.cs +++ b/Dalamud/Interface/ImGuiNotification/Internal/IconSource/TextureWrapTaskIconSource.cs @@ -1,42 +1,41 @@ using System.Numerics; using System.Threading.Tasks; -using Dalamud.Interface.ImGuiNotification.Internal; using Dalamud.Interface.Internal; using Dalamud.Plugin.Internal.Types; using Dalamud.Utility; using Serilog; -namespace Dalamud.Interface.ImGuiNotification.IconSource; +namespace Dalamud.Interface.ImGuiNotification.Internal.IconSource; /// Represents the use of future as the icon of a notification. /// If there was no texture loaded for any reason, the plugin icon will be displayed instead. -public readonly struct TextureWrapTaskIconSource : INotificationIconSource.IInternal +internal class TextureWrapTaskIconSource : INotificationIconSource.IInternal { - /// The function that returns a task resulting in a new instance of . - /// - /// Dalamud will take ownership of the result. Do not call . - public readonly Func?>? TextureWrapTaskFunc; - /// Gets the default materialized icon, for the purpose of displaying the plugin icon. internal static readonly INotificationMaterializedIcon DefaultMaterializedIcon = new MaterializedIcon(null); - /// Initializes a new instance of the struct. + /// Initializes a new instance of the class. /// The function. public TextureWrapTaskIconSource(Func?>? taskFunc) => this.TextureWrapTaskFunc = taskFunc; + /// Gets the function that returns a task resulting in a new instance of . + /// + /// Dalamud will take ownership of the result. Do not call . + public Func?>? TextureWrapTaskFunc { get; } + /// public INotificationIconSource Clone() => this; /// - void IDisposable.Dispose() + public void Dispose() { } /// - INotificationMaterializedIcon INotificationIconSource.IInternal.Materialize() => + public INotificationMaterializedIcon Materialize() => new MaterializedIcon(this.TextureWrapTaskFunc); private sealed class MaterializedIcon : INotificationMaterializedIcon diff --git a/Dalamud/Interface/ImGuiNotification/Internal/NotificationUtilities.cs b/Dalamud/Interface/ImGuiNotification/NotificationUtilities.cs similarity index 65% rename from Dalamud/Interface/ImGuiNotification/Internal/NotificationUtilities.cs rename to Dalamud/Interface/ImGuiNotification/NotificationUtilities.cs index 3e24f628c..9b3602b68 100644 --- a/Dalamud/Interface/ImGuiNotification/Internal/NotificationUtilities.cs +++ b/Dalamud/Interface/ImGuiNotification/NotificationUtilities.cs @@ -1,5 +1,8 @@ +using System.IO; using System.Numerics; +using System.Runtime.CompilerServices; +using Dalamud.Game.Text; using Dalamud.Interface.Internal; using Dalamud.Interface.Internal.Windows; using Dalamud.Plugin.Internal.Types; @@ -7,17 +10,37 @@ using Dalamud.Storage.Assets; using ImGuiNET; -namespace Dalamud.Interface.ImGuiNotification.Internal; +namespace Dalamud.Interface.ImGuiNotification; /// Utilities for implementing stuff under . -internal static class NotificationUtilities +public static class NotificationUtilities { + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static INotificationIconSource ToIconSource(this SeIconChar iconChar) => + INotificationIconSource.From(iconChar); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static INotificationIconSource ToIconSource(this FontAwesomeIcon iconChar) => + INotificationIconSource.From(iconChar); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static INotificationIconSource ToIconSource(this IDalamudTextureWrap? wrap, bool takeOwnership = true) => + INotificationIconSource.From(wrap, takeOwnership); + + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static INotificationIconSource ToIconSource(this FileInfo fileInfo) => + INotificationIconSource.FromFile(fileInfo.FullName); + /// Draws the given texture, or the icon of the plugin if texture is null. /// The texture. /// The coordinates of the top left of the icon area. /// The coordinates of the bottom right of the icon area. /// The initiator plugin. - public static void DrawTexture( + internal static void DrawTexture( IDalamudTextureWrap? texture, Vector2 minCoord, Vector2 maxCoord, diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs index 1093ca4b8..3b518af84 100644 --- a/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs +++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs @@ -3,8 +3,8 @@ using System.Threading.Tasks; using Dalamud.Game.Text; using Dalamud.Interface.ImGuiNotification; -using Dalamud.Interface.ImGuiNotification.IconSource; using Dalamud.Interface.ImGuiNotification.Internal; +using Dalamud.Interface.ImGuiNotification.Internal.IconSource; using Dalamud.Interface.Internal.Notifications; using Dalamud.Interface.Windowing; using Dalamud.Storage.Assets; @@ -161,32 +161,32 @@ internal class ImGuiWidget : IDataWindowWidget }, IconSource = this.notificationTemplate.IconSourceInt switch { - 1 => new SeIconCharIconSource( + 1 => INotificationIconSource.From( (SeIconChar)(this.notificationTemplate.IconSourceText.Length == 0 ? 0 : this.notificationTemplate.IconSourceText[0])), - 2 => new FontAwesomeIconIconSource( + 2 => INotificationIconSource.From( (FontAwesomeIcon)(this.notificationTemplate.IconSourceText.Length == 0 ? 0 : this.notificationTemplate.IconSourceText[0])), - 3 => new TextureWrapIconSource( + 3 => INotificationIconSource.From( Service.Get().GetDalamudTextureWrap( Enum.Parse( NotificationTemplate.AssetSources[ this.notificationTemplate.IconSourceAssetInt])), false), - 4 => new TextureWrapTaskIconSource( + 4 => INotificationIconSource.From( () => Service.Get().GetDalamudTextureWrapAsync( Enum.Parse( NotificationTemplate.AssetSources[ this.notificationTemplate.IconSourceAssetInt]))), - 5 => new GamePathIconSource(this.notificationTemplate.IconSourceText), - 6 => new FilePathIconSource(this.notificationTemplate.IconSourceText), - 7 => new TextureWrapIconSource( + 5 => INotificationIconSource.FromGame(this.notificationTemplate.IconSourceText), + 6 => INotificationIconSource.FromFile(this.notificationTemplate.IconSourceText), + 7 => INotificationIconSource.From( Service.Get().GetTextureFromGame(this.notificationTemplate.IconSourceText), false), - 8 => new TextureWrapIconSource( + 8 => INotificationIconSource.From( Service.Get().GetTextureFromFile( new(this.notificationTemplate.IconSourceText)), false),