mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-01-03 06:13:45 +01:00
Lots of collection progress.
This commit is contained in:
parent
d908f22a17
commit
3f33bab296
22 changed files with 666 additions and 636 deletions
|
|
@ -6,6 +6,8 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Penumbra.Api;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Interop.Services;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Services;
|
||||
|
|
@ -16,6 +18,7 @@ public class CollectionCacheManager : IDisposable, IReadOnlyDictionary<ModCollec
|
|||
{
|
||||
private readonly ActiveCollections _active;
|
||||
private readonly CommunicatorService _communicator;
|
||||
private readonly CharacterUtility _characterUtility;
|
||||
|
||||
private readonly Dictionary<ModCollection, ModCollectionCache> _cache = new();
|
||||
|
||||
|
|
@ -46,17 +49,23 @@ public class CollectionCacheManager : IDisposable, IReadOnlyDictionary<ModCollec
|
|||
public IEnumerable<ModCollection> Active
|
||||
=> _cache.Keys.Where(c => c.Index > ModCollection.Empty.Index);
|
||||
|
||||
public CollectionCacheManager(ActiveCollections active, CommunicatorService communicator)
|
||||
public CollectionCacheManager(ActiveCollections active, CommunicatorService communicator, CharacterUtility characterUtility)
|
||||
{
|
||||
_active = active;
|
||||
_communicator = communicator;
|
||||
_active = active;
|
||||
_communicator = communicator;
|
||||
_characterUtility = characterUtility;
|
||||
|
||||
_communicator.CollectionChange.Subscribe(OnCollectionChange);
|
||||
_communicator.ModPathChanged.Subscribe(OnModChangeAddition, -100);
|
||||
_communicator.ModPathChanged.Subscribe(OnModChangeRemoval, 100);
|
||||
_communicator.TemporaryGlobalModChange.Subscribe(OnGlobalModChange);
|
||||
_communicator.ModOptionChanged.Subscribe(OnModOptionChange, -100);
|
||||
_communicator.ModSettingChanged.Subscribe(OnModSettingChange);
|
||||
_communicator.CollectionInheritanceChanged.Subscribe(OnCollectionInheritanceChange);
|
||||
CreateNecessaryCaches();
|
||||
|
||||
if (!_characterUtility.Ready)
|
||||
_characterUtility.LoadingFinished += IncrementCounters;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
@ -66,6 +75,9 @@ public class CollectionCacheManager : IDisposable, IReadOnlyDictionary<ModCollec
|
|||
_communicator.ModPathChanged.Unsubscribe(OnModChangeRemoval);
|
||||
_communicator.TemporaryGlobalModChange.Unsubscribe(OnGlobalModChange);
|
||||
_communicator.ModOptionChanged.Unsubscribe(OnModOptionChange);
|
||||
_communicator.ModSettingChanged.Unsubscribe(OnModSettingChange);
|
||||
_communicator.CollectionInheritanceChanged.Unsubscribe(OnCollectionInheritanceChange);
|
||||
_characterUtility.LoadingFinished -= IncrementCounters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -170,4 +182,57 @@ public class CollectionCacheManager : IDisposable, IReadOnlyDictionary<ModCollec
|
|||
collection._cache!.AddMod(mod, true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Increment the counter to ensure new files are loaded after applying meta changes. </summary>
|
||||
private void IncrementCounters()
|
||||
{
|
||||
foreach (var (collection, _) in _cache)
|
||||
++collection.ChangeCounter;
|
||||
_characterUtility.LoadingFinished -= IncrementCounters;
|
||||
}
|
||||
|
||||
private void OnModSettingChange(ModCollection collection, ModSettingChange type, Mod? mod, int oldValue, int groupIdx, bool _)
|
||||
{
|
||||
if (collection._cache == null)
|
||||
return;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ModSettingChange.Inheritance:
|
||||
collection._cache.ReloadMod(mod!, true);
|
||||
break;
|
||||
case ModSettingChange.EnableState:
|
||||
if (oldValue == 0)
|
||||
collection._cache.AddMod(mod!, true);
|
||||
else if (oldValue == 1)
|
||||
collection._cache.RemoveMod(mod!, true);
|
||||
else if (collection[mod!.Index].Settings?.Enabled == true)
|
||||
collection._cache.ReloadMod(mod!, true);
|
||||
else
|
||||
collection._cache.RemoveMod(mod!, true);
|
||||
|
||||
break;
|
||||
case ModSettingChange.Priority:
|
||||
if (collection._cache.Conflicts(mod!).Count > 0)
|
||||
collection._cache.ReloadMod(mod!, true);
|
||||
|
||||
break;
|
||||
case ModSettingChange.Setting:
|
||||
if (collection[mod!.Index].Settings?.Enabled == true)
|
||||
collection._cache.ReloadMod(mod!, true);
|
||||
|
||||
break;
|
||||
case ModSettingChange.MultiInheritance:
|
||||
case ModSettingChange.MultiEnableState:
|
||||
collection._cache.FullRecalculation(collection == _active.Default);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inheritance changes are too big to check for relevance,
|
||||
/// just recompute everything.
|
||||
/// </summary>
|
||||
private void OnCollectionInheritanceChange(ModCollection collection, bool _)
|
||||
=> collection._cache?.FullRecalculation(collection == _active.Default);
|
||||
}
|
||||
|
|
|
|||
230
Penumbra/Collections/Manager/CollectionEditor.cs
Normal file
230
Penumbra/Collections/Manager/CollectionEditor.cs
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using OtterGui;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Collections.Manager;
|
||||
|
||||
public class CollectionEditor
|
||||
{
|
||||
private readonly CommunicatorService _communicator;
|
||||
private readonly SaveService _saveService;
|
||||
|
||||
public CollectionEditor(SaveService saveService, CommunicatorService communicator)
|
||||
{
|
||||
_saveService = saveService;
|
||||
_communicator = communicator;
|
||||
}
|
||||
|
||||
/// <summary> Enable or disable the mod inheritance of mod idx. </summary>
|
||||
public bool SetModInheritance(ModCollection collection, Mod mod, bool inherit)
|
||||
{
|
||||
if (!FixInheritance(collection, mod, inherit))
|
||||
return false;
|
||||
|
||||
InvokeChange(collection, ModSettingChange.Inheritance, mod, inherit ? 0 : 1, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the enabled state mod idx to newValue if it differs from the current enabled state.
|
||||
/// If the mod is currently inherited, stop the inheritance.
|
||||
/// </summary>
|
||||
public bool SetModState(ModCollection collection, Mod mod, bool newValue)
|
||||
{
|
||||
var oldValue = collection._settings[mod.Index]?.Enabled ?? collection[mod.Index].Settings?.Enabled ?? false;
|
||||
if (newValue == oldValue)
|
||||
return false;
|
||||
|
||||
var inheritance = FixInheritance(collection, mod, false);
|
||||
collection._settings[mod.Index]!.Enabled = newValue;
|
||||
InvokeChange(collection, ModSettingChange.EnableState, mod, inheritance ? -1 : newValue ? 0 : 1, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary> Enable or disable the mod inheritance of every mod in mods. </summary>
|
||||
public void SetMultipleModInheritances(ModCollection collection, IEnumerable<Mod> mods, bool inherit)
|
||||
{
|
||||
if (!mods.Aggregate(false, (current, mod) => current | FixInheritance(collection, mod, inherit)))
|
||||
return;
|
||||
|
||||
InvokeChange(collection, ModSettingChange.MultiInheritance, null, -1, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the enabled state of every mod in mods to the new value.
|
||||
/// If the mod is currently inherited, stop the inheritance.
|
||||
/// </summary>
|
||||
public void SetMultipleModStates(ModCollection collection, IEnumerable<Mod> mods, bool newValue)
|
||||
{
|
||||
var changes = false;
|
||||
foreach (var mod in mods)
|
||||
{
|
||||
var oldValue = collection._settings[mod.Index]?.Enabled;
|
||||
if (newValue == oldValue)
|
||||
continue;
|
||||
|
||||
FixInheritance(collection, mod, false);
|
||||
collection._settings[mod.Index]!.Enabled = newValue;
|
||||
changes = true;
|
||||
}
|
||||
|
||||
if (!changes)
|
||||
return;
|
||||
|
||||
InvokeChange(collection, ModSettingChange.MultiEnableState, null, -1, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the priority of mod idx to newValue if it differs from the current priority.
|
||||
/// If the mod is currently inherited, stop the inheritance.
|
||||
/// </summary>
|
||||
public bool SetModPriority(ModCollection collection, Mod mod, int newValue)
|
||||
{
|
||||
var oldValue = collection._settings[mod.Index]?.Priority ?? collection[mod.Index].Settings?.Priority ?? 0;
|
||||
if (newValue == oldValue)
|
||||
return false;
|
||||
|
||||
var inheritance = FixInheritance(collection, mod, false);
|
||||
collection._settings[mod.Index]!.Priority = newValue;
|
||||
InvokeChange(collection, ModSettingChange.Priority, mod, inheritance ? -1 : oldValue, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set a given setting group settingName of mod idx to newValue if it differs from the current value and fix it if necessary.
|
||||
/// /// If the mod is currently inherited, stop the inheritance.
|
||||
/// </summary>
|
||||
public bool SetModSetting(ModCollection collection, Mod mod, int groupIdx, uint newValue)
|
||||
{
|
||||
var settings = collection._settings[mod.Index] != null
|
||||
? collection._settings[mod.Index]!.Settings
|
||||
: collection[mod.Index].Settings?.Settings;
|
||||
var oldValue = settings?[groupIdx] ?? mod.Groups[groupIdx].DefaultSettings;
|
||||
if (oldValue == newValue)
|
||||
return false;
|
||||
|
||||
var inheritance = FixInheritance(collection, mod, false);
|
||||
collection._settings[mod.Index]!.SetValue(mod, groupIdx, newValue);
|
||||
InvokeChange(collection, ModSettingChange.Setting, mod, inheritance ? -1 : (int)oldValue, groupIdx);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary> Copy the settings of an existing (sourceMod != null) or stored (sourceName) mod to another mod, if they exist. </summary>
|
||||
public bool CopyModSettings(ModCollection collection, Mod? sourceMod, string sourceName, Mod? targetMod, string targetName)
|
||||
{
|
||||
if (targetName.Length == 0 && targetMod == null || sourceName.Length == 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 = sourceMod != null
|
||||
? collection._settings[sourceMod.Index] != null
|
||||
? new ModSettings.SavedSettings(collection._settings[sourceMod.Index]!, sourceMod)
|
||||
: null
|
||||
: collection._unusedSettings.TryGetValue(sourceName, out var s)
|
||||
? s
|
||||
: null;
|
||||
|
||||
if (targetMod != 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(targetMod, out var settings);
|
||||
SetModState(collection, targetMod, settings.Enabled);
|
||||
SetModPriority(collection, targetMod, settings.Priority);
|
||||
foreach (var (value, index) in settings.Settings.WithIndex())
|
||||
SetModSetting(collection, targetMod, index, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The target mod exists, but the source is inheriting, set the target to inheriting.
|
||||
// This triggers events.
|
||||
SetModInheritance(collection, targetMod, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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)
|
||||
collection._unusedSettings[targetName] = savedSettings.Value;
|
||||
else
|
||||
collection._unusedSettings.Remove(targetName);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change one of the available mod settings for mod idx discerned by type.
|
||||
/// If type == Setting, settingName should be a valid setting for that mod, otherwise it will be ignored.
|
||||
/// The setting will also be automatically fixed if it is invalid for that setting group.
|
||||
/// For boolean parameters, newValue == 0 will be treated as false and != 0 as true.
|
||||
/// </summary>
|
||||
public bool ChangeModSetting(ModCollection collection, ModSettingChange type, Mod mod, int newValue, int groupIdx)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
ModSettingChange.Inheritance => SetModInheritance(collection, mod, newValue != 0),
|
||||
ModSettingChange.EnableState => SetModState(collection, mod, newValue != 0),
|
||||
ModSettingChange.Priority => SetModPriority(collection, mod, newValue),
|
||||
ModSettingChange.Setting => SetModSetting(collection, mod, groupIdx, (uint)newValue),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null),
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set inheritance of a mod without saving,
|
||||
/// to be used as an intermediary.
|
||||
/// </summary>
|
||||
private static bool FixInheritance(ModCollection collection, Mod mod, bool inherit)
|
||||
{
|
||||
var settings = collection._settings[mod.Index];
|
||||
if (inherit == (settings == null))
|
||||
return false;
|
||||
|
||||
collection._settings[mod.Index] = inherit ? null : collection[mod.Index].Settings?.DeepCopy() ?? ModSettings.DefaultSettings(mod);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary> Queue saves and trigger changes for any non-inherited change in a collection, then trigger changes for all inheritors. </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
private void InvokeChange(ModCollection changedCollection, ModSettingChange type, Mod? mod, int oldValue, int groupIdx)
|
||||
{
|
||||
_saveService.QueueSave(changedCollection);
|
||||
_communicator.ModSettingChanged.Invoke(changedCollection, type, mod, oldValue, groupIdx, false);
|
||||
RecurseInheritors(changedCollection, type, mod, oldValue, groupIdx);
|
||||
}
|
||||
|
||||
/// <summary> Trigger changes in all inherited collections. </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
private void RecurseInheritors(ModCollection directParent, ModSettingChange type, Mod? mod, int oldValue, int groupIdx)
|
||||
{
|
||||
foreach (var directInheritor in directParent.DirectParentOf)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ModSettingChange.MultiInheritance:
|
||||
case ModSettingChange.MultiEnableState:
|
||||
_communicator.ModSettingChanged.Invoke(directInheritor, type, null, oldValue, groupIdx, true);
|
||||
break;
|
||||
default:
|
||||
if (directInheritor._settings[mod!.Index] == null)
|
||||
_communicator.ModSettingChanged.Invoke(directInheritor, type, mod, oldValue, groupIdx, true);
|
||||
break;
|
||||
}
|
||||
|
||||
RecurseInheritors(directInheritor, type, mod, oldValue, groupIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,14 +7,16 @@ public class CollectionManager
|
|||
public readonly InheritanceManager Inheritances;
|
||||
public readonly CollectionCacheManager Caches;
|
||||
public readonly TempCollectionManager Temp;
|
||||
public readonly CollectionEditor Editor;
|
||||
|
||||
public CollectionManager(CollectionStorage storage, ActiveCollections active, InheritanceManager inheritances,
|
||||
CollectionCacheManager caches, TempCollectionManager temp)
|
||||
CollectionCacheManager caches, TempCollectionManager temp, CollectionEditor editor)
|
||||
{
|
||||
Storage = storage;
|
||||
Active = active;
|
||||
Inheritances = inheritances;
|
||||
Caches = caches;
|
||||
Temp = temp;
|
||||
Editor = editor;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,34 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
using OtterGui;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Collections.Manager;
|
||||
|
||||
/// <summary>
|
||||
/// ModCollections can inherit from an arbitrary number of other collections.
|
||||
/// This is transitive, so a collection A inheriting from B also inherits from everything B inherits.
|
||||
/// Circular dependencies are resolved by distinctness.
|
||||
/// </summary>
|
||||
public class InheritanceManager : IDisposable
|
||||
{
|
||||
public enum ValidInheritance
|
||||
{
|
||||
Valid,
|
||||
/// <summary> Can not inherit from self </summary>
|
||||
Self,
|
||||
/// <summary> Can not inherit from the empty collection </summary>
|
||||
Empty,
|
||||
/// <summary> Already inherited from </summary>
|
||||
Contained,
|
||||
/// <summary> Inheritance would lead to a circle. </summary>
|
||||
Circle,
|
||||
}
|
||||
|
||||
private readonly CollectionStorage _storage;
|
||||
private readonly CommunicatorService _communicator;
|
||||
private readonly SaveService _saveService;
|
||||
|
|
@ -26,22 +48,88 @@ public class InheritanceManager : IDisposable
|
|||
_communicator.CollectionChange.Unsubscribe(OnCollectionChange);
|
||||
}
|
||||
|
||||
/// <summary> Check whether a collection can be inherited from. </summary>
|
||||
public static ValidInheritance CheckValidInheritance(ModCollection potentialInheritor, ModCollection? potentialParent)
|
||||
{
|
||||
if (potentialParent == null || ReferenceEquals(potentialParent, ModCollection.Empty))
|
||||
return ValidInheritance.Empty;
|
||||
|
||||
if (ReferenceEquals(potentialParent, potentialInheritor))
|
||||
return ValidInheritance.Self;
|
||||
|
||||
if (potentialInheritor.DirectlyInheritsFrom.Contains(potentialParent))
|
||||
return ValidInheritance.Contained;
|
||||
|
||||
if (ModCollection.InheritedCollections(potentialParent).Any(c => ReferenceEquals(c, potentialInheritor)))
|
||||
return ValidInheritance.Circle;
|
||||
|
||||
return ValidInheritance.Valid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a new collection to the inheritance list.
|
||||
/// We do not check if this collection would be visited before,
|
||||
/// only that it is unique in the list itself.
|
||||
/// </summary>
|
||||
public bool AddInheritance(ModCollection inheritor, ModCollection parent)
|
||||
=> AddInheritance(inheritor, parent, true);
|
||||
|
||||
/// <summary> Remove an existing inheritance from a collection. </summary>
|
||||
public void RemoveInheritance(ModCollection inheritor, int idx)
|
||||
{
|
||||
var parent = inheritor.DirectlyInheritsFrom[idx];
|
||||
((List<ModCollection>)inheritor.DirectlyInheritsFrom).RemoveAt(idx);
|
||||
((List<ModCollection>)parent.DirectParentOf).Remove(inheritor);
|
||||
_communicator.CollectionInheritanceChanged.Invoke(inheritor, false);
|
||||
RecurseInheritanceChanges(inheritor);
|
||||
Penumbra.Log.Debug($"Removed {parent.AnonymizedName} from {inheritor.AnonymizedName} inheritances.");
|
||||
}
|
||||
|
||||
/// <summary> Order in the inheritance list is relevant. </summary>
|
||||
public void MoveInheritance(ModCollection inheritor, int from, int to)
|
||||
{
|
||||
if (!((List<ModCollection>)inheritor.DirectlyInheritsFrom).Move(from, to))
|
||||
return;
|
||||
|
||||
_communicator.CollectionInheritanceChanged.Invoke(inheritor, false);
|
||||
RecurseInheritanceChanges(inheritor);
|
||||
Penumbra.Log.Debug($"Moved {inheritor.AnonymizedName}s inheritance {from} to {to}.");
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="AddInheritance(ModCollection, ModCollection)"/>
|
||||
private bool AddInheritance(ModCollection inheritor, ModCollection parent, bool invokeEvent)
|
||||
{
|
||||
if (CheckValidInheritance(inheritor, parent) != ValidInheritance.Valid)
|
||||
return false;
|
||||
|
||||
((List<ModCollection>)inheritor.DirectlyInheritsFrom).Add(parent);
|
||||
((List<ModCollection>)parent.DirectParentOf).Add(inheritor);
|
||||
if (invokeEvent)
|
||||
{
|
||||
_communicator.CollectionInheritanceChanged.Invoke(inheritor, false);
|
||||
RecurseInheritanceChanges(inheritor);
|
||||
}
|
||||
|
||||
Penumbra.Log.Debug($"Added {parent.AnonymizedName} to {inheritor.AnonymizedName} inheritances.");
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inheritances can not be setup before all collections are read,
|
||||
/// so this happens after reading the collections in the constructor, consuming the stored strings.
|
||||
/// </summary>
|
||||
private void ApplyInheritances()
|
||||
{
|
||||
foreach (var (collection, inheritances, changes) in _storage.ConsumeInheritanceNames())
|
||||
foreach (var (collection, directParents, changes) in _storage.ConsumeInheritanceNames())
|
||||
{
|
||||
var localChanges = changes;
|
||||
foreach (var subCollection in inheritances)
|
||||
foreach (var parent in directParents)
|
||||
{
|
||||
if (collection.AddInheritance(subCollection, false))
|
||||
if (AddInheritance(collection, parent, false))
|
||||
continue;
|
||||
|
||||
localChanges = true;
|
||||
Penumbra.ChatService.NotificationMessage($"{collection.Name} can not inherit from {subCollection.Name}, removed.", "Warning",
|
||||
Penumbra.ChatService.NotificationMessage($"{collection.Name} can not inherit from {parent.Name}, removed.", "Warning",
|
||||
NotificationType.Warning);
|
||||
}
|
||||
|
||||
|
|
@ -55,14 +143,22 @@ public class InheritanceManager : IDisposable
|
|||
if (collectionType is not CollectionType.Inactive || old == null)
|
||||
return;
|
||||
|
||||
foreach (var inheritance in old.Inheritance)
|
||||
old.ClearSubscriptions(inheritance);
|
||||
|
||||
foreach (var c in _storage)
|
||||
{
|
||||
var inheritedIdx = c._inheritance.IndexOf(old);
|
||||
var inheritedIdx = c.DirectlyInheritsFrom.IndexOf(old);
|
||||
if (inheritedIdx >= 0)
|
||||
c.RemoveInheritance(inheritedIdx);
|
||||
RemoveInheritance(c, inheritedIdx);
|
||||
|
||||
((List<ModCollection>)c.DirectParentOf).Remove(old);
|
||||
}
|
||||
}
|
||||
|
||||
private void RecurseInheritanceChanges(ModCollection newInheritor)
|
||||
{
|
||||
foreach (var inheritor in newInheritor.DirectParentOf)
|
||||
{
|
||||
_communicator.CollectionInheritanceChanged.Invoke(inheritor, true);
|
||||
RecurseInheritanceChanges(inheritor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue