diff --git a/Dalamud/Interface/ImGuiNotification/IActiveNotification.cs b/Dalamud/Interface/ImGuiNotification/IActiveNotification.cs
index c3ea2b9de..e677471b4 100644
--- a/Dalamud/Interface/ImGuiNotification/IActiveNotification.cs
+++ b/Dalamud/Interface/ImGuiNotification/IActiveNotification.cs
@@ -1,4 +1,5 @@
using System.Threading;
+using System.Threading.Tasks;
using Dalamud.Interface.ImGuiNotification.EventArgs;
using Dalamud.Interface.Internal;
@@ -50,7 +51,7 @@ public interface IActiveNotification : INotification
/// This does not override .
void ExtendBy(TimeSpan extension);
- /// Sets the icon from , overriding the icon .
+ /// 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 .
///
@@ -61,6 +62,21 @@ public interface IActiveNotification : INotification
///
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. 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);
+
/// 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 2bc8e751c..207722c56 100644
--- a/Dalamud/Interface/ImGuiNotification/INotification.cs
+++ b/Dalamud/Interface/ImGuiNotification/INotification.cs
@@ -1,3 +1,6 @@
+using System.Threading.Tasks;
+
+using Dalamud.Interface.Internal;
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Plugin.Services;
@@ -20,8 +23,10 @@ public interface INotification
NotificationType Type { get; set; }
/// Gets or sets the icon source.
- /// Use to use a texture, after calling
- /// .
+ /// Use or
+ /// to use a texture, after calling
+ /// . Call either of those functions with null to revert
+ /// the effective icon back to this property.
INotificationIcon? Icon { get; set; }
/// Gets or sets the hard expiry.
diff --git a/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs b/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs
index a9950745d..c54a9c6fa 100644
--- a/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs
+++ b/Dalamud/Interface/ImGuiNotification/Internal/ActiveNotification.cs
@@ -1,5 +1,6 @@
using System.Runtime.Loader;
using System.Threading;
+using System.Threading.Tasks;
using Dalamud.Interface.Animation;
using Dalamud.Interface.Animation.EasingFunctions;
@@ -29,7 +30,7 @@ internal sealed partial class ActiveNotification : IActiveNotification
private DateTime extendedExpiry;
/// The icon texture to use if specified; otherwise, icon will be used from .
- private IDalamudTextureWrap? iconTextureWrap;
+ private Task? iconTextureWrap;
/// The plugin that initiated this notification.
private LocalPlugin? initiatorPlugin;
@@ -229,18 +230,24 @@ internal sealed partial class ActiveNotification : IActiveNotification
///
public void SetIconTexture(IDalamudTextureWrap? textureWrap)
+ {
+ this.SetIconTexture(textureWrap is null ? null : Task.FromResult(textureWrap));
+ }
+
+ ///
+ public void SetIconTexture(Task? textureWrapTask)
{
if (this.DismissReason is not null)
{
- textureWrap?.Dispose();
+ textureWrapTask?.ToContentDisposedTask(true);
return;
}
// After replacing, if the old texture is not the old texture, then dispose the old texture.
- if (Interlocked.Exchange(ref this.iconTextureWrap, textureWrap) is { } wrapToDispose &&
- wrapToDispose != textureWrap)
+ if (Interlocked.Exchange(ref this.iconTextureWrap, textureWrapTask) is { } wrapTaskToDispose &&
+ wrapTaskToDispose != textureWrapTask)
{
- wrapToDispose.Dispose();
+ wrapTaskToDispose.ToContentDisposedTask(true);
}
}
@@ -333,8 +340,8 @@ internal sealed partial class ActiveNotification : IActiveNotification
/// Clears the resources associated with this instance of .
internal void DisposeInternal()
{
- if (Interlocked.Exchange(ref this.iconTextureWrap, null) is { } wrapToDispose)
- wrapToDispose.Dispose();
+ if (Interlocked.Exchange(ref this.iconTextureWrap, null) is { } wrapTaskToDispose)
+ wrapTaskToDispose.ToContentDisposedTask(true);
this.Dismiss = null;
this.Click = null;
this.DrawActions = null;
diff --git a/Dalamud/Interface/ImGuiNotification/NotificationUtilities.cs b/Dalamud/Interface/ImGuiNotification/NotificationUtilities.cs
index 0ec2561fd..0ed552b42 100644
--- a/Dalamud/Interface/ImGuiNotification/NotificationUtilities.cs
+++ b/Dalamud/Interface/ImGuiNotification/NotificationUtilities.cs
@@ -1,6 +1,7 @@
using System.IO;
using System.Numerics;
using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
using Dalamud.Game.Text;
using Dalamud.Interface.Internal;
@@ -103,6 +104,16 @@ 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/Windows/Data/Widgets/ImGuiWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs
index 47c5993cd..95119bb48 100644
--- a/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs
+++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs
@@ -88,20 +88,20 @@ internal class ImGuiWidget : IDataWindowWidget
ref this.notificationTemplate.IconText,
255);
break;
- case 3 or 4:
+ case 5 or 6:
ImGui.Combo(
"Asset##iconAssetCombo",
ref this.notificationTemplate.IconAssetInt,
NotificationTemplate.AssetSources,
NotificationTemplate.AssetSources.Length);
break;
- case 5 or 7:
+ case 3 or 7:
ImGui.InputText(
"Game Path##iconText",
ref this.notificationTemplate.IconText,
255);
break;
- case 6 or 8:
+ case 4 or 8:
ImGui.InputText(
"File Path##iconText",
ref this.notificationTemplate.IconText,
@@ -206,9 +206,15 @@ internal class ImGuiWidget : IDataWindowWidget
NotificationTemplate.AssetSources[this.notificationTemplate.IconAssetInt])));
break;
case 6:
- n.SetIconTexture(tm.GetTextureFromGame(this.notificationTemplate.IconText));
+ n.SetIconTexture(
+ dam.GetDalamudTextureWrapAsync(
+ Enum.Parse(
+ NotificationTemplate.AssetSources[this.notificationTemplate.IconAssetInt])));
break;
case 7:
+ n.SetIconTexture(tm.GetTextureFromGame(this.notificationTemplate.IconText));
+ break;
+ case 8:
n.SetIconTexture(tm.GetTextureFromFile(new(this.notificationTemplate.IconText)));
break;
}
@@ -315,6 +321,7 @@ internal class ImGuiWidget : IDataWindowWidget
"GamePath",
"FilePath",
"TextureWrap from DalamudAssets",
+ "TextureWrap from DalamudAssets(Async)",
"TextureWrap from GamePath",
"TextureWrap from FilePath",
};