mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Turn ImFontLocked into a class
As `ImFontLocked` utilizes a reference counter, changed it to a class so that at worst case we still got the destructor to decrease the reference count.
This commit is contained in:
parent
df89472d4c
commit
68dc16803c
5 changed files with 75 additions and 34 deletions
|
|
@ -79,7 +79,7 @@ internal class InterfaceManager : IDisposable, IServiceType
|
||||||
private Hook<ResizeBuffersDelegate>? resizeBuffersHook;
|
private Hook<ResizeBuffersDelegate>? resizeBuffersHook;
|
||||||
|
|
||||||
private IFontAtlas? dalamudAtlas;
|
private IFontAtlas? dalamudAtlas;
|
||||||
private IFontHandle.ImFontLocked defaultFontResourceLock;
|
private IFontHandle.ImFontLocked? defaultFontResourceLock;
|
||||||
|
|
||||||
// can't access imgui IO before first present call
|
// can't access imgui IO before first present call
|
||||||
private bool lastWantCapture = false;
|
private bool lastWantCapture = false;
|
||||||
|
|
@ -243,6 +243,8 @@ internal class InterfaceManager : IDisposable, IServiceType
|
||||||
Disposer();
|
Disposer();
|
||||||
|
|
||||||
this.wndProcHookManager.PreWndProc -= this.WndProcHookManagerOnPreWndProc;
|
this.wndProcHookManager.PreWndProc -= this.WndProcHookManagerOnPreWndProc;
|
||||||
|
this.defaultFontResourceLock?.Dispose(); // lock outlives handle and atlas
|
||||||
|
this.defaultFontResourceLock = null;
|
||||||
this.dalamudAtlas?.Dispose();
|
this.dalamudAtlas?.Dispose();
|
||||||
this.scene?.Dispose();
|
this.scene?.Dispose();
|
||||||
return;
|
return;
|
||||||
|
|
@ -727,22 +729,26 @@ internal class InterfaceManager : IDisposable, IServiceType
|
||||||
tk.GetFont(this.MonoFontHandle),
|
tk.GetFont(this.MonoFontHandle),
|
||||||
missingOnly: true);
|
missingOnly: true);
|
||||||
});
|
});
|
||||||
this.DefaultFontHandle.ImFontChanged += (_, font) => Service<Framework>.Get().RunOnFrameworkThread(
|
this.DefaultFontHandle.ImFontChanged += (_, font) =>
|
||||||
() =>
|
{
|
||||||
{
|
var fontLocked = font.NewRef();
|
||||||
// Update the ImGui default font.
|
Service<Framework>.Get().RunOnFrameworkThread(
|
||||||
unsafe
|
() =>
|
||||||
{
|
{
|
||||||
ImGui.GetIO().NativePtr->FontDefault = font;
|
// Update the ImGui default font.
|
||||||
}
|
unsafe
|
||||||
|
{
|
||||||
|
ImGui.GetIO().NativePtr->FontDefault = fontLocked;
|
||||||
|
}
|
||||||
|
|
||||||
// Update the reference to the resources of the default font.
|
// Update the reference to the resources of the default font.
|
||||||
this.defaultFontResourceLock.Dispose();
|
this.defaultFontResourceLock?.Dispose();
|
||||||
this.defaultFontResourceLock = font.NewRef();
|
this.defaultFontResourceLock = fontLocked;
|
||||||
|
|
||||||
// Broadcast to auto-rebuilding instances.
|
// Broadcast to auto-rebuilding instances.
|
||||||
this.AfterBuildFonts?.Invoke();
|
this.AfterBuildFonts?.Invoke();
|
||||||
});
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will wait for scene on its own. We just wait for this.dalamudAtlas.BuildTask in this.InitScene.
|
// This will wait for scene on its own. We just wait for this.dalamudAtlas.BuildTask in this.InitScene.
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,14 @@
|
||||||
using System.Threading.Tasks;
|
using System.Diagnostics;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Dalamud.Interface.Utility;
|
||||||
using Dalamud.Utility;
|
using Dalamud.Utility;
|
||||||
|
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
||||||
|
using Microsoft.Extensions.ObjectPool;
|
||||||
|
|
||||||
namespace Dalamud.Interface.ManagedFontAtlas;
|
namespace Dalamud.Interface.ManagedFontAtlas;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -80,26 +85,23 @@ public interface IFontHandle : IDisposable
|
||||||
/// The wrapper for <see cref="ImFontPtr"/>, guaranteeing that the associated data will be available as long as
|
/// The wrapper for <see cref="ImFontPtr"/>, guaranteeing that the associated data will be available as long as
|
||||||
/// this struct is not disposed.
|
/// this struct is not disposed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct ImFontLocked : IDisposable
|
public class ImFontLocked : IDisposable
|
||||||
{
|
{
|
||||||
/// <summary>
|
// Using constructor instead of DefaultObjectPoolProvider, since we do not want the pool to call Dispose.
|
||||||
/// The associated <see cref="ImFontPtr"/>.
|
private static readonly ObjectPool<ImFontLocked> Pool =
|
||||||
/// </summary>
|
new DefaultObjectPool<ImFontLocked>(new DefaultPooledObjectPolicy<ImFontLocked>());
|
||||||
public ImFontPtr ImFont;
|
|
||||||
|
|
||||||
private IRefCountable? owner;
|
private IRefCountable? owner;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ImFontLocked"/> struct.
|
/// Finalizes an instance of the <see cref="ImFontLocked"/> class.
|
||||||
/// Ownership of reference of <paramref name="owner"/> is transferred.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="imFont">The contained font.</param>
|
~ImFontLocked() => this.FreeOwner();
|
||||||
/// <param name="owner">The owner.</param>
|
|
||||||
internal ImFontLocked(ImFontPtr imFont, IRefCountable owner)
|
/// <summary>
|
||||||
{
|
/// Gets the associated <see cref="ImFontPtr"/>.
|
||||||
this.ImFont = imFont;
|
/// </summary>
|
||||||
this.owner = owner;
|
public ImFontPtr ImFont { get; private set; }
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator ImFontPtr(ImFontLocked l) => l.ImFont;
|
public static implicit operator ImFontPtr(ImFontLocked l) => l.ImFont;
|
||||||
|
|
||||||
|
|
@ -109,16 +111,47 @@ public interface IFontHandle : IDisposable
|
||||||
/// Creates a new instance of <see cref="ImFontLocked"/> with an additional reference to the owner.
|
/// Creates a new instance of <see cref="ImFontLocked"/> with an additional reference to the owner.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The new locked instance.</returns>
|
/// <returns>The new locked instance.</returns>
|
||||||
public readonly ImFontLocked NewRef()
|
public ImFontLocked NewRef()
|
||||||
{
|
{
|
||||||
if (this.owner is null)
|
if (this.owner is null)
|
||||||
throw new ObjectDisposedException(nameof(ImFontLocked));
|
throw new ObjectDisposedException(nameof(ImFontLocked));
|
||||||
|
|
||||||
|
var rented = Pool.Get();
|
||||||
|
rented.owner = this.owner;
|
||||||
|
rented.ImFont = this.ImFont;
|
||||||
|
|
||||||
this.owner.AddRef();
|
this.owner.AddRef();
|
||||||
return new(this.ImFont, this.owner);
|
return rented;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
[SuppressMessage(
|
||||||
|
"Usage",
|
||||||
|
"CA1816:Dispose methods should call SuppressFinalize",
|
||||||
|
Justification = "Dispose returns this object to the pool.")]
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
{
|
||||||
|
this.FreeOwner();
|
||||||
|
Pool.Return(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ImFontLocked"/> class.
|
||||||
|
/// Ownership of reference of <paramref name="owner"/> is transferred.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="font">The contained font.</param>
|
||||||
|
/// <param name="owner">The owner.</param>
|
||||||
|
/// <returns>The rented instance of <see cref="ImFontLocked"/>.</returns>
|
||||||
|
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)
|
if (this.owner is null)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -557,7 +557,9 @@ internal sealed partial class FontAtlasFactory
|
||||||
foreach (var fontHandle in substance.RelevantHandles)
|
foreach (var fontHandle in substance.RelevantHandles)
|
||||||
{
|
{
|
||||||
substance.DataRoot.AddRef();
|
substance.DataRoot.AddRef();
|
||||||
var locked = new IFontHandle.ImFontLocked(substance.GetFontPtr(fontHandle), substance.DataRoot);
|
var locked = IFontHandle.ImFontLocked.Rent(
|
||||||
|
substance.GetFontPtr(fontHandle),
|
||||||
|
substance.DataRoot);
|
||||||
fontsAndLocks.Add((fontHandle, garbage.Add(locked)));
|
fontsAndLocks.Add((fontHandle, garbage.Add(locked)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ internal abstract class FontHandle : IFontHandle
|
||||||
|
|
||||||
// Transfer the ownership of reference.
|
// Transfer the ownership of reference.
|
||||||
errorMessage = null;
|
errorMessage = null;
|
||||||
return new(fontPtr, substance.DataRoot);
|
return IFontHandle.ImFontLocked.Rent(fontPtr, substance.DataRoot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ internal sealed class SimplePushedFont : IDisposable
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stack">The <see cref="IFontHandle"/>-private stack.</param>
|
/// <param name="stack">The <see cref="IFontHandle"/>-private stack.</param>
|
||||||
/// <param name="fontPtr">The font pointer being pushed.</param>
|
/// <param name="fontPtr">The font pointer being pushed.</param>
|
||||||
/// <returns><c>this</c>.</returns>
|
/// <returns>The rented instance of <see cref="SimplePushedFont"/>.</returns>
|
||||||
public static SimplePushedFont Rent(List<IDisposable> stack, ImFontPtr fontPtr)
|
public static SimplePushedFont Rent(List<IDisposable> stack, ImFontPtr fontPtr)
|
||||||
{
|
{
|
||||||
var rented = Pool.Get();
|
var rented = Pool.Get();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue