Improve DesignStorage slightly.

This commit is contained in:
Ottermandias 2024-01-25 15:56:49 +01:00
parent a284d5adc5
commit fce8b058b0
7 changed files with 48 additions and 56 deletions

View file

@ -1,7 +1,6 @@
using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Plugin; using Dalamud.Plugin;
using Glamourer.Designs; using Glamourer.Designs;
using Glamourer.Events;
using Glamourer.Interop.Structs; using Glamourer.Interop.Structs;
using Glamourer.State; using Glamourer.State;
using Penumbra.Api.Helpers; using Penumbra.Api.Helpers;
@ -138,5 +137,5 @@ public partial class GlamourerIpc
} }
private void ApplyDesignByGuid(Guid identifier, IEnumerable<ActorIdentifier> actors, uint lockCode) private void ApplyDesignByGuid(Guid identifier, IEnumerable<ActorIdentifier> actors, uint lockCode)
=> ApplyDesign(_designManager.Designs.FirstOrDefault(x => x.Identifier == identifier), actors, DesignConverter.Version, lockCode); => ApplyDesign(_designManager.Designs.ByIdentifier(identifier), actors, DesignConverter.Version, lockCode);
} }

View file

@ -480,8 +480,7 @@ public class AutoDesignManager : ISavable, IReadOnlyList<AutoDesignSet>, IDispos
return null; return null;
} }
design = _designs.Designs.FirstOrDefault(d => d.Identifier == guid); if (!_designs.Designs.TryGetValue(guid, out design))
if (design == null)
{ {
Glamourer.Messager.NotificationMessage( Glamourer.Messager.NotificationMessage(
$"Error parsing automatically applied design for set {setName}: The specified design {guid} does not exist.", $"Error parsing automatically applied design for set {setName}: The specified design {guid} does not exist.",

View file

@ -11,21 +11,10 @@ using OtterGui.Classes;
namespace Glamourer.Designs; namespace Glamourer.Designs;
public class DesignColorUi public class DesignColorUi(DesignColors colors, Configuration config)
{ {
private readonly DesignColors _colors;
private readonly DesignManager _designs;
private readonly Configuration _config;
private string _newName = string.Empty; private string _newName = string.Empty;
public DesignColorUi(DesignColors colors, DesignManager designs, Configuration config)
{
_colors = colors;
_designs = designs;
_config = config;
}
public void Draw() public void Draw()
{ {
using var table = ImRaii.Table("designColors", 3, ImGuiTableFlags.RowBg); using var table = ImRaii.Table("designColors", 3, ImGuiTableFlags.RowBg);
@ -44,7 +33,7 @@ public class DesignColorUi
ImGui.TableNextColumn(); ImGui.TableNextColumn();
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Recycle.ToIconString(), buttonSize, if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Recycle.ToIconString(), buttonSize,
"Revert the color used for missing design colors to its default.", _colors.MissingColor == DesignColors.MissingColorDefault, "Revert the color used for missing design colors to its default.", colors.MissingColor == DesignColors.MissingColorDefault,
true)) true))
{ {
changeString = DesignColors.MissingColorName; changeString = DesignColors.MissingColorName;
@ -52,7 +41,7 @@ public class DesignColorUi
} }
ImGui.TableNextColumn(); ImGui.TableNextColumn();
if (DrawColorButton(DesignColors.MissingColorName, _colors.MissingColor, out var newColor)) if (DrawColorButton(DesignColors.MissingColorName, colors.MissingColor, out var newColor))
{ {
changeString = DesignColors.MissingColorName; changeString = DesignColors.MissingColorName;
changeValue = newColor; changeValue = newColor;
@ -64,12 +53,12 @@ public class DesignColorUi
ImGuiUtil.HoverTooltip("This color is used when the color specified in a design is not available."); ImGuiUtil.HoverTooltip("This color is used when the color specified in a design is not available.");
var disabled = !_config.DeleteDesignModifier.IsActive(); var disabled = !config.DeleteDesignModifier.IsActive();
var tt = "Delete this color. This does not remove it from designs using it."; var tt = "Delete this color. This does not remove it from designs using it.";
if (disabled) if (disabled)
tt += $"\nHold {_config.DeleteDesignModifier} to delete."; tt += $"\nHold {config.DeleteDesignModifier} to delete.";
foreach (var ((name, color), idx) in _colors.WithIndex()) foreach (var ((name, color), idx) in colors.WithIndex())
{ {
using var id = ImRaii.PushId(idx); using var id = ImRaii.PushId(idx);
ImGui.TableNextColumn(); ImGui.TableNextColumn();
@ -97,7 +86,7 @@ public class DesignColorUi
? ("Specify a name for a new color first.", true) ? ("Specify a name for a new color first.", true)
: _newName is DesignColors.MissingColorName or DesignColors.AutomaticName : _newName is DesignColors.MissingColorName or DesignColors.AutomaticName
? ($"You can not use the name {DesignColors.MissingColorName} or {DesignColors.AutomaticName}, choose a different one.", true) ? ($"You can not use the name {DesignColors.MissingColorName} or {DesignColors.AutomaticName}, choose a different one.", true)
: _colors.ContainsKey(_newName) : colors.ContainsKey(_newName)
? ($"The color {_newName} already exists, please choose a different name.", true) ? ($"The color {_newName} already exists, please choose a different name.", true)
: ($"Add a new color {_newName} to your list.", false); : ($"Add a new color {_newName} to your list.", false);
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), buttonSize, tt, disabled, true)) if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Plus.ToIconString(), buttonSize, tt, disabled, true))
@ -119,9 +108,9 @@ public class DesignColorUi
if (changeString.Length > 0) if (changeString.Length > 0)
{ {
if (!changeValue.HasValue) if (!changeValue.HasValue)
_colors.DeleteColor(changeString); colors.DeleteColor(changeString);
else else
_colors.SetColor(changeString, changeValue.Value); colors.SetColor(changeString, changeValue.Value);
} }
} }

View file

@ -21,16 +21,14 @@ public class DesignManager
private readonly HumanModelList _humans; private readonly HumanModelList _humans;
private readonly SaveService _saveService; private readonly SaveService _saveService;
private readonly DesignChanged _event; private readonly DesignChanged _event;
private readonly DesignStorage _designs;
private readonly Dictionary<Guid, DesignData> _undoStore = []; private readonly Dictionary<Guid, DesignData> _undoStore = [];
public IReadOnlyList<Design> Designs public DesignStorage Designs { get; }
=> _designs;
public DesignManager(SaveService saveService, ItemManager items, CustomizeService customizations, public DesignManager(SaveService saveService, ItemManager items, CustomizeService customizations,
DesignChanged @event, HumanModelList humans, DesignStorage storage, DesignLinkLoader designLinkLoader, Configuration config) DesignChanged @event, HumanModelList humans, DesignStorage storage, DesignLinkLoader designLinkLoader, Configuration config)
{ {
_designs = storage; Designs = storage;
_config = config; _config = config;
_saveService = saveService; _saveService = saveService;
_items = items; _items = items;
@ -55,7 +53,7 @@ public class DesignManager
_items.ItemData.Awaiter.Wait(); _items.ItemData.Awaiter.Wait();
var stopwatch = Stopwatch.StartNew(); var stopwatch = Stopwatch.StartNew();
_designs.Clear(); Designs.Clear();
var skipped = 0; var skipped = 0;
ThreadLocal<List<(Design, string)>> designs = new(() => [], true); ThreadLocal<List<(Design, string)>> designs = new(() => [], true);
Parallel.ForEach(_saveService.FileNames.Designs(), (f, _) => Parallel.ForEach(_saveService.FileNames.Designs(), (f, _) =>
@ -79,15 +77,15 @@ public class DesignManager
{ {
if (design.Identifier.ToString() != Path.GetFileNameWithoutExtension(path)) if (design.Identifier.ToString() != Path.GetFileNameWithoutExtension(path))
invalidNames.Add((design, path)); invalidNames.Add((design, path));
if (_designs.Any(d => d.Identifier == design.Identifier)) if (Designs.Contains(design.Identifier))
{ {
Glamourer.Log.Error($"Could not load design, skipped: Identifier {design.Identifier} was not unique."); Glamourer.Log.Error($"Could not load design, skipped: Identifier {design.Identifier} was not unique.");
++skipped; ++skipped;
continue; continue;
} }
design.Index = _designs.Count; design.Index = Designs.Count;
_designs.Add(design); Designs.Add(design);
} }
var failed = MoveInvalidNames(invalidNames); var failed = MoveInvalidNames(invalidNames);
@ -96,7 +94,7 @@ public class DesignManager
$"Moved {invalidNames.Count - failed} designs to correct names.{(failed > 0 ? $" Failed to move {failed} designs to correct names." : string.Empty)}"); $"Moved {invalidNames.Count - failed} designs to correct names.{(failed > 0 ? $" Failed to move {failed} designs to correct names." : string.Empty)}");
Glamourer.Log.Information( Glamourer.Log.Information(
$"Loaded {_designs.Count} designs in {stopwatch.ElapsedMilliseconds} ms.{(skipped > 0 ? $" Skipped loading {skipped} designs due to errors." : string.Empty)}"); $"Loaded {Designs.Count} designs in {stopwatch.ElapsedMilliseconds} ms.{(skipped > 0 ? $" Skipped loading {skipped} designs due to errors." : string.Empty)}");
_event.Invoke(DesignChanged.Type.ReloadedAll, null!, null); _event.Invoke(DesignChanged.Type.ReloadedAll, null!, null);
} }
@ -118,9 +116,9 @@ public class DesignManager
LastEdit = DateTimeOffset.UtcNow, LastEdit = DateTimeOffset.UtcNow,
Identifier = CreateNewGuid(), Identifier = CreateNewGuid(),
Name = actualName, Name = actualName,
Index = _designs.Count, Index = Designs.Count,
}; };
_designs.Add(design); Designs.Add(design);
Glamourer.Log.Debug($"Added new design {design.Identifier}."); Glamourer.Log.Debug($"Added new design {design.Identifier}.");
_saveService.ImmediateSave(design); _saveService.ImmediateSave(design);
_event.Invoke(DesignChanged.Type.Created, design, path); _event.Invoke(DesignChanged.Type.Created, design, path);
@ -137,10 +135,10 @@ public class DesignManager
LastEdit = DateTimeOffset.UtcNow, LastEdit = DateTimeOffset.UtcNow,
Identifier = CreateNewGuid(), Identifier = CreateNewGuid(),
Name = actualName, Name = actualName,
Index = _designs.Count, Index = Designs.Count,
}; };
_designs.Add(design); Designs.Add(design);
Glamourer.Log.Debug($"Added new design {design.Identifier} by cloning Temporary Design."); Glamourer.Log.Debug($"Added new design {design.Identifier} by cloning Temporary Design.");
_saveService.ImmediateSave(design); _saveService.ImmediateSave(design);
_event.Invoke(DesignChanged.Type.Created, design, path); _event.Invoke(DesignChanged.Type.Created, design, path);
@ -157,9 +155,9 @@ public class DesignManager
LastEdit = DateTimeOffset.UtcNow, LastEdit = DateTimeOffset.UtcNow,
Identifier = CreateNewGuid(), Identifier = CreateNewGuid(),
Name = actualName, Name = actualName,
Index = _designs.Count, Index = Designs.Count,
}; };
_designs.Add(design); Designs.Add(design);
Glamourer.Log.Debug( Glamourer.Log.Debug(
$"Added new design {design.Identifier} by cloning {clone.Identifier.ToString()}."); $"Added new design {design.Identifier} by cloning {clone.Identifier.ToString()}.");
_saveService.ImmediateSave(design); _saveService.ImmediateSave(design);
@ -170,9 +168,9 @@ public class DesignManager
/// <summary> Delete a design. </summary> /// <summary> Delete a design. </summary>
public void Delete(Design design) public void Delete(Design design)
{ {
foreach (var d in _designs.Skip(design.Index + 1)) foreach (var d in Designs.Skip(design.Index + 1))
--d.Index; --d.Index;
_designs.RemoveAt(design.Index); Designs.RemoveAt(design.Index);
_saveService.ImmediateDelete(design); _saveService.ImmediateDelete(design);
_event.Invoke(DesignChanged.Type.Deleted, design, null); _event.Invoke(DesignChanged.Type.Deleted, design, null);
} }
@ -591,7 +589,7 @@ public class DesignManager
var errors = 0; var errors = 0;
var skips = 0; var skips = 0;
var successes = 0; var successes = 0;
var oldDesigns = _designs.ToList(); var oldDesigns = Designs.ToList();
try try
{ {
var text = File.ReadAllText(_saveService.FileNames.MigrationDesignFile); var text = File.ReadAllText(_saveService.FileNames.MigrationDesignFile);
@ -697,7 +695,7 @@ public class DesignManager
while (true) while (true)
{ {
var guid = Guid.NewGuid(); var guid = Guid.NewGuid();
if (_designs.All(d => d.Identifier != guid)) if (!Designs.Contains(guid))
return guid; return guid;
} }
} }
@ -709,11 +707,11 @@ public class DesignManager
/// </summary> /// </summary>
private bool Add(Design design, string? message) private bool Add(Design design, string? message)
{ {
if (_designs.Any(d => d == design || d.Identifier == design.Identifier)) if (Designs.Any(d => d == design || d.Identifier == design.Identifier))
return false; return false;
design.Index = _designs.Count; design.Index = Designs.Count;
_designs.Add(design); Designs.Add(design);
if (!message.IsNullOrEmpty()) if (!message.IsNullOrEmpty())
Glamourer.Log.Debug(message); Glamourer.Log.Debug(message);
_saveService.ImmediateSave(design); _saveService.ImmediateSave(design);
@ -740,7 +738,8 @@ public class DesignManager
} }
/// <summary> Change a mainhand weapon and either fix or apply appropriate offhand and potentially gauntlets. </summary> /// <summary> Change a mainhand weapon and either fix or apply appropriate offhand and potentially gauntlets. </summary>
private bool ChangeMainhandPeriphery(Design design, EquipItem currentMain, EquipItem currentOff, EquipItem newMain, out EquipItem? newOff, out EquipItem? newGauntlets) private bool ChangeMainhandPeriphery(Design design, EquipItem currentMain, EquipItem currentOff, EquipItem newMain, out EquipItem? newOff,
out EquipItem? newGauntlets)
{ {
newOff = null; newOff = null;
newGauntlets = null; newGauntlets = null;

View file

@ -3,4 +3,16 @@
namespace Glamourer.Designs; namespace Glamourer.Designs;
public class DesignStorage : List<Design>, IService public class DesignStorage : List<Design>, IService
{} {
public bool TryGetValue(Guid identifier, [NotNullWhen(true)] out Design? design)
{
design = ByIdentifier(identifier);
return design != null;
}
public Design? ByIdentifier(Guid identifier)
=> this.FirstOrDefault(d => d.Identifier == identifier);
public bool Contains(Guid identifier)
=> ByIdentifier(identifier) != null;
}

View file

@ -587,7 +587,7 @@ public class CommandService : IDisposable
if (Guid.TryParse(argument, out var guid)) if (Guid.TryParse(argument, out var guid))
{ {
design = _designManager.Designs.FirstOrDefault(d => d.Identifier == guid); design = _designManager.Designs.ByIdentifier(guid);
} }
else else
{ {

View file

@ -1,6 +0,0 @@
namespace Glamourer.Services
{
internal interface IGamePathParser
{
}
}