From 63b3a02e95b00dcbed78f55da4db6ba2ce874d23 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Mon, 3 Jun 2024 17:45:22 +0200 Subject: [PATCH] Fix issue with crash handler and collections not saving on rename. --- OtterGui | 2 +- Penumbra.CrashHandler/CrashData.cs | 4 +- .../Collections/Manager/CollectionStorage.cs | 1 + Penumbra/Communication/ModSettingChanged.cs | 2 +- Penumbra/Services/CrashHandlerService.cs | 2 +- Penumbra/UI/CollectionTab/CollectionPanel.cs | 68 ++++++++----------- .../UI/CollectionTab/CollectionSelector.cs | 22 +++--- Penumbra/UI/Tabs/CollectionsTab.cs | 8 +-- Penumbra/UI/Tabs/Debug/CrashDataExtensions.cs | 2 +- 9 files changed, 52 insertions(+), 59 deletions(-) diff --git a/OtterGui b/OtterGui index becacbca..5de708b2 160000 --- a/OtterGui +++ b/OtterGui @@ -1 +1 @@ -Subproject commit becacbca4f35595d16ff40dc9639cfa24be3461f +Subproject commit 5de708b27ed45c9cdead71742c7061ad9ce64323 diff --git a/Penumbra.CrashHandler/CrashData.cs b/Penumbra.CrashHandler/CrashData.cs index cdac103f..dd75f46e 100644 --- a/Penumbra.CrashHandler/CrashData.cs +++ b/Penumbra.CrashHandler/CrashData.cs @@ -55,7 +55,7 @@ public class CrashData /// The last vfx function invoked before this crash data was generated. public VfxFuncInvokedEntry? LastVfxFuncInvoked - => LastVfxFuncsInvoked.Count == 0 ? default : LastVfxFuncsInvoked[0]; + => LastVFXFuncsInvoked.Count == 0 ? default : LastVFXFuncsInvoked[0]; /// A collection of the last few characters loaded before this crash data was generated. public List LastCharactersLoaded { get; set; } = []; @@ -64,5 +64,5 @@ public class CrashData public List LastModdedFilesLoaded { get; set; } = []; /// A collection of the last few vfx functions invoked before this crash data was generated. - public List LastVfxFuncsInvoked { get; set; } = []; + public List LastVFXFuncsInvoked { get; set; } = []; } diff --git a/Penumbra/Collections/Manager/CollectionStorage.cs b/Penumbra/Collections/Manager/CollectionStorage.cs index f6287320..67de3a03 100644 --- a/Penumbra/Collections/Manager/CollectionStorage.cs +++ b/Penumbra/Collections/Manager/CollectionStorage.cs @@ -181,6 +181,7 @@ public class CollectionStorage : IReadOnlyList, IDisposable return false; } + Delete(collection); _saveService.ImmediateDelete(new ModCollectionSave(_modStorage, collection)); _collections.RemoveAt(collection.Index); // Update indices. diff --git a/Penumbra/Communication/ModSettingChanged.cs b/Penumbra/Communication/ModSettingChanged.cs index a7da345b..7fda2f35 100644 --- a/Penumbra/Communication/ModSettingChanged.cs +++ b/Penumbra/Communication/ModSettingChanged.cs @@ -24,7 +24,7 @@ public sealed class ModSettingChanged() { public enum Priority { - /// + /// Api = int.MinValue, /// diff --git a/Penumbra/Services/CrashHandlerService.cs b/Penumbra/Services/CrashHandlerService.cs index 1239578b..25c6cf57 100644 --- a/Penumbra/Services/CrashHandlerService.cs +++ b/Penumbra/Services/CrashHandlerService.cs @@ -287,7 +287,7 @@ public sealed class CrashHandlerService : IDisposable, IService try { - if (PathDataHandler.Split(manipulatedPath.Value.FullName, out var actualPath, out _) && Path.IsPathRooted(actualPath)) + if (PathDataHandler.Split(manipulatedPath.Value.FullName, out var actualPath, out _) && !Path.IsPathRooted(actualPath)) return; var name = GetActorName(resolveData.AssociatedGameObject); diff --git a/Penumbra/UI/CollectionTab/CollectionPanel.cs b/Penumbra/UI/CollectionTab/CollectionPanel.cs index cb4dbe20..082b78b8 100644 --- a/Penumbra/UI/CollectionTab/CollectionPanel.cs +++ b/Penumbra/UI/CollectionTab/CollectionPanel.cs @@ -20,19 +20,23 @@ using Penumbra.UI.Classes; namespace Penumbra.UI.CollectionTab; -public sealed class CollectionPanel : IDisposable +public sealed class CollectionPanel( + DalamudPluginInterface pi, + CommunicatorService communicator, + CollectionManager manager, + CollectionSelector selector, + ActorManager actors, + ITargetManager targets, + ModStorage mods, + SaveService saveService, + IncognitoService incognito) + : IDisposable { - private readonly CollectionStorage _collections; - private readonly ActiveCollections _active; - private readonly CollectionSelector _selector; - private readonly ActorManager _actors; - private readonly ITargetManager _targets; - private readonly IndividualAssignmentUi _individualAssignmentUi; - private readonly InheritanceUi _inheritanceUi; - private readonly ModStorage _mods; - private readonly FilenameService _fileNames; - private readonly IncognitoService _incognito; - private readonly IFontHandle _nameFont; + private readonly CollectionStorage _collections = manager.Storage; + private readonly ActiveCollections _active = manager.Active; + private readonly IndividualAssignmentUi _individualAssignmentUi = new(communicator, actors, manager); + private readonly InheritanceUi _inheritanceUi = new(manager, incognito); + private readonly IFontHandle _nameFont = pi.UiBuilder.FontAtlas.NewGameFontHandle(new GameFontStyle(GameFontFamilyAndSize.Jupiter23)); private static readonly IReadOnlyDictionary Buttons = CreateButtons(); private static readonly IReadOnlyList<(CollectionType, bool, bool, string, uint)> AdvancedTree = CreateTree(); @@ -41,23 +45,6 @@ public sealed class CollectionPanel : IDisposable private int _draggedIndividualAssignment = -1; - public CollectionPanel(DalamudPluginInterface pi, CommunicatorService communicator, CollectionManager manager, - CollectionSelector selector, ActorManager actors, ITargetManager targets, ModStorage mods, FilenameService fileNames, - IncognitoService incognito) - { - _collections = manager.Storage; - _active = manager.Active; - _selector = selector; - _actors = actors; - _targets = targets; - _mods = mods; - _fileNames = fileNames; - _incognito = incognito; - _individualAssignmentUi = new IndividualAssignmentUi(communicator, actors, manager); - _inheritanceUi = new InheritanceUi(manager, incognito); - _nameFont = pi.UiBuilder.FontAtlas.NewGameFontHandle(new GameFontStyle(GameFontFamilyAndSize.Jupiter23)); - } - public void Dispose() { _individualAssignmentUi.Dispose(); @@ -237,17 +224,22 @@ public sealed class CollectionPanel : IDisposable var name = _newName ?? collection.Name; var identifier = collection.Identifier; var width = ImGui.GetContentRegionAvail().X; - var fileName = _fileNames.CollectionFile(collection); + var fileName = saveService.FileNames.CollectionFile(collection); ImGui.SetNextItemWidth(width); if (ImGui.InputText("##name", ref name, 128)) _newName = name; - if (ImGui.IsItemDeactivatedAfterEdit() && _newName != null) + if (ImGui.IsItemDeactivatedAfterEdit() && _newName != null && _newName != collection.Name) { collection.Name = _newName; - _newName = null; + saveService.QueueSave(new ModCollectionSave(mods, collection)); + selector.RestoreCollections(); + _newName = null; } else if (ImGui.IsItemDeactivated()) + { _newName = null; + } + using (ImRaii.PushFont(UiBuilder.MonoFont)) { if (ImGui.Button(collection.Identifier, new Vector2(width, 0))) @@ -329,7 +321,7 @@ public sealed class CollectionPanel : IDisposable DrawIndividualDragTarget(text, id); if (!invalid) { - _selector.DragTargetAssignment(type, id); + selector.DragTargetAssignment(type, id); var name = Name(collection); var size = ImGui.CalcTextSize(name); var textPos = ImGui.GetItemRectMax() - size - ImGui.GetStyle().FramePadding; @@ -418,7 +410,7 @@ public sealed class CollectionPanel : IDisposable /// Respect incognito mode for names of identifiers. private string Name(ActorIdentifier id, string? name) - => _incognito.IncognitoMode && id.Type is IdentifierType.Player or IdentifierType.Owned + => incognito.IncognitoMode && id.Type is IdentifierType.Player or IdentifierType.Owned ? id.Incognito(name) : name ?? id.ToString(); @@ -426,7 +418,7 @@ public sealed class CollectionPanel : IDisposable private string Name(ModCollection? collection) => collection == null ? "Unassigned" : collection == ModCollection.Empty ? "Use No Mods" : - _incognito.IncognitoMode ? collection.AnonymizedName : collection.Name; + incognito.IncognitoMode ? collection.AnonymizedName : collection.Name; private void DrawIndividualButton(string intro, Vector2 width, string tooltip, char suffix, params ActorIdentifier[] identifiers) { @@ -445,11 +437,11 @@ public sealed class CollectionPanel : IDisposable } private void DrawCurrentCharacter(Vector2 width) - => DrawIndividualButton("Current Character", width, string.Empty, 'c', _actors.GetCurrentPlayer()); + => DrawIndividualButton("Current Character", width, string.Empty, 'c', actors.GetCurrentPlayer()); private void DrawCurrentTarget(Vector2 width) => DrawIndividualButton("Current Target", width, string.Empty, 't', - _actors.FromObject(_targets.Target, false, true, true)); + actors.FromObject(targets.Target, false, true, true)); private void DrawNewPlayer(Vector2 width) => DrawIndividualButton("New Player", width, _individualAssignmentUi.PlayerTooltip, 'p', @@ -610,7 +602,7 @@ public sealed class CollectionPanel : IDisposable ImGui.TableSetupColumn("State", ImGuiTableColumnFlags.WidthFixed, 1.75f * ImGui.GetFrameHeight()); ImGui.TableSetupColumn("Priority", ImGuiTableColumnFlags.WidthFixed, 2.5f * ImGui.GetFrameHeight()); ImGui.TableHeadersRow(); - foreach (var (mod, (settings, parent)) in _mods.Select(m => (m, collection[m.Index])) + foreach (var (mod, (settings, parent)) in mods.Select(m => (m, collection[m.Index])) .Where(t => t.Item2.Settings != null) .OrderBy(t => t.m.Name)) { diff --git a/Penumbra/UI/CollectionTab/CollectionSelector.cs b/Penumbra/UI/CollectionTab/CollectionSelector.cs index c14baf5b..024873bf 100644 --- a/Penumbra/UI/CollectionTab/CollectionSelector.cs +++ b/Penumbra/UI/CollectionTab/CollectionSelector.cs @@ -44,7 +44,9 @@ public sealed class CollectionSelector : ItemSelector, IDisposabl if (idx < 0 || idx >= Items.Count) return false; - return _storage.RemoveCollection(Items[idx]); + // Always return false since we handle the selection update ourselves. + _storage.RemoveCollection(Items[idx]); + return false; } protected override bool DeleteButtonEnabled() @@ -111,6 +113,15 @@ public sealed class CollectionSelector : ItemSelector, IDisposabl private string Name(ModCollection collection) => _incognito.IncognitoMode || collection.Name.Length == 0 ? collection.AnonymizedName : collection.Name; + public void RestoreCollections() + { + Items.Clear(); + foreach (var c in _storage.OrderBy(c => c.Name)) + Items.Add(c); + SetFilterDirty(); + SetCurrent(_active.Current); + } + private void OnCollectionChange(CollectionType type, ModCollection? old, ModCollection? @new, string _3) { switch (type) @@ -122,14 +133,7 @@ public sealed class CollectionSelector : ItemSelector, IDisposabl SetFilterDirty(); return; case CollectionType.Inactive: - Items.Clear(); - foreach (var c in _storage.OrderBy(c => c.Name)) - Items.Add(c); - - if (old == Current) - ClearCurrentSelection(); - else - TryRestoreCurrent(); + RestoreCollections(); SetFilterDirty(); return; default: diff --git a/Penumbra/UI/Tabs/CollectionsTab.cs b/Penumbra/UI/Tabs/CollectionsTab.cs index 1eaece50..fabf7561 100644 --- a/Penumbra/UI/Tabs/CollectionsTab.cs +++ b/Penumbra/UI/Tabs/CollectionsTab.cs @@ -1,16 +1,12 @@ using Dalamud.Game.ClientState.Objects; -using Dalamud.Interface; -using Dalamud.Interface.Utility; using Dalamud.Plugin; using ImGuiNET; -using OtterGui; using OtterGui.Raii; using OtterGui.Widgets; using Penumbra.Collections.Manager; using Penumbra.GameData.Actors; using Penumbra.Mods.Manager; using Penumbra.Services; -using Penumbra.UI.Classes; using Penumbra.UI.CollectionTab; namespace Penumbra.UI.Tabs; @@ -42,13 +38,13 @@ public sealed class CollectionsTab : IDisposable, ITab } public CollectionsTab(DalamudPluginInterface pi, Configuration configuration, CommunicatorService communicator, IncognitoService incognito, - CollectionManager collectionManager, ModStorage modStorage, ActorManager actors, ITargetManager targets, TutorialService tutorial, FilenameService fileNames) + CollectionManager collectionManager, ModStorage modStorage, ActorManager actors, ITargetManager targets, TutorialService tutorial, SaveService saveService) { _config = configuration.Ephemeral; _tutorial = tutorial; _incognito = incognito; _selector = new CollectionSelector(configuration, communicator, collectionManager.Storage, collectionManager.Active, _tutorial, incognito); - _panel = new CollectionPanel(pi, communicator, collectionManager, _selector, actors, targets, modStorage, fileNames, incognito); + _panel = new CollectionPanel(pi, communicator, collectionManager, _selector, actors, targets, modStorage, saveService, incognito); } public void Dispose() diff --git a/Penumbra/UI/Tabs/Debug/CrashDataExtensions.cs b/Penumbra/UI/Tabs/Debug/CrashDataExtensions.cs index 4649e548..94c6cbd6 100644 --- a/Penumbra/UI/Tabs/Debug/CrashDataExtensions.cs +++ b/Penumbra/UI/Tabs/Debug/CrashDataExtensions.cs @@ -96,7 +96,7 @@ public static class CrashDataExtensions if (!table) return; - ImGuiClip.ClippedDraw(data.LastVfxFuncsInvoked, vfx => + ImGuiClip.ClippedDraw(data.LastVFXFuncsInvoked, vfx => { ImGuiUtil.DrawTableColumn(vfx.Age.ToString(CultureInfo.InvariantCulture)); ImGuiUtil.DrawTableColumn(vfx.ThreadId.ToString());