mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-01-03 06:13:45 +01:00
Start for Mod rework, currently not applied.
This commit is contained in:
parent
1861c40a4f
commit
5bfcb71f52
30 changed files with 1440 additions and 306 deletions
|
|
@ -206,14 +206,6 @@ public partial class ModCollection
|
|||
}
|
||||
}
|
||||
|
||||
private void ForceCacheUpdates()
|
||||
{
|
||||
foreach( var collection in this )
|
||||
{
|
||||
collection.ForceCacheUpdate( collection == Default );
|
||||
}
|
||||
}
|
||||
|
||||
// Recalculate effective files for active collections on events.
|
||||
private void OnModAddedActive( bool meta )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -56,21 +56,23 @@ public partial class ModCollection
|
|||
IEnumerator IEnumerable.GetEnumerator()
|
||||
=> GetEnumerator();
|
||||
|
||||
public Manager( Mods.Mod.Manager manager )
|
||||
public Manager( Mod.Manager manager )
|
||||
{
|
||||
_modManager = manager;
|
||||
|
||||
// The collection manager reacts to changes in mods by itself.
|
||||
_modManager.ModsRediscovered += OnModsRediscovered;
|
||||
_modManager.ModChange += OnModChanged;
|
||||
_modManager.ModDiscoveryStarted += OnModDiscoveryStarted;
|
||||
_modManager.ModDiscoveryFinished += OnModDiscoveryFinished;
|
||||
_modManager.ModChange += OnModChanged;
|
||||
ReadCollections();
|
||||
LoadCollections();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_modManager.ModsRediscovered -= OnModsRediscovered;
|
||||
_modManager.ModChange -= OnModChanged;
|
||||
_modManager.ModDiscoveryStarted -= OnModDiscoveryStarted;
|
||||
_modManager.ModDiscoveryFinished -= OnModDiscoveryFinished;
|
||||
_modManager.ModChange -= OnModChanged;
|
||||
}
|
||||
|
||||
// Add a new collection of the given name.
|
||||
|
|
@ -144,12 +146,27 @@ public partial class ModCollection
|
|||
public bool RemoveCollection( ModCollection collection )
|
||||
=> RemoveCollection( collection.Index );
|
||||
|
||||
|
||||
private void OnModsRediscovered()
|
||||
private void OnModDiscoveryStarted()
|
||||
{
|
||||
// When mods are rediscovered, force all cache updates and set the files of the default collection.
|
||||
ForceCacheUpdates();
|
||||
Default.SetFiles();
|
||||
foreach( var collection in this )
|
||||
{
|
||||
collection.PrepareModDiscovery();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnModDiscoveryFinished()
|
||||
{
|
||||
// First, re-apply all mod settings.
|
||||
foreach( var collection in this )
|
||||
{
|
||||
collection.ApplyModSettings();
|
||||
}
|
||||
|
||||
// Afterwards, we update the caches. This can not happen in the same loop due to inheritance.
|
||||
foreach( var collection in this )
|
||||
{
|
||||
collection.ForceCacheUpdate( collection == Default );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -209,8 +226,7 @@ public partial class ModCollection
|
|||
|
||||
// Inheritances can not be setup before all collections are read,
|
||||
// so this happens after reading the collections.
|
||||
// During this iteration, we can also fix all settings that are not valid for the given mod anymore.
|
||||
private void ApplyInheritancesAndFixSettings( IEnumerable< IReadOnlyList< string > > inheritances )
|
||||
private void ApplyInheritances( IEnumerable< IReadOnlyList< string > > inheritances )
|
||||
{
|
||||
foreach( var (collection, inheritance) in this.Zip( inheritances ) )
|
||||
{
|
||||
|
|
@ -229,11 +245,6 @@ public partial class ModCollection
|
|||
}
|
||||
}
|
||||
|
||||
foreach( var (setting, mod) in collection.Settings.Zip( _modManager.Mods ).Where( s => s.First != null ) )
|
||||
{
|
||||
changes |= setting!.FixInvalidSettings( mod.Meta );
|
||||
}
|
||||
|
||||
if( changes )
|
||||
{
|
||||
collection.Save();
|
||||
|
|
@ -277,7 +288,7 @@ public partial class ModCollection
|
|||
}
|
||||
|
||||
AddDefaultCollection();
|
||||
ApplyInheritancesAndFixSettings( inheritances );
|
||||
ApplyInheritances( inheritances );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -74,7 +74,7 @@ public partial class ModCollection
|
|||
|
||||
// Update the effective file list for the given cache.
|
||||
// Creates a cache if necessary.
|
||||
public void CalculateEffectiveFileList( bool withMetaManipulations, bool reloadResident )
|
||||
public void CalculateEffectiveFileList( bool withMetaManipulations, bool reloadDefault )
|
||||
{
|
||||
// Skip the empty collection.
|
||||
if( Index == 0 )
|
||||
|
|
@ -82,15 +82,20 @@ public partial class ModCollection
|
|||
return;
|
||||
}
|
||||
|
||||
PluginLog.Debug( "Recalculating effective file list for {CollectionName} [{WithMetaManipulations}]", Name, withMetaManipulations );
|
||||
PluginLog.Debug( "Recalculating effective file list for {CollectionName} [{WithMetaManipulations}] [{ReloadDefault}]", Name,
|
||||
withMetaManipulations, reloadDefault );
|
||||
_cache ??= new Cache( this );
|
||||
_cache.CalculateEffectiveFileList();
|
||||
if( withMetaManipulations )
|
||||
{
|
||||
_cache.UpdateMetaManipulations();
|
||||
if( reloadDefault )
|
||||
{
|
||||
SetFiles();
|
||||
}
|
||||
}
|
||||
|
||||
if( reloadResident )
|
||||
if( reloadDefault )
|
||||
{
|
||||
Penumbra.ResidentResources.Reload();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Penumbra.Mods;
|
||||
|
||||
namespace Penumbra.Collections;
|
||||
|
||||
public partial class ModCollection
|
||||
{
|
||||
// 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 );
|
||||
collection.Index = 0;
|
||||
collection._settings.Clear();
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
|
||||
// A ModCollection is a named set of ModSettings to all of the users' installed mods.
|
||||
// Settings to mods that are not installed anymore are kept as long as no call to CleanUnavailableSettings is made.
|
||||
// Invariants:
|
||||
|
|
@ -51,7 +39,6 @@ public partial class ModCollection
|
|||
// Settings for deleted mods will be kept via directory name.
|
||||
private readonly Dictionary< string, ModSettings > _unusedSettings;
|
||||
|
||||
|
||||
// Constructor for duplication.
|
||||
private ModCollection( string name, ModCollection duplicate )
|
||||
{
|
||||
|
|
@ -70,16 +57,9 @@ public partial class ModCollection
|
|||
Name = name;
|
||||
Version = version;
|
||||
_unusedSettings = allSettings;
|
||||
_settings = Enumerable.Repeat( ( ModSettings? )null, Penumbra.ModManager.Count ).ToList();
|
||||
for( var i = 0; i < Penumbra.ModManager.Count; ++i )
|
||||
{
|
||||
var modName = Penumbra.ModManager[ i ].BasePath.Name;
|
||||
if( _unusedSettings.TryGetValue( Penumbra.ModManager[ i ].BasePath.Name, out var settings ) )
|
||||
{
|
||||
_unusedSettings.Remove( modName );
|
||||
_settings[ i ] = settings;
|
||||
}
|
||||
}
|
||||
|
||||
_settings = new List< ModSettings? >();
|
||||
ApplyModSettings();
|
||||
|
||||
Migration.Migrate( this );
|
||||
ModSettingChanged += SaveOnChange;
|
||||
|
|
@ -106,7 +86,7 @@ public partial class ModCollection
|
|||
}
|
||||
|
||||
// Add settings for a new appended mod, by checking if the mod had settings from a previous deletion.
|
||||
private void AddMod( Mods.Mod mod )
|
||||
private void AddMod( Mod mod )
|
||||
{
|
||||
if( _unusedSettings.TryGetValue( mod.BasePath.Name, out var settings ) )
|
||||
{
|
||||
|
|
@ -120,7 +100,7 @@ public partial class ModCollection
|
|||
}
|
||||
|
||||
// Move settings from the current mod list to the unused mod settings.
|
||||
private void RemoveMod( Mods.Mod mod, int idx )
|
||||
private void RemoveMod( Mod mod, int idx )
|
||||
{
|
||||
var settings = _settings[ idx ];
|
||||
if( settings != null )
|
||||
|
|
@ -130,4 +110,51 @@ public partial class ModCollection
|
|||
|
||||
_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 );
|
||||
collection.Index = 0;
|
||||
collection._settings.Clear();
|
||||
return collection;
|
||||
}
|
||||
|
||||
// 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.BasePath.Name ] = setting!;
|
||||
}
|
||||
|
||||
_settings.Clear();
|
||||
}
|
||||
|
||||
// Apply all mod settings from unused settings to the current set of mods.
|
||||
// Also fixes invalid settings.
|
||||
private void ApplyModSettings()
|
||||
{
|
||||
_settings.Capacity = Math.Max( _settings.Capacity, Penumbra.ModManager.Count );
|
||||
var changes = false;
|
||||
foreach( var mod in Penumbra.ModManager )
|
||||
{
|
||||
if( _unusedSettings.TryGetValue( mod.BasePath.Name, out var s ) )
|
||||
{
|
||||
changes |= s.FixInvalidSettings( mod.Meta );
|
||||
_settings.Add( s );
|
||||
_unusedSettings.Remove( mod.BasePath.Name );
|
||||
}
|
||||
else
|
||||
{
|
||||
_settings.Add( null );
|
||||
}
|
||||
}
|
||||
|
||||
if( changes )
|
||||
{
|
||||
Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue