diff --git a/Dalamud/Game/Gui/Dtr/DtrBar.cs b/Dalamud/Game/Gui/Dtr/DtrBar.cs index b1679c296..8b021bc7a 100644 --- a/Dalamud/Game/Gui/Dtr/DtrBar.cs +++ b/Dalamud/Game/Gui/Dtr/DtrBar.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; @@ -50,6 +51,7 @@ public sealed unsafe class DtrBar : IDisposable, IServiceType, IDtrBar private readonly DalamudAddonEventManager uiEventManager = Service.Get(); private readonly DtrBarAddressResolver address; + private readonly ConcurrentBag newEntries = new(); private readonly List entries = new(); private readonly Hook onAddonDrawHook; private readonly Hook onAddonRequestedUpdateHook; @@ -78,18 +80,17 @@ public sealed unsafe class DtrBar : IDisposable, IServiceType, IDtrBar /// public DtrBarEntry Get(string title, SeString? text = null) { - if (this.entries.Any(x => x.Title == title)) + if (this.entries.Any(x => x.Title == title) || this.newEntries.Any(x => x.Title == title)) throw new ArgumentException("An entry with the same title already exists."); - var node = this.MakeNode(++this.runningNodeIds); - var entry = new DtrBarEntry(title, node); + var entry = new DtrBarEntry(title, null); entry.Text = text; // Add the entry to the end of the order list, if it's not there already. if (!this.configuration.DtrOrder!.Contains(title)) this.configuration.DtrOrder!.Add(title); - this.entries.Add(entry); - this.ApplySort(); + + this.newEntries.Add(entry); return entry; } @@ -173,6 +174,7 @@ public sealed unsafe class DtrBar : IDisposable, IServiceType, IDtrBar private void Update(Framework unused) { this.HandleRemovedNodes(); + this.HandleAddedNodes(); var dtr = this.GetDtr(); if (dtr == null) return; @@ -238,6 +240,21 @@ public sealed unsafe class DtrBar : IDisposable, IServiceType, IDtrBar } } + private void HandleAddedNodes() + { + if (this.newEntries.Any()) + { + foreach (var newEntry in this.newEntries) + { + newEntry.TextNode = this.MakeNode(++this.runningNodeIds); + this.entries.Add(newEntry); + } + + this.newEntries.Clear(); + this.ApplySort(); + } + } + // This hooks all AtkUnitBase.Draw calls, then checks for our specific addon name. // AddonDtr doesn't implement it's own Draw method, would need to replace vtable entry to be more efficient. private void OnAddonDrawDetour(AtkUnitBase* addon)