mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-02-20 06:47:46 +01:00
Everything's a service.
This commit is contained in:
parent
2670ba52c1
commit
dd8c910597
45 changed files with 2155 additions and 2212 deletions
|
|
@ -4,6 +4,8 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OtterGui;
|
||||
using OtterGui.Classes;
|
||||
using Penumbra.Services;
|
||||
|
||||
namespace Penumbra.Collections;
|
||||
|
||||
|
|
@ -27,16 +29,16 @@ public partial class ModCollection
|
|||
|
||||
// Get the first two letters of a collection name and its Index (or None if it is the empty collection).
|
||||
public string AnonymizedName
|
||||
=> this == Empty ? Empty.Name : Name.Length > 2 ? $"{Name[ ..2 ]}... ({Index})" : $"{Name} ({Index})";
|
||||
=> this == Empty ? Empty.Name : Name.Length > 2 ? $"{Name[..2]}... ({Index})" : $"{Name} ({Index})";
|
||||
|
||||
public int Version { get; private set; }
|
||||
public int Index { get; private set; } = -1;
|
||||
public int Index { get; private set; } = -1;
|
||||
|
||||
// If a ModSetting is null, it can be inherited from other collections.
|
||||
// If no collection provides a setting for the mod, it is just disabled.
|
||||
private readonly List< ModSettings? > _settings;
|
||||
private readonly List<ModSettings?> _settings;
|
||||
|
||||
public IReadOnlyList< ModSettings? > Settings
|
||||
public IReadOnlyList<ModSettings?> Settings
|
||||
=> _settings;
|
||||
|
||||
// Returns whether there are settings not in use by any current mod.
|
||||
|
|
@ -47,107 +49,103 @@ public partial class ModCollection
|
|||
=> _unusedSettings.Count;
|
||||
|
||||
// Evaluates the settings along the whole inheritance tree.
|
||||
public IEnumerable< ModSettings? > ActualSettings
|
||||
=> Enumerable.Range( 0, _settings.Count ).Select( i => this[ i ].Settings );
|
||||
public IEnumerable<ModSettings?> ActualSettings
|
||||
=> Enumerable.Range(0, _settings.Count).Select(i => this[i].Settings);
|
||||
|
||||
// Settings for deleted mods will be kept via directory name.
|
||||
private readonly Dictionary< string, ModSettings.SavedSettings > _unusedSettings;
|
||||
private readonly Dictionary<string, ModSettings.SavedSettings> _unusedSettings;
|
||||
|
||||
// Constructor for duplication.
|
||||
private ModCollection( string name, ModCollection duplicate )
|
||||
private ModCollection(string name, ModCollection duplicate)
|
||||
{
|
||||
Name = name;
|
||||
Version = duplicate.Version;
|
||||
_settings = duplicate._settings.ConvertAll( s => s?.DeepCopy() );
|
||||
_unusedSettings = duplicate._unusedSettings.ToDictionary( kvp => kvp.Key, kvp => kvp.Value.DeepCopy() );
|
||||
_settings = duplicate._settings.ConvertAll(s => s?.DeepCopy());
|
||||
_unusedSettings = duplicate._unusedSettings.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.DeepCopy());
|
||||
_inheritance = duplicate._inheritance.ToList();
|
||||
ModSettingChanged += SaveOnChange;
|
||||
InheritanceChanged += SaveOnChange;
|
||||
}
|
||||
|
||||
// Constructor for reading from files.
|
||||
private ModCollection( string name, int version, Dictionary< string, ModSettings.SavedSettings > allSettings )
|
||||
private ModCollection(string name, int version, Dictionary<string, ModSettings.SavedSettings> allSettings)
|
||||
{
|
||||
Name = name;
|
||||
Version = version;
|
||||
_unusedSettings = allSettings;
|
||||
|
||||
_settings = new List< ModSettings? >();
|
||||
_settings = new List<ModSettings?>();
|
||||
ApplyModSettings();
|
||||
|
||||
Migration.Migrate( this );
|
||||
Migration.Migrate(Penumbra.SaveService, this);
|
||||
ModSettingChanged += SaveOnChange;
|
||||
InheritanceChanged += SaveOnChange;
|
||||
}
|
||||
|
||||
// Create a new, unique empty collection of a given name.
|
||||
public static ModCollection CreateNewEmpty( string name )
|
||||
=> new(name, CurrentVersion, new Dictionary< string, ModSettings.SavedSettings >());
|
||||
public static ModCollection CreateNewEmpty(string name)
|
||||
=> new(name, CurrentVersion, new Dictionary<string, ModSettings.SavedSettings>());
|
||||
|
||||
// Create a new temporary collection that does not save and has a negative index.
|
||||
public static ModCollection CreateNewTemporary( string name, int changeCounter )
|
||||
public static ModCollection CreateNewTemporary(string name, int changeCounter)
|
||||
{
|
||||
var collection = new ModCollection( name, Empty );
|
||||
var collection = new ModCollection(name, Empty);
|
||||
collection.ModSettingChanged -= collection.SaveOnChange;
|
||||
collection.InheritanceChanged -= collection.SaveOnChange;
|
||||
collection.Index = ~Penumbra.TempCollections.Count;
|
||||
collection.ChangeCounter = changeCounter;
|
||||
collection.CreateCache();
|
||||
collection.CreateCache(false);
|
||||
return collection;
|
||||
}
|
||||
|
||||
// Duplicate the calling collection to a new, unique collection of a given name.
|
||||
public ModCollection Duplicate( string name )
|
||||
public ModCollection Duplicate(string name)
|
||||
=> new(name, this);
|
||||
|
||||
// Check if a name is valid to use for a collection.
|
||||
// Does not check for uniqueness.
|
||||
public static bool IsValidName( string name )
|
||||
=> name.Length > 0 && name.All( c => !c.IsInvalidAscii() && c is not '|' && !c.IsInvalidInPath() );
|
||||
public static bool IsValidName(string name)
|
||||
=> name.Length > 0 && name.All(c => !c.IsInvalidAscii() && c is not '|' && !c.IsInvalidInPath());
|
||||
|
||||
// Remove all settings for not currently-installed mods.
|
||||
public void CleanUnavailableSettings()
|
||||
{
|
||||
var any = _unusedSettings.Count > 0;
|
||||
_unusedSettings.Clear();
|
||||
if( any )
|
||||
{
|
||||
Save();
|
||||
}
|
||||
if (any)
|
||||
Penumbra.SaveService.QueueSave(this);
|
||||
}
|
||||
|
||||
// Add settings for a new appended mod, by checking if the mod had settings from a previous deletion.
|
||||
private bool AddMod( Mod mod )
|
||||
private bool AddMod(Mod mod)
|
||||
{
|
||||
if( _unusedSettings.TryGetValue( mod.ModPath.Name, out var save ) )
|
||||
if (_unusedSettings.TryGetValue(mod.ModPath.Name, out var save))
|
||||
{
|
||||
var ret = save.ToSettings( mod, out var settings );
|
||||
_settings.Add( settings );
|
||||
_unusedSettings.Remove( mod.ModPath.Name );
|
||||
var ret = save.ToSettings(mod, out var settings);
|
||||
_settings.Add(settings);
|
||||
_unusedSettings.Remove(mod.ModPath.Name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
_settings.Add( null );
|
||||
_settings.Add(null);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Move settings from the current mod list to the unused mod settings.
|
||||
private void RemoveMod( Mod mod, int idx )
|
||||
private void RemoveMod(Mod mod, int idx)
|
||||
{
|
||||
var settings = _settings[ idx ];
|
||||
if( settings != null )
|
||||
{
|
||||
_unusedSettings[ mod.ModPath.Name ] = new ModSettings.SavedSettings( settings, mod );
|
||||
}
|
||||
var settings = _settings[idx];
|
||||
if (settings != null)
|
||||
_unusedSettings[mod.ModPath.Name] = new ModSettings.SavedSettings(settings, mod);
|
||||
|
||||
_settings.RemoveAt( idx );
|
||||
_settings.RemoveAt(idx);
|
||||
}
|
||||
|
||||
// Create the always available Empty Collection that will always sit at index 0,
|
||||
// can not be deleted and does never create a cache.
|
||||
private static ModCollection CreateEmpty()
|
||||
{
|
||||
var collection = CreateNewEmpty( EmptyCollection );
|
||||
var collection = CreateNewEmpty(EmptyCollection);
|
||||
collection.Index = 0;
|
||||
collection._settings.Clear();
|
||||
return collection;
|
||||
|
|
@ -156,10 +154,8 @@ public partial class ModCollection
|
|||
// Move all settings to unused settings for rediscovery.
|
||||
private void PrepareModDiscovery()
|
||||
{
|
||||
foreach( var (mod, setting) in Penumbra.ModManager.Zip( _settings ).Where( s => s.Second != null ) )
|
||||
{
|
||||
_unusedSettings[ mod.ModPath.Name ] = new ModSettings.SavedSettings( setting!, mod );
|
||||
}
|
||||
foreach (var (mod, setting) in Penumbra.ModManager.Zip(_settings).Where(s => s.Second != null))
|
||||
_unusedSettings[mod.ModPath.Name] = new ModSettings.SavedSettings(setting!, mod);
|
||||
|
||||
_settings.Clear();
|
||||
}
|
||||
|
|
@ -168,50 +164,44 @@ public partial class ModCollection
|
|||
// Also fixes invalid settings.
|
||||
private void ApplyModSettings()
|
||||
{
|
||||
_settings.Capacity = Math.Max( _settings.Capacity, Penumbra.ModManager.Count );
|
||||
if( Penumbra.ModManager.Aggregate( false, ( current, mod ) => current | AddMod( mod ) ) )
|
||||
{
|
||||
Save();
|
||||
}
|
||||
_settings.Capacity = Math.Max(_settings.Capacity, Penumbra.ModManager.Count);
|
||||
if (Penumbra.ModManager.Aggregate(false, (current, mod) => current | AddMod(mod)))
|
||||
Penumbra.SaveService.ImmediateSave(this);
|
||||
}
|
||||
|
||||
public bool CopyModSettings( int modIdx, string modName, int targetIdx, string targetName )
|
||||
public bool CopyModSettings(int modIdx, string modName, int targetIdx, string targetName)
|
||||
{
|
||||
if( targetName.Length == 0 && targetIdx < 0 || modName.Length == 0 && modIdx < 0 )
|
||||
{
|
||||
if (targetName.Length == 0 && targetIdx < 0 || modName.Length == 0 && modIdx < 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the source mod exists, convert its settings to saved settings or null if its inheriting.
|
||||
// If it does not exist, check unused settings.
|
||||
// If it does not exist and has no unused settings, also use null.
|
||||
ModSettings.SavedSettings? savedSettings = modIdx >= 0
|
||||
? _settings[ modIdx ] != null
|
||||
? new ModSettings.SavedSettings( _settings[ modIdx ]!, Penumbra.ModManager[ modIdx ] )
|
||||
? _settings[modIdx] != null
|
||||
? new ModSettings.SavedSettings(_settings[modIdx]!, Penumbra.ModManager[modIdx])
|
||||
: null
|
||||
: _unusedSettings.TryGetValue( modName, out var s )
|
||||
: _unusedSettings.TryGetValue(modName, out var s)
|
||||
? s
|
||||
: null;
|
||||
|
||||
if( targetIdx >= 0 )
|
||||
if (targetIdx >= 0)
|
||||
{
|
||||
if( savedSettings != null )
|
||||
if (savedSettings != null)
|
||||
{
|
||||
// The target mod exists and the source settings are not inheriting, convert and fix the settings and copy them.
|
||||
// This triggers multiple events.
|
||||
savedSettings.Value.ToSettings( Penumbra.ModManager[ targetIdx ], out var settings );
|
||||
SetModState( targetIdx, settings.Enabled );
|
||||
SetModPriority( targetIdx, settings.Priority );
|
||||
foreach( var (value, index) in settings.Settings.WithIndex() )
|
||||
{
|
||||
SetModSetting( targetIdx, index, value );
|
||||
}
|
||||
savedSettings.Value.ToSettings(Penumbra.ModManager[targetIdx], out var settings);
|
||||
SetModState(targetIdx, settings.Enabled);
|
||||
SetModPriority(targetIdx, settings.Priority);
|
||||
foreach (var (value, index) in settings.Settings.WithIndex())
|
||||
SetModSetting(targetIdx, index, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The target mod exists, but the source is inheriting, set the target to inheriting.
|
||||
// This triggers events.
|
||||
SetModInheritance( targetIdx, true );
|
||||
SetModInheritance(targetIdx, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -219,14 +209,10 @@ public partial class ModCollection
|
|||
// The target mod does not exist.
|
||||
// Either copy the unused source settings directly if they are not inheriting,
|
||||
// or remove any unused settings for the target if they are inheriting.
|
||||
if( savedSettings != null )
|
||||
{
|
||||
_unusedSettings[ targetName ] = savedSettings.Value;
|
||||
}
|
||||
if (savedSettings != null)
|
||||
_unusedSettings[targetName] = savedSettings.Value;
|
||||
else
|
||||
{
|
||||
_unusedSettings.Remove( targetName );
|
||||
}
|
||||
_unusedSettings.Remove(targetName);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -234,4 +220,4 @@ public partial class ModCollection
|
|||
|
||||
public override string ToString()
|
||||
=> Name;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue