diff --git a/Dalamud/Interface/ImGuiNotification/IActiveNotification.cs b/Dalamud/Interface/ImGuiNotification/IActiveNotification.cs
index 332516315..d39fe6bee 100644
--- a/Dalamud/Interface/ImGuiNotification/IActiveNotification.cs
+++ b/Dalamud/Interface/ImGuiNotification/IActiveNotification.cs
@@ -1,9 +1,6 @@
using System.Threading;
-using System.Threading.Tasks;
using Dalamud.Interface.ImGuiNotification.EventArgs;
-using Dalamud.Interface.Internal;
-using Dalamud.Interface.Textures.TextureWraps;
namespace Dalamud.Interface.ImGuiNotification;
@@ -52,64 +49,6 @@ public interface IActiveNotification : INotification
/// This does not override .
void ExtendBy(TimeSpan extension);
- /// Sets the icon from , overriding the icon.
- /// The new texture wrap to use, or null to clear and revert back to the icon specified
- /// from .
- ///
- /// The texture passed will be disposed when the notification is dismissed or a new different texture is set
- /// via another call to this function or overwriting the property. You do not have to dispose it yourself.
- /// If is not null, then calling this function will simply dispose the
- /// passed without actually updating the icon.
- ///
- void SetIconTexture(IDalamudTextureWrap? textureWrap);
-
- /// Sets the icon from , overriding the icon, once the given task
- /// completes.
- /// The task that will result in a new texture wrap to use, or null to clear and
- /// revert back to the icon specified from .
- ///
- /// The texture resulted from the passed will be disposed when the notification
- /// is dismissed or a new different texture is set via another call to this function over overwriting the property.
- /// You do not have to dispose the resulted instance of yourself.
- /// If the task fails for any reason, the exception will be silently ignored and the icon specified from
- /// will be used instead.
- /// If is not null, then calling this function will simply dispose the
- /// result of the passed without actually updating the icon.
- ///
- void SetIconTexture(Task? textureWrapTask);
-
- /// Sets the icon from , overriding the icon.
- /// The new texture wrap to use, or null to clear and revert back to the icon specified
- /// from .
- /// Whether to keep the passed not disposed.
- ///
- /// If is false, the texture passed will be disposed when the
- /// notification is dismissed or a new different texture is set via another call to this function. You do not have
- /// to dispose it yourself.
- /// If is not null and is false, then
- /// calling this function will simply dispose the passed without actually updating
- /// the icon.
- ///
- void SetIconTexture(IDalamudTextureWrap? textureWrap, bool leaveOpen);
-
- /// Sets the icon from , overriding the icon, once the given task
- /// completes.
- /// The task that will result in a new texture wrap to use, or null to clear and
- /// revert back to the icon specified from .
- /// Whether to keep the result from the passed not
- /// disposed.
- ///
- /// If is false, the texture resulted from the passed
- /// will be disposed when the notification is dismissed or a new different texture is
- /// set via another call to this function. You do not have to dispose the resulted instance of
- /// yourself.
- /// If the task fails for any reason, the exception will be silently ignored and the icon specified from
- /// will be used instead.
- /// If is not null, then calling this function will simply dispose the
- /// result of the passed without actually updating the icon.
- ///
- void SetIconTexture(Task? textureWrapTask, bool leaveOpen);
-
/// Generates a new value to use for .
/// The new value.
internal static long CreateNewId() => Interlocked.Increment(ref idCounter);
diff --git a/Dalamud/Interface/ImGuiNotification/INotification.cs b/Dalamud/Interface/ImGuiNotification/INotification.cs
index eab0fd131..0b15d2398 100644
--- a/Dalamud/Interface/ImGuiNotification/INotification.cs
+++ b/Dalamud/Interface/ImGuiNotification/INotification.cs
@@ -1,8 +1,4 @@
-using System.Threading.Tasks;
-
-using Dalamud.Interface.Internal;
-using Dalamud.Interface.Textures.TextureWraps;
-using Dalamud.Plugin.Services;
+using Dalamud.Interface.Textures;
namespace Dalamud.Interface.ImGuiNotification;
@@ -22,35 +18,12 @@ public interface INotification
/// Gets or sets the type of the notification.
NotificationType Type { get; set; }
- /// Gets or sets the icon source, in case is not set or the task has faulted.
+ /// Gets or sets the icon source, in case is not set.
///
INotificationIcon? Icon { get; set; }
- /// Gets or sets a texture wrap that will be used in place of if set.
- ///
- /// A texture wrap set via this property will NOT be disposed when the notification is dismissed.
- /// Use or
- /// to use a texture, after calling
- /// . Call either of those functions with null to revert
- /// the effective icon back to this property.
- /// This property and are bound together. If the task is not null but
- /// is false (because the task is still in progress or faulted,)
- /// the property will return null. Setting this property will set to a new
- /// completed with the new value as its result.
- ///
- public IDalamudTextureWrap? IconTexture { get; set; }
-
- /// Gets or sets a task that results in a texture wrap that will be used in place of if
- /// available.
- ///
- /// A texture wrap set via this property will NOT be disposed when the notification is dismissed.
- /// Use or
- /// to use a texture, after calling
- /// . Call either of those functions with null to revert
- /// the effective icon back to this property.
- /// This property and are bound together.
- ///
- Task? IconTextureTask { get; set; }
+ /// Gets or sets a texture that will be used in place of if set.
+ public ISharedImmediateTexture? IconTexture { get; set; }
/// Gets or sets the hard expiry.
///
diff --git a/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.ImGui.cs b/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.ImGui.cs
index 16d58bea5..e8d6c5cc0 100644
--- a/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.ImGui.cs
+++ b/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.ImGui.cs
@@ -404,7 +404,7 @@ internal sealed partial class ActiveNotification
var maxCoord = minCoord + size;
var iconColor = this.Type.ToColor();
- if (NotificationUtilities.DrawIconFrom(minCoord, maxCoord, this.IconTextureTask))
+ if (NotificationUtilities.DrawIconFrom(minCoord, maxCoord, this.IconTexture))
return;
if (this.Icon?.DrawIcon(minCoord, maxCoord, iconColor) is true)
@@ -499,7 +499,7 @@ internal sealed partial class ActiveNotification
if (fillStartCw == 0 && fillEndCw == 0)
return;
-
+
var radius = Math.Min(size.X, size.Y) / 3f;
var ifrom = fillStartCw * MathF.PI * 2;
var ito = fillEndCw * MathF.PI * 2;
diff --git a/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs b/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs
index 607c7c49d..6587b6c32 100644
--- a/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs
+++ b/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs
@@ -1,11 +1,9 @@
using System.Runtime.Loader;
-using System.Threading.Tasks;
using Dalamud.Configuration.Internal;
using Dalamud.Interface.Animation;
using Dalamud.Interface.Animation.EasingFunctions;
-using Dalamud.Interface.Internal;
-using Dalamud.Interface.Textures.TextureWraps;
+using Dalamud.Interface.Textures;
using Dalamud.Plugin.Internal.Types;
using Dalamud.Utility;
@@ -23,9 +21,6 @@ internal sealed partial class ActiveNotification : IActiveNotification
private readonly Easing progressEasing;
private readonly Easing expandoEasing;
- /// Whether to call on .
- private bool hasIconTextureOwnership;
-
/// Gets the time of starting to count the timer for the expiration.
private DateTime lastInterestTime;
@@ -119,31 +114,10 @@ internal sealed partial class ActiveNotification : IActiveNotification
}
///
- public IDalamudTextureWrap? IconTexture
+ public ISharedImmediateTexture? IconTexture
{
get => this.underlyingNotification.IconTexture;
- set => this.IconTextureTask = value is null ? null : Task.FromResult(value);
- }
-
- ///
- public Task? IconTextureTask
- {
- get => this.underlyingNotification.IconTextureTask;
- set
- {
- // Do nothing if the value did not change.
- if (this.underlyingNotification.IconTextureTask == value)
- return;
-
- if (this.hasIconTextureOwnership)
- {
- _ = this.underlyingNotification.IconTextureTask?.ToContentDisposedTask(true);
- this.underlyingNotification.IconTextureTask = null;
- this.hasIconTextureOwnership = false;
- }
-
- this.underlyingNotification.IconTextureTask = value;
- }
+ set => this.underlyingNotification.IconTexture = value;
}
///
@@ -265,39 +239,6 @@ internal sealed partial class ActiveNotification : IActiveNotification
this.extendedExpiry = newExpiry;
}
- ///
- public void SetIconTexture(IDalamudTextureWrap? textureWrap) =>
- this.SetIconTexture(textureWrap, false);
-
- ///
- public void SetIconTexture(IDalamudTextureWrap? textureWrap, bool leaveOpen) =>
- this.SetIconTexture(textureWrap is null ? null : Task.FromResult(textureWrap), leaveOpen);
-
- ///
- public void SetIconTexture(Task? textureWrapTask) =>
- this.SetIconTexture(textureWrapTask, false);
-
- ///
- public void SetIconTexture(Task? textureWrapTask, bool leaveOpen)
- {
- // If we're requested to replace the texture with the same texture, do nothing.
- if (this.underlyingNotification.IconTextureTask == textureWrapTask)
- return;
-
- if (this.DismissReason is not null)
- {
- if (!leaveOpen)
- textureWrapTask?.ToContentDisposedTask(true);
- return;
- }
-
- if (this.hasIconTextureOwnership)
- _ = this.underlyingNotification.IconTextureTask?.ToContentDisposedTask(true);
-
- this.hasIconTextureOwnership = !leaveOpen;
- this.underlyingNotification.IconTextureTask = textureWrapTask;
- }
-
/// Removes non-Dalamud invocation targets from events.
///
/// This is done to prevent references of plugins being unloaded from outliving the plugin itself.
@@ -317,10 +258,8 @@ internal sealed partial class ActiveNotification : IActiveNotification
if (this.Icon is { } previousIcon && !IsOwnedByDalamud(previousIcon.GetType()))
this.Icon = null;
- // Clear the texture if we don't have the ownership.
- // The texture probably was owned by the plugin being unloaded in such case.
- if (!this.hasIconTextureOwnership)
- this.IconTextureTask = null;
+ if (this.IconTexture is { } previousTexture && !IsOwnedByDalamud(previousTexture.GetType()))
+ this.IconTexture = null;
this.isInitiatorUnloaded = true;
this.UserDismissable = true;
@@ -400,13 +339,6 @@ internal sealed partial class ActiveNotification : IActiveNotification
/// Clears the resources associated with this instance of .
internal void DisposeInternal()
{
- if (this.hasIconTextureOwnership)
- {
- _ = this.underlyingNotification.IconTextureTask?.ToContentDisposedTask(true);
- this.underlyingNotification.IconTextureTask = null;
- this.hasIconTextureOwnership = false;
- }
-
this.Dismiss = null;
this.Click = null;
this.DrawActions = null;
diff --git a/Dalamud/Interface/ImGuiNotification/Notification.cs b/Dalamud/Interface/ImGuiNotification/Notification.cs
index 927dd5ba9..4dcb10c17 100644
--- a/Dalamud/Interface/ImGuiNotification/Notification.cs
+++ b/Dalamud/Interface/ImGuiNotification/Notification.cs
@@ -1,11 +1,11 @@
using System.Threading.Tasks;
using Dalamud.Interface.ImGuiNotification.Internal;
-using Dalamud.Interface.Internal;
+using Dalamud.Interface.Textures;
using Dalamud.Interface.Textures.TextureWraps;
+using Serilog;
namespace Dalamud.Interface.ImGuiNotification;
-
/// Represents a blueprint for a notification.
public sealed record Notification : INotification
{
@@ -30,14 +30,7 @@ public sealed record Notification : INotification
public INotificationIcon? Icon { get; set; }
///
- public IDalamudTextureWrap? IconTexture
- {
- get => this.IconTextureTask?.IsCompletedSuccessfully is true ? this.IconTextureTask.Result : null;
- set => this.IconTextureTask = value is null ? null : Task.FromResult(value);
- }
-
- ///
- public Task? IconTextureTask { get; set; }
+ public ISharedImmediateTexture? IconTexture { get; set; }
///
public DateTime HardExpiry { get; set; } = DateTime.MaxValue;
diff --git a/Dalamud/Interface/ImGuiNotification/NotificationUtilities.cs b/Dalamud/Interface/ImGuiNotification/NotificationUtilities.cs
index 2172663e8..b31321d8b 100644
--- a/Dalamud/Interface/ImGuiNotification/NotificationUtilities.cs
+++ b/Dalamud/Interface/ImGuiNotification/NotificationUtilities.cs
@@ -7,6 +7,7 @@ using Dalamud.Game.Text;
using Dalamud.Interface.Internal;
using Dalamud.Interface.Internal.Windows;
using Dalamud.Interface.ManagedFontAtlas;
+using Dalamud.Interface.Textures;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Interface.Utility;
using Dalamud.Plugin.Internal.Types;
@@ -78,6 +79,19 @@ public static class NotificationUtilities
return true;
}
+ /// Draws an icon from an instance of .
+ /// The coordinates of the top left of the icon area.
+ /// The coordinates of the bottom right of the icon area.
+ /// The texture.
+ /// true if anything has been drawn.
+ internal static bool DrawIconFrom(Vector2 minCoord, Vector2 maxCoord, ISharedImmediateTexture? texture)
+ {
+ if (texture is null)
+ return false;
+
+ return DrawIconFrom(minCoord, maxCoord, texture.GetWrapOrEmpty());
+ }
+
/// Draws an icon from an instance of .
/// The coordinates of the top left of the icon area.
/// The coordinates of the bottom right of the icon area.
@@ -105,16 +119,6 @@ public static class NotificationUtilities
}
}
- /// Draws an icon from an instance of that results in an
- /// .
- /// The coordinates of the top left of the icon area.
- /// The coordinates of the bottom right of the icon area.
- /// The task that results in a texture.
- /// true if anything has been drawn.
- /// Exceptions from the task will be treated as if no texture is provided.
- internal static bool DrawIconFrom(Vector2 minCoord, Vector2 maxCoord, Task? textureTask) =>
- textureTask?.IsCompletedSuccessfully is true && DrawIconFrom(minCoord, maxCoord, textureTask.Result);
-
/// Draws an icon from an instance of .
/// The coordinates of the top left of the icon area.
/// The coordinates of the bottom right of the icon area.
diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs
index f3f2564af..7d798c541 100644
--- a/Dalamud/Interface/Internal/DalamudInterface.cs
+++ b/Dalamud/Interface/Internal/DalamudInterface.cs
@@ -26,6 +26,7 @@ using Dalamud.Interface.Internal.Windows.Settings;
using Dalamud.Interface.Internal.Windows.StyleEditor;
using Dalamud.Interface.ManagedFontAtlas.Internals;
using Dalamud.Interface.Style;
+using Dalamud.Interface.Textures;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Interface.Windowing;
@@ -169,16 +170,16 @@ internal class DalamudInterface : IInternalDisposableService
{
titleScreenMenu.AddEntryCore(
Loc.Localize("TSMDalamudPlugins", "Plugin Installer"),
- dalamudAssetManager.GetDalamudTextureWrap(DalamudAsset.LogoSmall),
+ new ForwardingSharedImmediateTexture(dalamudAssetManager.GetDalamudTextureWrap(DalamudAsset.LogoSmall)),
this.OpenPluginInstaller);
titleScreenMenu.AddEntryCore(
Loc.Localize("TSMDalamudSettings", "Dalamud Settings"),
- dalamudAssetManager.GetDalamudTextureWrap(DalamudAsset.LogoSmall),
+ new ForwardingSharedImmediateTexture(dalamudAssetManager.GetDalamudTextureWrap(DalamudAsset.LogoSmall)),
this.OpenSettings);
titleScreenMenu.AddEntryCore(
"Toggle Dev Menu",
- dalamudAssetManager.GetDalamudTextureWrap(DalamudAsset.LogoSmall),
+ new ForwardingSharedImmediateTexture(dalamudAssetManager.GetDalamudTextureWrap(DalamudAsset.LogoSmall)),
() => Service.GetNullable()?.ToggleDevMenu(),
VirtualKey.SHIFT);
@@ -186,7 +187,7 @@ internal class DalamudInterface : IInternalDisposableService
{
titleScreenMenu.AddEntryCore(
Loc.Localize("TSMDalamudDevMenu", "Developer Menu"),
- dalamudAssetManager.GetDalamudTextureWrap(DalamudAsset.LogoSmall),
+ new ForwardingSharedImmediateTexture(dalamudAssetManager.GetDalamudTextureWrap(DalamudAsset.LogoSmall)),
() => this.isImGuiDrawDevMenu = true);
}
});
diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs
index 1476ce2e6..08d29398b 100644
--- a/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs
+++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs
@@ -5,11 +5,11 @@ using System.Threading.Tasks;
using Dalamud.Game.Text;
using Dalamud.Interface.ImGuiNotification;
using Dalamud.Interface.ImGuiNotification.Internal;
+using Dalamud.Interface.Textures;
using Dalamud.Interface.Textures.Internal;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Interface.Windowing;
using Dalamud.Storage.Assets;
-using Dalamud.Utility;
using ImGuiNET;
@@ -144,8 +144,6 @@ internal class ImGuiWidget : IDataWindowWidget
"Action Bar (always on if not user dismissable for the example)",
ref this.notificationTemplate.ActionBar);
- ImGui.Checkbox("Leave Textures Open", ref this.notificationTemplate.LeaveTexturesOpen);
-
if (ImGui.Button("Add notification"))
{
var text =
@@ -212,35 +210,34 @@ internal class ImGuiWidget : IDataWindowWidget
switch (this.notificationTemplate.IconInt)
{
case 5:
- n.SetIconTexture(
- DisposeLoggingTextureWrap.Wrap(
- dam.GetDalamudTextureWrap(
- Enum.Parse(
- NotificationTemplate.AssetSources[this.notificationTemplate.IconAssetInt]))),
- this.notificationTemplate.LeaveTexturesOpen);
- break;
- case 6:
- n.SetIconTexture(
- dam.GetDalamudTextureWrapAsync(
- Enum.Parse(
- NotificationTemplate.AssetSources[this.notificationTemplate.IconAssetInt]))
- .ContinueWith(
- r => r.IsCompletedSuccessfully
- ? Task.FromResult(DisposeLoggingTextureWrap.Wrap(r.Result))
- : r).Unwrap(),
- this.notificationTemplate.LeaveTexturesOpen);
+ var textureWrap = DisposeLoggingTextureWrap.Wrap(
+ dam.GetDalamudTextureWrap(
+ Enum.Parse(
+ NotificationTemplate.AssetSources[this.notificationTemplate.IconAssetInt])));
+
+ if (textureWrap != null)
+ {
+ n.IconTexture = new ForwardingSharedImmediateTexture(textureWrap);
+ }
+
break;
case 7:
- n.SetIconTexture(
- DisposeLoggingTextureWrap.Wrap(
- tm.Shared.GetFromGame(this.notificationTemplate.IconText).GetWrapOrDefault()),
- this.notificationTemplate.LeaveTexturesOpen);
+ var textureWrap2 = DisposeLoggingTextureWrap.Wrap(
+ tm.Shared.GetFromGame(this.notificationTemplate.IconText).GetWrapOrDefault());
+ if (textureWrap2 != null)
+ {
+ n.IconTexture = new ForwardingSharedImmediateTexture(textureWrap2);
+ }
+
break;
case 8:
- n.SetIconTexture(
- DisposeLoggingTextureWrap.Wrap(
- tm.Shared.GetFromFile(this.notificationTemplate.IconText).GetWrapOrDefault()),
- this.notificationTemplate.LeaveTexturesOpen);
+ var textureWrap3 = DisposeLoggingTextureWrap.Wrap(
+ tm.Shared.GetFromFile(this.notificationTemplate.IconText).GetWrapOrDefault());
+ if (textureWrap3 != null)
+ {
+ n.IconTexture = new ForwardingSharedImmediateTexture(textureWrap3);
+ }
+
break;
}
@@ -303,15 +300,15 @@ internal class ImGuiWidget : IDataWindowWidget
};
}
}
-
+
ImGui.SameLine();
if (ImGui.Button("Replace images using setter"))
{
foreach (var n in this.notifications)
{
var i = (uint)Random.Shared.NextInt64(0, 200000);
- n.IconTexture = DisposeLoggingTextureWrap.Wrap(
- Service.Get().Shared.GetFromGameIcon(new(i)).GetWrapOrDefault());
+
+ n.IconTexture = Service.Get().Shared.GetFromGameIcon(new(i, false, false));
}
}
}
@@ -428,7 +425,6 @@ internal class ImGuiWidget : IDataWindowWidget
public bool Minimized;
public bool UserDismissable;
public bool ActionBar;
- public bool LeaveTexturesOpen;
public int ProgressMode;
public void Reset()
@@ -450,7 +446,6 @@ internal class ImGuiWidget : IDataWindowWidget
this.Minimized = true;
this.UserDismissable = true;
this.ActionBar = true;
- this.LeaveTexturesOpen = true;
this.ProgressMode = 0;
this.RespectUiHidden = true;
}
diff --git a/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs b/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs
index ce8c192a4..c9ca65e0c 100644
--- a/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs
@@ -28,6 +28,8 @@ using ImGuiNET;
using Lumina.Text.ReadOnly;
+using Serilog;
+
using LSeStringBuilder = Lumina.Text.SeStringBuilder;
namespace Dalamud.Interface.Internal.Windows;
@@ -185,6 +187,23 @@ internal class TitleScreenMenuWindow : Window, IDisposable
if (!entry.IsShowConditionSatisfied())
continue;
+ if (entry.Texture.TryGetWrap(out var textureWrap, out var exception))
+ {
+ if (textureWrap.Width != 64 && textureWrap.Height != 64)
+ {
+ Log.Error("Texture provided for ITitleScreenMenuEntry must be 64x64. Entry will be removed.");
+ this.titleScreenMenu.RemoveEntry(entry);
+ continue;
+ }
+ }
+
+ if (exception != null)
+ {
+ Log.Error(exception, "An exception occurred while attempting to get the texture wrap for a ITitleScreenMenuEntry. Entry will be removed.");
+ this.titleScreenMenu.RemoveEntry(entry);
+ continue;
+ }
+
if (!this.moveEasings.TryGetValue(entry.Id, out var moveEasing))
{
moveEasing = new InOutQuint(TimeSpan.FromMilliseconds(400));
@@ -259,6 +278,23 @@ internal class TitleScreenMenuWindow : Window, IDisposable
if (!entry.IsShowConditionSatisfied())
continue;
+ if (entry.Texture.TryGetWrap(out var textureWrap, out var exception))
+ {
+ if (textureWrap.Width != 64 && textureWrap.Height != 64)
+ {
+ Log.Error($"Texture provided for ITitleScreenMenuEntry {entry.Name} must be 64x64. Entry will be removed.");
+ this.titleScreenMenu.RemoveEntry(entry);
+ continue;
+ }
+ }
+
+ if (exception != null)
+ {
+ Log.Error(exception, $"An exception occurred while attempting to get the texture wrap for ITitleScreenMenuEntry {entry.Name}. Entry will be removed.");
+ this.titleScreenMenu.RemoveEntry(entry);
+ continue;
+ }
+
var finalPos = (i + 1) * this.shadeTexture.Value.Height * scale;
this.DrawEntry(entry, i != 0, true, i == 0, false, false);
@@ -374,7 +410,9 @@ internal class TitleScreenMenuWindow : Window, IDisposable
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, 1f);
}
- ImGui.Image(entry.Texture.ImGuiHandle, new Vector2(TitleScreenMenu.TextureSize * scale));
+ // Wrap should always be valid at this point due to us checking the validity of the image each frame
+ var dalamudTextureWrap = entry.Texture.GetWrapOrEmpty();
+ ImGui.Image(dalamudTextureWrap.ImGuiHandle, new Vector2(TitleScreenMenu.TextureSize * scale));
if (overrideAlpha || isFirst)
{
ImGui.PopStyleVar();
@@ -388,7 +426,7 @@ internal class TitleScreenMenuWindow : Window, IDisposable
var textHeight = ImGui.GetTextLineHeightWithSpacing();
var cursor = ImGui.GetCursorPos();
- cursor.Y += (entry.Texture.Height * scale / 2) - (textHeight / 2);
+ cursor.Y += (dalamudTextureWrap.Height * scale / 2) - (textHeight / 2);
if (overrideAlpha)
{
@@ -411,7 +449,7 @@ internal class TitleScreenMenuWindow : Window, IDisposable
ImGui.PopStyleVar();
}
- initialCursor.Y += entry.Texture.Height * scale;
+ initialCursor.Y += dalamudTextureWrap.Height * scale;
ImGui.SetCursorPos(initialCursor);
return isHover;
diff --git a/Dalamud/Interface/Textures/ForwardingSharedImmediateTexture.cs b/Dalamud/Interface/Textures/ForwardingSharedImmediateTexture.cs
new file mode 100644
index 000000000..12e312b3e
--- /dev/null
+++ b/Dalamud/Interface/Textures/ForwardingSharedImmediateTexture.cs
@@ -0,0 +1,50 @@
+using System.Threading;
+using System.Threading.Tasks;
+
+using Dalamud.Interface.Textures.TextureWraps;
+using Dalamud.Storage.Assets;
+
+namespace Dalamud.Interface.Textures;
+
+///
+/// Wraps a dalamud texture allowing interoperability with certain services. Only use this if you need to provide a texture that has been created or rented as a ISharedImmediateTexture.
+///
+public class ForwardingSharedImmediateTexture : ISharedImmediateTexture
+{
+ private readonly IDalamudTextureWrap textureWrap;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A textureWrap that has been created or provided by RentAsync.
+ public ForwardingSharedImmediateTexture(IDalamudTextureWrap textureWrap)
+ {
+ this.textureWrap = textureWrap;
+ }
+
+ ///
+ public IDalamudTextureWrap GetWrapOrEmpty()
+ {
+ return this.textureWrap;
+ }
+
+ ///
+ public IDalamudTextureWrap? GetWrapOrDefault(IDalamudTextureWrap? defaultWrap = null)
+ {
+ return this.textureWrap;
+ }
+
+ ///
+ public bool TryGetWrap(out IDalamudTextureWrap? texture, out Exception? exception)
+ {
+ texture = this.textureWrap;
+ exception = null;
+ return true;
+ }
+
+ ///
+ public Task RentAsync(CancellationToken cancellationToken = default)
+ {
+ return Task.FromResult(this.textureWrap);
+ }
+}
diff --git a/Dalamud/Interface/TitleScreenMenu/TitleScreenMenu.cs b/Dalamud/Interface/TitleScreenMenu/TitleScreenMenu.cs
index 6f98b9757..586d65559 100644
--- a/Dalamud/Interface/TitleScreenMenu/TitleScreenMenu.cs
+++ b/Dalamud/Interface/TitleScreenMenu/TitleScreenMenu.cs
@@ -3,8 +3,7 @@ using System.Linq;
using System.Reflection;
using Dalamud.Game.ClientState.Keys;
-using Dalamud.Interface.Internal;
-using Dalamud.Interface.Textures.TextureWraps;
+using Dalamud.Interface.Textures;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
@@ -67,7 +66,7 @@ internal class TitleScreenMenu : IServiceType, ITitleScreenMenu
}
}
}
-
+
///
/// Adds a new entry to the title screen menu.
///
@@ -76,13 +75,8 @@ internal class TitleScreenMenu : IServiceType, ITitleScreenMenu
/// The action to execute when the option is selected.
/// A object that can be used to manage the entry.
/// Thrown when the texture provided does not match the required resolution(64x64).
- public ITitleScreenMenuEntry AddPluginEntry(string text, IDalamudTextureWrap texture, Action onTriggered)
+ public ITitleScreenMenuEntry AddPluginEntry(string text, ISharedImmediateTexture texture, Action onTriggered)
{
- if (texture.Height != TextureSize || texture.Width != TextureSize)
- {
- throw new ArgumentException("Texture must be 64x64");
- }
-
TitleScreenMenuEntry entry;
lock (this.entries)
{
@@ -103,13 +97,13 @@ internal class TitleScreenMenu : IServiceType, ITitleScreenMenu
}
///
- public IReadOnlyTitleScreenMenuEntry AddEntry(string text, IDalamudTextureWrap texture, Action onTriggered)
+ public IReadOnlyTitleScreenMenuEntry AddEntry(string text, ISharedImmediateTexture texture, Action onTriggered)
{
return this.AddPluginEntry(text, texture, onTriggered);
}
///
- public IReadOnlyTitleScreenMenuEntry AddEntry(ulong priority, string text, IDalamudTextureWrap texture, Action onTriggered)
+ public IReadOnlyTitleScreenMenuEntry AddEntry(ulong priority, string text, ISharedImmediateTexture texture, Action onTriggered)
{
return this.AddPluginEntry(priority, text, texture, onTriggered);
}
@@ -123,13 +117,8 @@ internal class TitleScreenMenu : IServiceType, ITitleScreenMenu
/// The action to execute when the option is selected.
/// A object that can be used to manage the entry.
/// Thrown when the texture provided does not match the required resolution(64x64).
- public ITitleScreenMenuEntry AddPluginEntry(ulong priority, string text, IDalamudTextureWrap texture, Action onTriggered)
+ public ITitleScreenMenuEntry AddPluginEntry(ulong priority, string text, ISharedImmediateTexture texture, Action onTriggered)
{
- if (texture.Height != TextureSize || texture.Width != TextureSize)
- {
- throw new ArgumentException("Texture must be 64x64");
- }
-
TitleScreenMenuEntry entry;
lock (this.entries)
{
@@ -166,13 +155,8 @@ internal class TitleScreenMenu : IServiceType, ITitleScreenMenu
/// The action to execute when the option is selected.
/// A object that can be used to manage the entry.
/// Thrown when the texture provided does not match the required resolution(64x64).
- internal TitleScreenMenuEntry AddEntryCore(ulong priority, string text, IDalamudTextureWrap texture, Action onTriggered)
+ internal TitleScreenMenuEntry AddEntryCore(ulong priority, string text, ISharedImmediateTexture texture, Action onTriggered)
{
- if (texture.Height != TextureSize || texture.Width != TextureSize)
- {
- throw new ArgumentException("Texture must be 64x64");
- }
-
TitleScreenMenuEntry entry;
lock (this.entries)
{
@@ -199,15 +183,10 @@ internal class TitleScreenMenu : IServiceType, ITitleScreenMenu
/// Thrown when the texture provided does not match the required resolution(64x64).
internal TitleScreenMenuEntry AddEntryCore(
string text,
- IDalamudTextureWrap texture,
+ ISharedImmediateTexture texture,
Action onTriggered,
params VirtualKey[] showConditionKeys)
{
- if (texture.Height != TextureSize || texture.Width != TextureSize)
- {
- throw new ArgumentException("Texture must be 64x64");
- }
-
TitleScreenMenuEntry entry;
lock (this.entries)
{
@@ -240,7 +219,7 @@ internal class TitleScreenMenuPluginScoped : IInternalDisposableService, ITitleS
{
[ServiceManager.ServiceDependency]
private readonly TitleScreenMenu titleScreenMenuService = Service.Get();
-
+
private readonly List pluginEntries = new();
///
@@ -254,25 +233,25 @@ internal class TitleScreenMenuPluginScoped : IInternalDisposableService, ITitleS
this.titleScreenMenuService.RemoveEntry(entry);
}
}
-
+
///
- public IReadOnlyTitleScreenMenuEntry AddEntry(string text, IDalamudTextureWrap texture, Action onTriggered)
+ public IReadOnlyTitleScreenMenuEntry AddEntry(string text, ISharedImmediateTexture texture, Action onTriggered)
{
var entry = this.titleScreenMenuService.AddPluginEntry(text, texture, onTriggered);
this.pluginEntries.Add(entry);
return entry;
}
-
+
///
- public IReadOnlyTitleScreenMenuEntry AddEntry(ulong priority, string text, IDalamudTextureWrap texture, Action onTriggered)
+ public IReadOnlyTitleScreenMenuEntry AddEntry(ulong priority, string text, ISharedImmediateTexture texture, Action onTriggered)
{
var entry = this.titleScreenMenuService.AddPluginEntry(priority, text, texture, onTriggered);
this.pluginEntries.Add(entry);
return entry;
}
-
+
///
public void RemoveEntry(IReadOnlyTitleScreenMenuEntry entry)
{
diff --git a/Dalamud/Interface/TitleScreenMenu/TitleScreenMenuEntry.cs b/Dalamud/Interface/TitleScreenMenu/TitleScreenMenuEntry.cs
index 2acb275ad..a98d32770 100644
--- a/Dalamud/Interface/TitleScreenMenu/TitleScreenMenuEntry.cs
+++ b/Dalamud/Interface/TitleScreenMenu/TitleScreenMenuEntry.cs
@@ -4,8 +4,7 @@ using System.Linq;
using System.Reflection;
using Dalamud.Game.ClientState.Keys;
-using Dalamud.Interface.Internal;
-using Dalamud.Interface.Textures.TextureWraps;
+using Dalamud.Interface.Textures;
namespace Dalamud.Interface;
@@ -64,7 +63,7 @@ public interface IReadOnlyTitleScreenMenuEntry
///
/// Gets the texture of this entry.
///
- IDalamudTextureWrap Texture { get; }
+ ISharedImmediateTexture Texture { get; }
}
///
@@ -87,7 +86,7 @@ public class TitleScreenMenuEntry : ITitleScreenMenuEntry
Assembly? callingAssembly,
ulong priority,
string text,
- IDalamudTextureWrap texture,
+ ISharedImmediateTexture texture,
Action onTriggered,
IEnumerable? showConditionKeys = null)
{
@@ -106,8 +105,8 @@ public class TitleScreenMenuEntry : ITitleScreenMenuEntry
public string Name { get; set; }
///
- public IDalamudTextureWrap Texture { get; set; }
-
+ public ISharedImmediateTexture Texture { get; set; }
+
///
public bool IsInternal { get; set; }
diff --git a/Dalamud/Plugin/Services/ITitleScreenMenu.cs b/Dalamud/Plugin/Services/ITitleScreenMenu.cs
index 5ebd80017..9f7b17ea3 100644
--- a/Dalamud/Plugin/Services/ITitleScreenMenu.cs
+++ b/Dalamud/Plugin/Services/ITitleScreenMenu.cs
@@ -1,8 +1,7 @@
using System.Collections.Generic;
using Dalamud.Interface;
-using Dalamud.Interface.Internal;
-using Dalamud.Interface.Textures.TextureWraps;
+using Dalamud.Interface.Textures;
namespace Dalamud.Plugin.Services;
@@ -20,22 +19,22 @@ public interface ITitleScreenMenu
/// Adds a new entry to the title screen menu.
///
/// The text to show.
- /// The texture to show.
+ /// The texture to show. The texture must be 64x64 or the entry will be removed and an error will be logged.
/// The action to execute when the option is selected.
/// A object that can be reference the entry.
/// Thrown when the texture provided does not match the required resolution(64x64).
- public IReadOnlyTitleScreenMenuEntry AddEntry(string text, IDalamudTextureWrap texture, Action onTriggered);
+ public IReadOnlyTitleScreenMenuEntry AddEntry(string text, ISharedImmediateTexture texture, Action onTriggered);
///
/// Adds a new entry to the title screen menu.
///
/// Priority of the entry.
/// The text to show.
- /// The texture to show.
+ /// The texture to show. The texture must be 64x64 or the entry will be removed and an error will be logged.
/// The action to execute when the option is selected.
/// A object that can be used to reference the entry.
/// Thrown when the texture provided does not match the required resolution(64x64).
- public IReadOnlyTitleScreenMenuEntry AddEntry(ulong priority, string text, IDalamudTextureWrap texture, Action onTriggered);
+ public IReadOnlyTitleScreenMenuEntry AddEntry(ulong priority, string text, ISharedImmediateTexture texture, Action onTriggered);
///
/// Remove an entry from the title screen menu.