Dalamud/Dalamud/Interface/Textures/ISharedImmediateTexture.cs

88 lines
5.5 KiB
C#

using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using Dalamud.Interface.Internal;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Utility;
namespace Dalamud.Interface.Textures;
/// <summary>A texture with a backing instance of <see cref="IDalamudTextureWrap"/> that is shared across multiple
/// requesters.</summary>
/// <remarks>
/// <para><see cref="GetWrapOrEmpty"/> and <see cref="TryGetWrap"/> may stop returning the intended texture at any point.
/// Use <see cref="RentAsync"/> to lock the texture for use in any thread for any duration.</para>
/// </remarks>
public interface ISharedImmediateTexture
{
/// <summary>Gets the texture for use with the current frame, or an empty texture if unavailable.</summary>
/// <returns>An instance of <see cref="IDalamudTextureWrap"/> that is guaranteed to be available for the current
/// frame being drawn.</returns>
/// <remarks>
/// <para>Do not cache the result of this function across draw calls for different frames.
/// <see cref="ISharedImmediateTexture"/>s may be cached, but the performance benefit will be minimal.</para>
/// <para>Calling outside the main thread will fail.</para>
/// <para>This function does not throw.</para>
/// <para><see cref="IDisposable.Dispose"/> will be ignored, including the cases when the returned texture wrap
/// is passed to a function with <c>leaveWrapOpen</c> parameter.</para>
/// <para>If the texture is unavailable for any reason, then the returned instance of
/// <see cref="IDalamudTextureWrap"/> will point to an empty texture instead.</para>
/// </remarks>
IDalamudTextureWrap GetWrapOrEmpty();
/// <summary>Gets the texture for use with the current frame, or a default value specified via
/// <paramref name="defaultWrap"/> if unavailable.</summary>
/// <param name="defaultWrap">The default wrap to return if the requested texture was not immediately available.
/// </param>
/// <returns>An instance of <see cref="IDalamudTextureWrap"/> that is guaranteed to be available for the current
/// frame being drawn.</returns>
/// <remarks>
/// <para>Do not cache the result of this function across draw calls for different frames.
/// <see cref="ISharedImmediateTexture"/>s may be cached, but the performance benefit will be minimal.</para>
/// <para>Calling outside the main thread will fail.</para>
/// <para>This function does not throw.</para>
/// <para><see cref="IDisposable.Dispose"/> will be ignored, including the cases when the returned texture wrap
/// is passed to a function with <c>leaveWrapOpen</c> parameter.</para>
/// <para>If the texture is unavailable for any reason, then <paramref name="defaultWrap"/> will be returned.</para>
/// </remarks>
[return: NotNullIfNotNull(nameof(defaultWrap))]
IDalamudTextureWrap? GetWrapOrDefault(IDalamudTextureWrap? defaultWrap = null);
/// <summary>Attempts to get the texture for use with the current frame.</summary>
/// <param name="texture">An instance of <see cref="IDalamudTextureWrap"/> that is guaranteed to be available for
/// the current frame being drawn, or <c>null</c> if texture is not loaded (yet).</param>
/// <param name="exception">The load exception, if any.</param>
/// <returns><c>true</c> if <paramref name="texture"/> points to the loaded texture; <c>false</c> if the texture is
/// still being loaded, or the load has failed.</returns>
/// <remarks>
/// <para>Do not cache the result of this function across draw calls for different frames.
/// <see cref="ISharedImmediateTexture"/>s may be cached, but the performance benefit will be minimal.</para>
/// <para>Calling outside the main thread will fail.</para>
/// <para>This function does not throw.</para>
/// <para><see cref="IDisposable.Dispose"/> on the returned <paramref name="texture"/> will be ignored, including
/// the cases when the returned texture wrap is passed to a function with <c>leaveWrapOpen</c> parameter.</para>
/// </remarks>
/// <exception cref="InvalidOperationException">Thrown when called outside the UI thread.</exception>
bool TryGetWrap([NotNullWhen(true)] out IDalamudTextureWrap? texture, out Exception? exception);
/// <summary>
/// <para>
/// Creates a new instance of <see cref="IDalamudTextureWrap"/> holding a new reference to this texture.
/// The returned texture is guaranteed to be available until <see cref="IDisposable.Dispose"/> is called.
/// </para>
/// <para>
/// <b>WARNING!</b> Usually, this method should be a "last resort"/compatibility wrapper for old code that does not
/// directly support <see cref="ISharedImmediateTexture"/> directly. Prefer using any of the other methods if possible,
/// and <b>DO NOT CACHE</b> the resulting texture wrap from those functions.
/// </para>
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A <see cref="Task{TResult}"/> containing the loaded texture on success.</returns>
/// <remarks>
/// <see cref="IDisposable.Dispose"/> must be called on the resulting instance of <see cref="IDalamudTextureWrap"/>
/// from the returned <see cref="Task{TResult}"/> after use. Consider using
/// <see cref="DisposeSafety.ToContentDisposedTask{T}"/> to dispose the result automatically according to the state
/// of the task.</remarks>
Task<IDalamudTextureWrap> RentAsync(CancellationToken cancellationToken = default);
}