diff --git a/Dalamud.CorePlugin/PluginImpl.cs b/Dalamud.CorePlugin/PluginImpl.cs index 96d212dd3..cb9b4368a 100644 --- a/Dalamud.CorePlugin/PluginImpl.cs +++ b/Dalamud.CorePlugin/PluginImpl.cs @@ -69,7 +69,7 @@ namespace Dalamud.CorePlugin this.Interface.UiBuilder.Draw += this.OnDraw; this.Interface.UiBuilder.OpenConfigUi += this.OnOpenConfigUi; this.Interface.UiBuilder.OpenMainUi += this.OnOpenMainUi; - this.Interface.UiBuilder.DefaultFontHandle.ImFontChanged += fc => + this.Interface.UiBuilder.DefaultFontHandle.ImFontChanged += (fc, _) => { Log.Information($"CorePlugin : DefaultFontHandle.ImFontChanged called {fc}"); }; diff --git a/Dalamud/Interface/GameFonts/GameFontHandle.cs b/Dalamud/Interface/GameFonts/GameFontHandle.cs index 4c472c032..679452ba4 100644 --- a/Dalamud/Interface/GameFonts/GameFontHandle.cs +++ b/Dalamud/Interface/GameFonts/GameFontHandle.cs @@ -31,7 +31,7 @@ public sealed class GameFontHandle : IFontHandle } /// - public event Action ImFontChanged + public event IFontHandle.ImFontChangedDelegate ImFontChanged { add => this.fontHandle.ImFontChanged += value; remove => this.fontHandle.ImFontChanged -= value; diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs index 93050d67a..18bb95799 100644 --- a/Dalamud/Interface/Internal/InterfaceManager.cs +++ b/Dalamud/Interface/Internal/InterfaceManager.cs @@ -79,6 +79,7 @@ internal class InterfaceManager : IDisposable, IServiceType private Hook? resizeBuffersHook; private IFontAtlas? dalamudAtlas; + private IFontHandle.ImFontLocked defaultFontResourceLock; // can't access imgui IO before first present call private bool lastWantCapture = false; @@ -717,32 +718,35 @@ internal class InterfaceManager : IDisposable, IServiceType tk => tk.AddDalamudAssetFont( DalamudAsset.InconsolataRegular, new() { SizePx = DefaultFontSizePx }))); - this.dalamudAtlas.BuildStepChange += e => e - .OnPostBuild( - tk => + this.dalamudAtlas.BuildStepChange += e => e.OnPostBuild( + tk => + { + // Fill missing glyphs in MonoFont from DefaultFont. + tk.CopyGlyphsAcrossFonts( + tk.GetFont(this.DefaultFontHandle), + tk.GetFont(this.MonoFontHandle), + missingOnly: true); + }); + this.DefaultFontHandle.ImFontChanged += (_, font) => Service.Get().RunOnFrameworkThread( + () => + { + // Update the ImGui default font. + unsafe { - // Fill missing glyphs in MonoFont from DefaultFont. - tk.CopyGlyphsAcrossFonts( - tk.GetFont(this.DefaultFontHandle), - tk.GetFont(this.MonoFontHandle), - missingOnly: true); - }) - .OnPostPromotion( - tk => - { - // Update the ImGui default font. - unsafe - { - ImGui.GetIO().NativePtr->FontDefault = tk.GetFont(this.DefaultFontHandle); - } + ImGui.GetIO().NativePtr->FontDefault = font; + } - // Broadcast to auto-rebuilding instances. - this.AfterBuildFonts?.Invoke(); - }); + // Update the reference to the resources of the default font. + this.defaultFontResourceLock.Dispose(); + this.defaultFontResourceLock = font.NewRef(); + + // Broadcast to auto-rebuilding instances. + this.AfterBuildFonts?.Invoke(); + }); } // This will wait for scene on its own. We just wait for this.dalamudAtlas.BuildTask in this.InitScene. - _ = this.dalamudAtlas.BuildFontsAsync(false); + _ = this.dalamudAtlas.BuildFontsAsync(); this.address.Setup(sigScanner); diff --git a/Dalamud/Interface/ManagedFontAtlas/FontAtlasBuildStep.cs b/Dalamud/Interface/ManagedFontAtlas/FontAtlasBuildStep.cs index ba94db435..dcfcc32e3 100644 --- a/Dalamud/Interface/ManagedFontAtlas/FontAtlasBuildStep.cs +++ b/Dalamud/Interface/ManagedFontAtlas/FontAtlasBuildStep.cs @@ -27,15 +27,4 @@ public enum FontAtlasBuildStep /// but it will never happen on its own. /// PostBuild = 2, - - /// - /// Called after promoting staging font atlas to the actual atlas for .
- /// Expect to be passed.
- /// When called from , this will be called after the delegates - /// passed to ; you should not make modifications to fonts.
- ///
- /// This callback is not guaranteed to happen after , - /// but it will never happen on its own. - ///
- PostPromotion = 3, } diff --git a/Dalamud/Interface/ManagedFontAtlas/FontAtlasBuildStepDelegate.cs b/Dalamud/Interface/ManagedFontAtlas/FontAtlasBuildStepDelegate.cs index 4f5b34061..2ed88102f 100644 --- a/Dalamud/Interface/ManagedFontAtlas/FontAtlasBuildStepDelegate.cs +++ b/Dalamud/Interface/ManagedFontAtlas/FontAtlasBuildStepDelegate.cs @@ -6,10 +6,9 @@ namespace Dalamud.Interface.ManagedFontAtlas; /// A toolkit that may help you for font building steps. /// /// An implementation of may implement all of -/// , , and -/// .
+/// and .
/// Either use to identify the build step, or use -/// , , -/// and for routing. +/// and +/// for routing. ///
public delegate void FontAtlasBuildStepDelegate(IFontAtlasBuildToolkit toolkit); diff --git a/Dalamud/Interface/ManagedFontAtlas/FontAtlasBuildToolkitUtilities.cs b/Dalamud/Interface/ManagedFontAtlas/FontAtlasBuildToolkitUtilities.cs index 586887a3b..4c3e9023a 100644 --- a/Dalamud/Interface/ManagedFontAtlas/FontAtlasBuildToolkitUtilities.cs +++ b/Dalamud/Interface/ManagedFontAtlas/FontAtlasBuildToolkitUtilities.cs @@ -113,21 +113,4 @@ public static class FontAtlasBuildToolkitUtilities action.Invoke((IFontAtlasBuildToolkitPostBuild)toolkit); return toolkit; } - - /// - /// Invokes - /// if of - /// is . - /// - /// The toolkit. - /// The action. - /// toolkit, for method chaining. - public static IFontAtlasBuildToolkit OnPostPromotion( - this IFontAtlasBuildToolkit toolkit, - Action action) - { - if (toolkit.BuildStep is FontAtlasBuildStep.PostPromotion) - action.Invoke((IFontAtlasBuildToolkitPostPromotion)toolkit); - return toolkit; - } } diff --git a/Dalamud/Interface/ManagedFontAtlas/IFontAtlas.cs b/Dalamud/Interface/ManagedFontAtlas/IFontAtlas.cs index 491292f9d..a9c21f94e 100644 --- a/Dalamud/Interface/ManagedFontAtlas/IFontAtlas.cs +++ b/Dalamud/Interface/ManagedFontAtlas/IFontAtlas.cs @@ -129,8 +129,7 @@ public interface IFontAtlas : IDisposable void BuildFontsOnNextFrame(); /// - /// Rebuilds fonts immediately, on the current thread.
- /// Even the callback for will be called on the same thread. + /// Rebuilds fonts immediately, on the current thread. ///
/// If is . void BuildFontsImmediately(); @@ -138,8 +137,7 @@ public interface IFontAtlas : IDisposable /// /// Rebuilds fonts asynchronously, on any thread. /// - /// Call on the main thread. /// The task. /// If is . - Task BuildFontsAsync(bool callPostPromotionOnMainThread = true); + Task BuildFontsAsync(); } diff --git a/Dalamud/Interface/ManagedFontAtlas/IFontAtlasBuildToolkitPostPromotion.cs b/Dalamud/Interface/ManagedFontAtlas/IFontAtlasBuildToolkitPostPromotion.cs deleted file mode 100644 index 930851fc7..000000000 --- a/Dalamud/Interface/ManagedFontAtlas/IFontAtlasBuildToolkitPostPromotion.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Dalamud.Interface.ManagedFontAtlas; - -/// -/// Toolkit for use when the build state is . -/// -public interface IFontAtlasBuildToolkitPostPromotion : IFontAtlasBuildToolkit -{ - // empty -} diff --git a/Dalamud/Interface/ManagedFontAtlas/IFontHandle.cs b/Dalamud/Interface/ManagedFontAtlas/IFontHandle.cs index 97d345925..d58a89e56 100644 --- a/Dalamud/Interface/ManagedFontAtlas/IFontHandle.cs +++ b/Dalamud/Interface/ManagedFontAtlas/IFontHandle.cs @@ -12,14 +12,17 @@ namespace Dalamud.Interface.ManagedFontAtlas; public interface IFontHandle : IDisposable { /// - /// Called when the built instance of has been changed.
- /// This event will be invoked on the same thread with - /// ., - /// when the build step is .
- /// See , , and - /// . + /// Delegate for . ///
- event Action ImFontChanged; + /// 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); + + /// + /// Called when the built instance of has been changed.
+ /// This event can be invoked outside the main thread. + ///
+ event ImFontChangedDelegate ImFontChanged; /// /// Gets the load exception, if it failed to load. Otherwise, it is null. @@ -102,6 +105,18 @@ public interface IFontHandle : IDisposable 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 readonly ImFontLocked NewRef() + { + if (this.owner is null) + throw new ObjectDisposedException(nameof(ImFontLocked)); + this.owner.AddRef(); + return new(this.ImFont, this.owner); + } + /// public void Dispose() { diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/DelegateFontHandle.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/DelegateFontHandle.cs index 53a836511..b13c60a53 100644 --- a/Dalamud/Interface/ManagedFontAtlas/Internals/DelegateFontHandle.cs +++ b/Dalamud/Interface/ManagedFontAtlas/Internals/DelegateFontHandle.cs @@ -80,16 +80,6 @@ internal sealed class DelegateFontHandle : FontHandle this.handles.Remove(cgfh); } - /// - public void InvokeFontHandleImFontChanged() - { - if (this.Substance is not HandleSubstance hs) - return; - - foreach (var handle in hs.RelevantHandles) - handle.InvokeImFontChanged(); - } - /// public IFontHandleSubstance NewSubstance(IRefCountable dataRoot) { @@ -133,6 +123,9 @@ internal sealed class DelegateFontHandle : FontHandle // Not owned by this class. Do not dispose. public DelegateFontHandle[] RelevantHandles { get; } + /// + ICollection IFontHandleSubstance.RelevantHandles => this.RelevantHandles; + /// public IRefCountable DataRoot { get; } @@ -306,32 +299,5 @@ internal sealed class DelegateFontHandle : FontHandle } } } - - /// - public void OnPostPromotion(IFontAtlasBuildToolkitPostPromotion toolkitPostPromotion) - { - foreach (var k in this.RelevantHandles) - { - if (!this.fonts[k].IsNotNullAndLoaded()) - continue; - - try - { - toolkitPostPromotion.Font = this.fonts[k]; - k.CallOnBuildStepChange.Invoke(toolkitPostPromotion); - } - catch (Exception e) - { - this.fonts[k] = default; - this.buildExceptions[k] = e; - - Log.Error( - e, - "[{name}:Substance] An error has occurred while during {delegate} PostPromotion call.", - this.Manager.Name, - nameof(FontAtlasBuildStepDelegate)); - } - } - } } } diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs index 3addfabe8..e2b096701 100644 --- a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs +++ b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs @@ -677,60 +677,4 @@ internal sealed partial class FontAtlasFactory } } } - - /// - /// Implementations for . - /// - private class BuildToolkitPostPromotion : IFontAtlasBuildToolkitPostPromotion - { - private readonly FontAtlasBuiltData builtData; - - /// - /// Initializes a new instance of the class. - /// - /// The built data. - public BuildToolkitPostPromotion(FontAtlasBuiltData builtData) => this.builtData = builtData; - - /// - public ImFontPtr Font { get; set; } - - /// - public float Scale => this.builtData.Scale; - - /// - public bool IsAsyncBuildOperation => true; - - /// - public FontAtlasBuildStep BuildStep => FontAtlasBuildStep.PostPromotion; - - /// - public ImFontAtlasPtr NewImAtlas => this.builtData.Atlas; - - /// - public unsafe ImVectorWrapper Fonts => new( - &this.NewImAtlas.NativePtr->Fonts, - x => ImGuiNative.ImFont_destroy(x->NativePtr)); - - /// - public T DisposeWithAtlas(T disposable) where T : IDisposable => this.builtData.Garbage.Add(disposable); - - /// - public GCHandle DisposeWithAtlas(GCHandle gcHandle) => this.builtData.Garbage.Add(gcHandle); - - /// - public void DisposeWithAtlas(Action action) => this.builtData.Garbage.Add(action); - - /// - public ImFontPtr GetFont(IFontHandle fontHandle) - { - foreach (var s in this.builtData.Substances) - { - var f = s.GetFontPtr(fontHandle); - if (!f.IsNull()) - return f; - } - - return default; - } - } } diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs index 85f7219b2..4e98bf226 100644 --- a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs +++ b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs @@ -486,7 +486,7 @@ internal sealed partial class FontAtlasFactory } /// - public Task BuildFontsAsync(bool callPostPromotionOnMainThread = true) + public Task BuildFontsAsync() { #if VeryVerboseLog Log.Verbose("[{name}] Called: {source}.", this.Name, nameof(this.BuildFontsAsync)); @@ -519,15 +519,7 @@ internal sealed partial class FontAtlasFactory if (res.Atlas.IsNull()) return res; - if (callPostPromotionOnMainThread) - { - await this.factory.Framework.RunOnFrameworkThread( - () => this.InvokePostPromotion(rebuildIndex, res, nameof(this.BuildFontsAsync))); - } - else - { - this.InvokePostPromotion(rebuildIndex, res, nameof(this.BuildFontsAsync)); - } + this.InvokePostPromotion(rebuildIndex, res, nameof(this.BuildFontsAsync)); return res; } @@ -536,6 +528,10 @@ internal sealed partial class FontAtlasFactory private void InvokePostPromotion(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)>(); + using var garbage = new DisposeSafety.ScopedFinalizer(); + lock (this.syncRoot) { if (this.buildIndex != rebuildIndex) @@ -549,56 +545,25 @@ internal sealed partial class FontAtlasFactory prevBuiltData.ExplicitDisposeIgnoreExceptions(); this.buildTask = EmptyTask; + fontsAndLocks.EnsureCapacity(data.Substances.Sum(x => x.RelevantHandles.Count)); foreach (var substance in data.Substances) + { substance.Manager.Substance = substance; + foreach (var fontHandle in substance.RelevantHandles) + { + substance.DataRoot.AddRef(); + var locked = new IFontHandle.ImFontLocked(substance.GetFontPtr(fontHandle), substance.DataRoot); + fontsAndLocks.Add((fontHandle, garbage.Add(locked))); + } + } } - lock (this.syncRootPostPromotion) - { - if (this.buildIndex != rebuildIndex) - { - data.ExplicitDisposeIgnoreExceptions(); - return; - } - - foreach (var substance in data.Substances) - substance.Manager.InvokeFontHandleImFontChanged(); - - var toolkit = new BuildToolkitPostPromotion(data); - - foreach (var substance in data.Substances) - { - try - { - substance.OnPostPromotion(toolkit); - } - catch (Exception e) - { - Log.Error( - e, - "[{name}] {substance} PostPromotion error", - this.Name, - substance.GetType().FullName ?? substance.GetType().Name); - } - } - - try - { - this.BuildStepChange?.Invoke(toolkit); - } - catch (Exception e) - { - Log.Error( - e, - "[{name}] {delegateName} PostPromotion error", - this.Name, - nameof(FontAtlasBuildStepDelegate)); - } + foreach (var (fontHandle, lockedFont) in fontsAndLocks) + fontHandle.InvokeImFontChanged(lockedFont); #if VeryVerboseLog - Log.Verbose("[{name}] Built from {source}.", this.Name, source); + Log.Verbose("[{name}] Built from {source}.", this.Name, source); #endif - } } private void ImGuiSceneOnNewRenderFrame() diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs index 93b17f86e..d01b0df87 100644 --- a/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs +++ b/Dalamud/Interface/ManagedFontAtlas/Internals/FontHandle.cs @@ -41,12 +41,12 @@ internal abstract class FontHandle : IFontHandle } /// - public event Action? ImFontChanged; + public event IFontHandle.ImFontChangedDelegate? ImFontChanged; /// /// Event to be called on the first call. /// - protected event Action? Disposed; + protected event Action? Disposed; /// public Exception? LoadException => this.Manager.Substance?.GetBuildException(this); @@ -70,6 +70,22 @@ internal abstract class FontHandle : IFontHandle GC.SuppressFinalize(this); } + /// + /// Invokes . + /// + /// The font, locked during the call of . + public void InvokeImFontChanged(IFontHandle.ImFontLocked font) + { + try + { + this.ImFontChanged?.Invoke(this, font); + } + catch (Exception e) + { + Log.Error(e, $"{nameof(this.InvokeImFontChanged)}: error"); + } + } + /// /// Obtains an instance of corresponding to this font handle, /// to be released after rendering the current frame. @@ -220,35 +236,51 @@ internal abstract class FontHandle : IFontHandle var tcs = new TaskCompletionSource(); this.ImFontChanged += OnImFontChanged; - this.Disposed += OnImFontChanged; + this.Disposed += OnDisposed; if (this.Available) - OnImFontChanged(this); + OnImFontChanged(this, default); return tcs.Task; - void OnImFontChanged(IFontHandle unused) + void OnImFontChanged(IFontHandle unused, IFontHandle.ImFontLocked unused2) { if (tcs.Task.IsCompletedSuccessfully) return; this.ImFontChanged -= OnImFontChanged; - this.Disposed -= OnImFontChanged; - if (this.manager is null) - tcs.SetException(new ObjectDisposedException(nameof(GamePrebakedFontHandle))); - else + this.Disposed -= OnDisposed; + try + { tcs.SetResult(this); + } + catch + { + // ignore + } + } + + void OnDisposed() + { + if (tcs.Task.IsCompletedSuccessfully) + return; + + this.ImFontChanged -= OnImFontChanged; + this.Disposed -= OnDisposed; + try + { + tcs.SetException(new ObjectDisposedException(nameof(GamePrebakedFontHandle))); + } + catch + { + // ignore + } } } /// - /// Invokes . - /// - protected void InvokeImFontChanged() => this.ImFontChanged.InvokeSafely(this); - - /// - /// Overrideable implementation for . + /// Implementation for . /// /// If true, then the function is being called from . - protected virtual void Dispose(bool disposing) + protected void Dispose(bool disposing) { if (disposing) { @@ -256,7 +288,7 @@ internal abstract class FontHandle : IFontHandle Log.Warning($"{nameof(IFontHandle)}.{nameof(IDisposable.Dispose)}: fonts were still in a stack."); this.Manager.FreeFontHandle(this); this.manager = null; - this.Disposed?.InvokeSafely(this); + this.Disposed?.InvokeSafely(); this.ImFontChanged = null; } } diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/GamePrebakedFontHandle.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/GamePrebakedFontHandle.cs index e062405b8..b6c9817aa 100644 --- a/Dalamud/Interface/ManagedFontAtlas/Internals/GamePrebakedFontHandle.cs +++ b/Dalamud/Interface/ManagedFontAtlas/Internals/GamePrebakedFontHandle.cs @@ -172,16 +172,6 @@ internal class GamePrebakedFontHandle : FontHandle } } - /// - public void InvokeFontHandleImFontChanged() - { - if (this.Substance is not HandleSubstance hs) - return; - - foreach (var handle in hs.RelevantHandles) - handle.InvokeImFontChanged(); - } - /// public IFontHandleSubstance NewSubstance(IRefCountable dataRoot) { @@ -232,6 +222,9 @@ internal class GamePrebakedFontHandle : FontHandle // Not owned by this class. Do not dispose. public GamePrebakedFontHandle[] RelevantHandles { get; } + /// + ICollection IFontHandleSubstance.RelevantHandles => this.RelevantHandles; + /// public IRefCountable DataRoot { get; } @@ -413,12 +406,6 @@ internal class GamePrebakedFontHandle : FontHandle } } - /// - public void OnPostPromotion(IFontAtlasBuildToolkitPostPromotion toolkitPostPromotion) - { - // Irrelevant - } - /// /// Creates a new template font. /// diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/IFontHandleManager.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/IFontHandleManager.cs index 7066817b7..94976598a 100644 --- a/Dalamud/Interface/ManagedFontAtlas/Internals/IFontHandleManager.cs +++ b/Dalamud/Interface/ManagedFontAtlas/Internals/IFontHandleManager.cs @@ -32,9 +32,4 @@ internal interface IFontHandleManager : IDisposable /// The data root. /// The new substance. IFontHandleSubstance NewSubstance(IRefCountable dataRoot); - - /// - /// Invokes . - /// - void InvokeFontHandleImFontChanged(); } diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/IFontHandleSubstance.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/IFontHandleSubstance.cs index 73c14efc1..62c893a48 100644 --- a/Dalamud/Interface/ManagedFontAtlas/Internals/IFontHandleSubstance.cs +++ b/Dalamud/Interface/ManagedFontAtlas/Internals/IFontHandleSubstance.cs @@ -1,4 +1,6 @@ -using Dalamud.Utility; +using System.Collections.Generic; + +using Dalamud.Utility; using ImGuiNET; @@ -32,6 +34,11 @@ internal interface IFontHandleSubstance : IDisposable [Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)] bool CreateFontOnAccess { get; set; } + /// + /// Gets the relevant handles. + /// + public ICollection RelevantHandles { get; } + /// /// Gets the font. /// @@ -64,11 +71,4 @@ internal interface IFontHandleSubstance : IDisposable /// /// The toolkit. void OnPostBuild(IFontAtlasBuildToolkitPostBuild toolkitPostBuild); - - /// - /// Called on the specific thread depending on after - /// promoting the staging atlas to direct use with . - /// - /// The toolkit. - void OnPostPromotion(IFontAtlasBuildToolkitPostPromotion toolkitPostPromotion); } diff --git a/Dalamud/Interface/UiBuilder.cs b/Dalamud/Interface/UiBuilder.cs index af4cc39c2..b038d44ba 100644 --- a/Dalamud/Interface/UiBuilder.cs +++ b/Dalamud/Interface/UiBuilder.cs @@ -744,7 +744,7 @@ public sealed class UiBuilder : IDisposable this.wrapped.ImFontChanged += this.WrappedOnImFontChanged; } - public event Action? ImFontChanged; + public event IFontHandle.ImFontChangedDelegate? ImFontChanged; public Exception? LoadException => this.wrapped!.LoadException ?? new ObjectDisposedException(nameof(FontHandleWrapper)); @@ -775,6 +775,7 @@ public sealed class UiBuilder : IDisposable public override string ToString() => $"{nameof(FontHandleWrapper)}({this.wrapped})"; - private void WrappedOnImFontChanged(IFontHandle obj) => this.ImFontChanged.InvokeSafely(this); + private void WrappedOnImFontChanged(IFontHandle obj, IFontHandle.ImFontLocked lockedFont) => + this.ImFontChanged?.Invoke(obj, lockedFont); } }