Fix issue with crash handler and collections not saving on rename.

This commit is contained in:
Ottermandias 2024-06-03 17:45:22 +02:00
parent b63935e81e
commit 63b3a02e95
9 changed files with 52 additions and 59 deletions

@ -1 +1 @@
Subproject commit becacbca4f35595d16ff40dc9639cfa24be3461f Subproject commit 5de708b27ed45c9cdead71742c7061ad9ce64323

View file

@ -55,7 +55,7 @@ public class CrashData
/// <summary> The last vfx function invoked before this crash data was generated. </summary> /// <summary> The last vfx function invoked before this crash data was generated. </summary>
public VfxFuncInvokedEntry? LastVfxFuncInvoked public VfxFuncInvokedEntry? LastVfxFuncInvoked
=> LastVfxFuncsInvoked.Count == 0 ? default : LastVfxFuncsInvoked[0]; => LastVFXFuncsInvoked.Count == 0 ? default : LastVFXFuncsInvoked[0];
/// <summary> A collection of the last few characters loaded before this crash data was generated. </summary> /// <summary> A collection of the last few characters loaded before this crash data was generated. </summary>
public List<CharacterLoadedEntry> LastCharactersLoaded { get; set; } = []; public List<CharacterLoadedEntry> LastCharactersLoaded { get; set; } = [];
@ -64,5 +64,5 @@ public class CrashData
public List<ModdedFileLoadedEntry> LastModdedFilesLoaded { get; set; } = []; public List<ModdedFileLoadedEntry> LastModdedFilesLoaded { get; set; } = [];
/// <summary> A collection of the last few vfx functions invoked before this crash data was generated. </summary> /// <summary> A collection of the last few vfx functions invoked before this crash data was generated. </summary>
public List<VfxFuncInvokedEntry> LastVfxFuncsInvoked { get; set; } = []; public List<VfxFuncInvokedEntry> LastVFXFuncsInvoked { get; set; } = [];
} }

View file

@ -181,6 +181,7 @@ public class CollectionStorage : IReadOnlyList<ModCollection>, IDisposable
return false; return false;
} }
Delete(collection);
_saveService.ImmediateDelete(new ModCollectionSave(_modStorage, collection)); _saveService.ImmediateDelete(new ModCollectionSave(_modStorage, collection));
_collections.RemoveAt(collection.Index); _collections.RemoveAt(collection.Index);
// Update indices. // Update indices.

View file

@ -24,7 +24,7 @@ public sealed class ModSettingChanged()
{ {
public enum Priority public enum Priority
{ {
/// <seealso cref="PenumbraApi.OnModSettingChange"/> /// <seealso cref="ModSettingsApi.OnModSettingChange"/>
Api = int.MinValue, Api = int.MinValue,
/// <seealso cref="Collections.Cache.CollectionCacheManager.OnModSettingChange"/> /// <seealso cref="Collections.Cache.CollectionCacheManager.OnModSettingChange"/>

View file

@ -287,7 +287,7 @@ public sealed class CrashHandlerService : IDisposable, IService
try 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; return;
var name = GetActorName(resolveData.AssociatedGameObject); var name = GetActorName(resolveData.AssociatedGameObject);

View file

@ -20,19 +20,23 @@ using Penumbra.UI.Classes;
namespace Penumbra.UI.CollectionTab; 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 CollectionStorage _collections = manager.Storage;
private readonly ActiveCollections _active; private readonly ActiveCollections _active = manager.Active;
private readonly CollectionSelector _selector; private readonly IndividualAssignmentUi _individualAssignmentUi = new(communicator, actors, manager);
private readonly ActorManager _actors; private readonly InheritanceUi _inheritanceUi = new(manager, incognito);
private readonly ITargetManager _targets; private readonly IFontHandle _nameFont = pi.UiBuilder.FontAtlas.NewGameFontHandle(new GameFontStyle(GameFontFamilyAndSize.Jupiter23));
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 static readonly IReadOnlyDictionary<CollectionType, (string Name, uint Border)> Buttons = CreateButtons(); private static readonly IReadOnlyDictionary<CollectionType, (string Name, uint Border)> Buttons = CreateButtons();
private static readonly IReadOnlyList<(CollectionType, bool, bool, string, uint)> AdvancedTree = CreateTree(); private static readonly IReadOnlyList<(CollectionType, bool, bool, string, uint)> AdvancedTree = CreateTree();
@ -41,23 +45,6 @@ public sealed class CollectionPanel : IDisposable
private int _draggedIndividualAssignment = -1; 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() public void Dispose()
{ {
_individualAssignmentUi.Dispose(); _individualAssignmentUi.Dispose();
@ -237,17 +224,22 @@ public sealed class CollectionPanel : IDisposable
var name = _newName ?? collection.Name; var name = _newName ?? collection.Name;
var identifier = collection.Identifier; var identifier = collection.Identifier;
var width = ImGui.GetContentRegionAvail().X; var width = ImGui.GetContentRegionAvail().X;
var fileName = _fileNames.CollectionFile(collection); var fileName = saveService.FileNames.CollectionFile(collection);
ImGui.SetNextItemWidth(width); ImGui.SetNextItemWidth(width);
if (ImGui.InputText("##name", ref name, 128)) if (ImGui.InputText("##name", ref name, 128))
_newName = name; _newName = name;
if (ImGui.IsItemDeactivatedAfterEdit() && _newName != null) if (ImGui.IsItemDeactivatedAfterEdit() && _newName != null && _newName != collection.Name)
{ {
collection.Name = _newName; collection.Name = _newName;
saveService.QueueSave(new ModCollectionSave(mods, collection));
selector.RestoreCollections();
_newName = null; _newName = null;
} }
else if (ImGui.IsItemDeactivated()) else if (ImGui.IsItemDeactivated())
{
_newName = null; _newName = null;
}
using (ImRaii.PushFont(UiBuilder.MonoFont)) using (ImRaii.PushFont(UiBuilder.MonoFont))
{ {
if (ImGui.Button(collection.Identifier, new Vector2(width, 0))) if (ImGui.Button(collection.Identifier, new Vector2(width, 0)))
@ -329,7 +321,7 @@ public sealed class CollectionPanel : IDisposable
DrawIndividualDragTarget(text, id); DrawIndividualDragTarget(text, id);
if (!invalid) if (!invalid)
{ {
_selector.DragTargetAssignment(type, id); selector.DragTargetAssignment(type, id);
var name = Name(collection); var name = Name(collection);
var size = ImGui.CalcTextSize(name); var size = ImGui.CalcTextSize(name);
var textPos = ImGui.GetItemRectMax() - size - ImGui.GetStyle().FramePadding; var textPos = ImGui.GetItemRectMax() - size - ImGui.GetStyle().FramePadding;
@ -418,7 +410,7 @@ public sealed class CollectionPanel : IDisposable
/// <summary> Respect incognito mode for names of identifiers. </summary> /// <summary> Respect incognito mode for names of identifiers. </summary>
private string Name(ActorIdentifier id, string? name) 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) ? id.Incognito(name)
: name ?? id.ToString(); : name ?? id.ToString();
@ -426,7 +418,7 @@ public sealed class CollectionPanel : IDisposable
private string Name(ModCollection? collection) private string Name(ModCollection? collection)
=> collection == null ? "Unassigned" : => collection == null ? "Unassigned" :
collection == ModCollection.Empty ? "Use No Mods" : 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) 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) 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) private void DrawCurrentTarget(Vector2 width)
=> DrawIndividualButton("Current Target", width, string.Empty, 't', => 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) private void DrawNewPlayer(Vector2 width)
=> DrawIndividualButton("New Player", width, _individualAssignmentUi.PlayerTooltip, 'p', => 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("State", ImGuiTableColumnFlags.WidthFixed, 1.75f * ImGui.GetFrameHeight());
ImGui.TableSetupColumn("Priority", ImGuiTableColumnFlags.WidthFixed, 2.5f * ImGui.GetFrameHeight()); ImGui.TableSetupColumn("Priority", ImGuiTableColumnFlags.WidthFixed, 2.5f * ImGui.GetFrameHeight());
ImGui.TableHeadersRow(); 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) .Where(t => t.Item2.Settings != null)
.OrderBy(t => t.m.Name)) .OrderBy(t => t.m.Name))
{ {

View file

@ -44,7 +44,9 @@ public sealed class CollectionSelector : ItemSelector<ModCollection>, IDisposabl
if (idx < 0 || idx >= Items.Count) if (idx < 0 || idx >= Items.Count)
return false; 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() protected override bool DeleteButtonEnabled()
@ -111,6 +113,15 @@ public sealed class CollectionSelector : ItemSelector<ModCollection>, IDisposabl
private string Name(ModCollection collection) private string Name(ModCollection collection)
=> _incognito.IncognitoMode || collection.Name.Length == 0 ? collection.AnonymizedName : collection.Name; => _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) private void OnCollectionChange(CollectionType type, ModCollection? old, ModCollection? @new, string _3)
{ {
switch (type) switch (type)
@ -122,14 +133,7 @@ public sealed class CollectionSelector : ItemSelector<ModCollection>, IDisposabl
SetFilterDirty(); SetFilterDirty();
return; return;
case CollectionType.Inactive: case CollectionType.Inactive:
Items.Clear(); RestoreCollections();
foreach (var c in _storage.OrderBy(c => c.Name))
Items.Add(c);
if (old == Current)
ClearCurrentSelection();
else
TryRestoreCurrent();
SetFilterDirty(); SetFilterDirty();
return; return;
default: default:

View file

@ -1,16 +1,12 @@
using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState.Objects;
using Dalamud.Interface;
using Dalamud.Interface.Utility;
using Dalamud.Plugin; using Dalamud.Plugin;
using ImGuiNET; using ImGuiNET;
using OtterGui;
using OtterGui.Raii; using OtterGui.Raii;
using OtterGui.Widgets; using OtterGui.Widgets;
using Penumbra.Collections.Manager; using Penumbra.Collections.Manager;
using Penumbra.GameData.Actors; using Penumbra.GameData.Actors;
using Penumbra.Mods.Manager; using Penumbra.Mods.Manager;
using Penumbra.Services; using Penumbra.Services;
using Penumbra.UI.Classes;
using Penumbra.UI.CollectionTab; using Penumbra.UI.CollectionTab;
namespace Penumbra.UI.Tabs; namespace Penumbra.UI.Tabs;
@ -42,13 +38,13 @@ public sealed class CollectionsTab : IDisposable, ITab
} }
public CollectionsTab(DalamudPluginInterface pi, Configuration configuration, CommunicatorService communicator, IncognitoService incognito, 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; _config = configuration.Ephemeral;
_tutorial = tutorial; _tutorial = tutorial;
_incognito = incognito; _incognito = incognito;
_selector = new CollectionSelector(configuration, communicator, collectionManager.Storage, collectionManager.Active, _tutorial, 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() public void Dispose()

View file

@ -96,7 +96,7 @@ public static class CrashDataExtensions
if (!table) if (!table)
return; return;
ImGuiClip.ClippedDraw(data.LastVfxFuncsInvoked, vfx => ImGuiClip.ClippedDraw(data.LastVFXFuncsInvoked, vfx =>
{ {
ImGuiUtil.DrawTableColumn(vfx.Age.ToString(CultureInfo.InvariantCulture)); ImGuiUtil.DrawTableColumn(vfx.Age.ToString(CultureInfo.InvariantCulture));
ImGuiUtil.DrawTableColumn(vfx.ThreadId.ToString()); ImGuiUtil.DrawTableColumn(vfx.ThreadId.ToString());