diff --git a/Dalamud/Interface/GameFonts/GameFontHandle.cs b/Dalamud/Interface/GameFonts/GameFontHandle.cs
index 679452ba4..2594eea0e 100644
--- a/Dalamud/Interface/GameFonts/GameFontHandle.cs
+++ b/Dalamud/Interface/GameFonts/GameFontHandle.cs
@@ -71,7 +71,7 @@ public sealed class GameFontHandle : IFontHandle
public void Dispose() => this.fontHandle.Dispose();
///
- public IFontHandle.ImFontLocked Lock() => this.fontHandle.Lock();
+ public ILockedImFont Lock() => this.fontHandle.Lock();
///
public IDisposable Push() => this.fontHandle.Push();
diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs
index 82299a136..6cf4a8b90 100644
--- a/Dalamud/Interface/Internal/InterfaceManager.cs
+++ b/Dalamud/Interface/Internal/InterfaceManager.cs
@@ -63,7 +63,7 @@ internal class InterfaceManager : IDisposable, IServiceType
public const float DefaultFontSizePx = (DefaultFontSizePt * 4.0f) / 3.0f;
private readonly ConcurrentBag deferredDisposeTextures = new();
- private readonly ConcurrentBag deferredDisposeImFontLockeds = new();
+ private readonly ConcurrentBag deferredDisposeImFontLockeds = new();
[ServiceManager.ServiceDependency]
private readonly WndProcHookManager wndProcHookManager = Service.Get();
@@ -79,7 +79,7 @@ internal class InterfaceManager : IDisposable, IServiceType
private Hook? resizeBuffersHook;
private IFontAtlas? dalamudAtlas;
- private IFontHandle.ImFontLocked? defaultFontResourceLock;
+ private ILockedImFont? defaultFontResourceLock;
// can't access imgui IO before first present call
private bool lastWantCapture = false;
@@ -408,10 +408,10 @@ internal class InterfaceManager : IDisposable, IServiceType
}
///
- /// Enqueue an to be disposed at the end of the frame.
+ /// Enqueue an to be disposed at the end of the frame.
///
/// The disposable.
- public void EnqueueDeferredDispose(in IFontHandle.ImFontLocked locked)
+ public void EnqueueDeferredDispose(in ILockedImFont locked)
{
this.deferredDisposeImFontLockeds.Add(locked);
}
@@ -738,7 +738,7 @@ internal class InterfaceManager : IDisposable, IServiceType
// Update the ImGui default font.
unsafe
{
- ImGui.GetIO().NativePtr->FontDefault = fontLocked;
+ ImGui.GetIO().NativePtr->FontDefault = fontLocked.ImFont;
}
// Update the reference to the resources of the default font.
diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/GamePrebakedFontsTestWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/GamePrebakedFontsTestWidget.cs
index 7b649a895..b486cc7d9 100644
--- a/Dalamud/Interface/Internal/Windows/Data/Widgets/GamePrebakedFontsTestWidget.cs
+++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/GamePrebakedFontsTestWidget.cs
@@ -249,7 +249,7 @@ internal class GamePrebakedFontsTestWidget : IDataWindowWidget, IDisposable
await handle.WaitAsync();
var locked = handle.Lock();
garbage.Add(locked);
- fonts.Add(locked);
+ fonts.Add(locked.ImFont);
}
}
catch (ObjectDisposedException)
diff --git a/Dalamud/Interface/ManagedFontAtlas/IFontHandle.cs b/Dalamud/Interface/ManagedFontAtlas/IFontHandle.cs
index dd3775236..11c26616b 100644
--- a/Dalamud/Interface/ManagedFontAtlas/IFontHandle.cs
+++ b/Dalamud/Interface/ManagedFontAtlas/IFontHandle.cs
@@ -1,14 +1,7 @@
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Threading.Tasks;
-
-using Dalamud.Interface.Utility;
-using Dalamud.Utility;
+using System.Threading.Tasks;
using ImGuiNET;
-using Microsoft.Extensions.ObjectPool;
-
namespace Dalamud.Interface.ManagedFontAtlas;
///
@@ -21,7 +14,7 @@ public interface IFontHandle : IDisposable
///
/// The relevant font handle.
/// The locked font for this font handle, locked during the call of this delegate.
- public delegate void ImFontChangedDelegate(IFontHandle fontHandle, ImFontLocked lockedFont);
+ public delegate void ImFontChangedDelegate(IFontHandle fontHandle, ILockedImFont lockedFont);
///
/// Called when the built instance of has been changed.
@@ -48,13 +41,13 @@ public interface IFontHandle : IDisposable
/// , for use in any thread.
/// Modification of the font will exhibit undefined behavior if some other thread also uses the font.
///
- /// An instance of that must be disposed after use.
+ /// An instance of that must be disposed after use.
///
/// Calling . will not unlock the
/// locked by this function.
///
/// If is false.
- ImFontLocked Lock();
+ ILockedImFont Lock();
///
/// Pushes the current font into ImGui font stack, if available.
@@ -80,85 +73,4 @@ public interface IFontHandle : IDisposable
///
/// A task containing this .
Task WaitAsync();
-
- ///
- /// The wrapper for , guaranteeing that the associated data will be available as long as
- /// this struct is not disposed.
- ///
- public class ImFontLocked : IDisposable
- {
- // Using constructor instead of DefaultObjectPoolProvider, since we do not want the pool to call Dispose.
- private static readonly ObjectPool Pool =
- new DefaultObjectPool(new DefaultPooledObjectPolicy());
-
- private IRefCountable? owner;
-
- ///
- /// Finalizes an instance of the class.
- ///
- ~ImFontLocked() => this.FreeOwner();
-
- ///
- /// Gets the associated .
- ///
- public ImFontPtr ImFont { get; private set; }
-
- public static implicit operator ImFontPtr(ImFontLocked l) => l.ImFont;
-
- public static unsafe implicit operator ImFont*(ImFontLocked l) => l.ImFont.NativePtr;
-
- ///
- /// Creates a new instance of with an additional reference to the owner.
- ///
- /// The new locked instance.
- public ImFontLocked NewRef()
- {
- if (this.owner is null)
- throw new ObjectDisposedException(nameof(ImFontLocked));
-
- var rented = Pool.Get();
- rented.owner = this.owner;
- rented.ImFont = this.ImFont;
-
- this.owner.AddRef();
- return rented;
- }
-
- ///
- [SuppressMessage(
- "Usage",
- "CA1816:Dispose methods should call SuppressFinalize",
- Justification = "Dispose returns this object to the pool.")]
- public void Dispose()
- {
- this.FreeOwner();
- Pool.Return(this);
- }
-
- ///
- /// Initializes a new instance of the class.
- /// Ownership of reference of is transferred.
- ///
- /// The contained font.
- /// The owner.
- /// The rented instance of .
- internal static ImFontLocked Rent(ImFontPtr font, IRefCountable owner)
- {
- var rented = Pool.Get();
- Debug.Assert(rented.ImFont.IsNull(), "Rented object must not have its font set");
- rented.ImFont = font;
- rented.owner = owner;
- return rented;
- }
-
- private void FreeOwner()
- {
- if (this.owner is null)
- return;
-
- this.owner.Release();
- this.owner = null;
- this.ImFont = default;
- }
- }
}
diff --git a/Dalamud/Interface/ManagedFontAtlas/ILockedImFont.cs b/Dalamud/Interface/ManagedFontAtlas/ILockedImFont.cs
new file mode 100644
index 000000000..9136d2723
--- /dev/null
+++ b/Dalamud/Interface/ManagedFontAtlas/ILockedImFont.cs
@@ -0,0 +1,21 @@
+using ImGuiNET;
+
+namespace Dalamud.Interface.ManagedFontAtlas;
+
+///
+/// The wrapper for , guaranteeing that the associated data will be available as long as
+/// this struct is not disposed.
+///
+public interface ILockedImFont : IDisposable
+{
+ ///
+ /// Gets the associated .
+ ///
+ ImFontPtr ImFont { get; }
+
+ ///
+ /// Creates a new instance of with an additional reference to the owner.
+ ///
+ /// The new locked instance.
+ ILockedImFont NewRef();
+}
diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs
index 06bc5b7ab..4d636b8cf 100644
--- a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs
+++ b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs
@@ -534,7 +534,7 @@ internal sealed partial class FontAtlasFactory
private void PromoteBuiltData(int rebuildIndex, FontAtlasBuiltData data, [UsedImplicitly] string source)
{
// Capture the locks inside the lock block, so that the fonts are guaranteed to be the ones just built.
- var fontsAndLocks = new List<(FontHandle FontHandle, IFontHandle.ImFontLocked Lock)>();
+ var fontsAndLocks = new List<(FontHandle FontHandle, ILockedImFont Lock)>();
using var garbage = new DisposeSafety.ScopedFinalizer();
lock (this.syncRoot)
@@ -557,7 +557,7 @@ internal sealed partial class FontAtlasFactory
foreach (var fontHandle in substance.RelevantHandles)
{
substance.DataRoot.AddRef();
- var locked = IFontHandle.ImFontLocked.Rent(
+ var locked = new LockedImFont(
substance.GetFontPtr(fontHandle),
substance.DataRoot);
fontsAndLocks.Add((fontHandle, garbage.Add(locked)));
diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs
index f8291cc51..47254a5c9 100644
--- a/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs
+++ b/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs
@@ -74,7 +74,7 @@ internal abstract class FontHandle : IFontHandle
/// Invokes .
///
/// The font, locked during the call of .
- public void InvokeImFontChanged(IFontHandle.ImFontLocked font)
+ public void InvokeImFontChanged(ILockedImFont font)
{
try
{
@@ -133,11 +133,11 @@ internal abstract class FontHandle : IFontHandle
///
/// The error message, if any.
///
- /// An instance of that must be disposed after use on success;
+ /// An instance of that must be disposed after use on success;
/// null with populated on failure.
///
/// Still may be thrown.
- public IFontHandle.ImFontLocked? TryLock(out string? errorMessage)
+ public ILockedImFont? TryLock(out string? errorMessage)
{
IFontHandleSubstance? prevSubstance = default;
while (true)
@@ -182,12 +182,12 @@ internal abstract class FontHandle : IFontHandle
// Transfer the ownership of reference.
errorMessage = null;
- return IFontHandle.ImFontLocked.Rent(fontPtr, substance.DataRoot);
+ return new LockedImFont(fontPtr, substance.DataRoot);
}
}
///
- public IFontHandle.ImFontLocked Lock() =>
+ public ILockedImFont Lock() =>
this.TryLock(out var errorMessage) ?? throw new InvalidOperationException(errorMessage);
///
@@ -238,10 +238,10 @@ internal abstract class FontHandle : IFontHandle
this.ImFontChanged += OnImFontChanged;
this.Disposed += OnDisposed;
if (this.Available)
- OnImFontChanged(this, default);
+ OnImFontChanged(this, null);
return tcs.Task;
- void OnImFontChanged(IFontHandle unused, IFontHandle.ImFontLocked unused2)
+ void OnImFontChanged(IFontHandle unused, ILockedImFont? unused2)
{
if (tcs.Task.IsCompletedSuccessfully)
return;
diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/LockedImFont.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/LockedImFont.cs
new file mode 100644
index 000000000..bd50502c8
--- /dev/null
+++ b/Dalamud/Interface/ManagedFontAtlas/Internals/LockedImFont.cs
@@ -0,0 +1,62 @@
+using Dalamud.Utility;
+
+using ImGuiNET;
+
+namespace Dalamud.Interface.ManagedFontAtlas.Internals;
+
+///
+/// The implementation for .
+///
+internal class LockedImFont : ILockedImFont
+{
+ private IRefCountable? owner;
+
+ ///
+ /// Initializes a new instance of the class.
+ /// Ownership of reference of is transferred.
+ ///
+ /// The contained font.
+ /// The owner.
+ /// The rented instance of .
+ internal LockedImFont(ImFontPtr font, IRefCountable owner)
+ {
+ this.ImFont = font;
+ this.owner = owner;
+ }
+
+ ///
+ /// Finalizes an instance of the class.
+ ///
+ ~LockedImFont() => this.FreeOwner();
+
+ ///
+ public ImFontPtr ImFont { get; private set; }
+
+ ///
+ public ILockedImFont NewRef()
+ {
+ if (this.owner is null)
+ throw new ObjectDisposedException(nameof(LockedImFont));
+
+ var newRef = new LockedImFont(this.ImFont, this.owner);
+ this.owner.AddRef();
+ return newRef;
+ }
+
+ ///
+ public void Dispose()
+ {
+ this.FreeOwner();
+ GC.SuppressFinalize(this);
+ }
+
+ private void FreeOwner()
+ {
+ if (this.owner is null)
+ return;
+
+ this.owner.Release();
+ this.owner = null;
+ this.ImFont = default;
+ }
+}
diff --git a/Dalamud/Interface/UiBuilder.cs b/Dalamud/Interface/UiBuilder.cs
index b038d44ba..ce5a09b22 100644
--- a/Dalamud/Interface/UiBuilder.cs
+++ b/Dalamud/Interface/UiBuilder.cs
@@ -761,7 +761,7 @@ public sealed class UiBuilder : IDisposable
// Note: do not dispose w; we do not own it
}
- public IFontHandle.ImFontLocked Lock() =>
+ public ILockedImFont Lock() =>
this.wrapped?.Lock() ?? throw new ObjectDisposedException(nameof(FontHandleWrapper));
public IDisposable Push() =>
@@ -775,7 +775,7 @@ public sealed class UiBuilder : IDisposable
public override string ToString() => $"{nameof(FontHandleWrapper)}({this.wrapped})";
- private void WrappedOnImFontChanged(IFontHandle obj, IFontHandle.ImFontLocked lockedFont) =>
+ private void WrappedOnImFontChanged(IFontHandle obj, ILockedImFont lockedFont) =>
this.ImFontChanged?.Invoke(obj, lockedFont);
}
}