Skip to content

Commit

Permalink
Now that was a lot of work.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ottermandias committed Apr 26, 2024
1 parent 297be48 commit 1e5ed1c
Show file tree
Hide file tree
Showing 44 changed files with 1,176 additions and 760 deletions.
2 changes: 1 addition & 1 deletion Penumbra.Api
3 changes: 2 additions & 1 deletion Penumbra/Api/Api/ModSettingsApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Penumbra.Mods.Groups;
using Penumbra.Mods.Manager;
using Penumbra.Mods.Settings;
using Penumbra.Mods.SubMods;
using Penumbra.Services;

namespace Penumbra.Api.Api;
Expand Down Expand Up @@ -254,7 +255,7 @@ private void OnModPathChange(ModPathChangeType type, Mod mod, DirectoryInfo? _1,
private void OnModSettingChange(ModCollection collection, ModSettingChange type, Mod? mod, Setting _1, int _2, bool inherited)
=> ModSettingChanged?.Invoke(type, collection.Id, mod?.ModPath.Name ?? string.Empty, inherited);

private void OnModOptionEdited(ModOptionChangeType type, Mod mod, int groupIndex, int optionIndex, int moveIndex)
private void OnModOptionEdited(ModOptionChangeType type, Mod mod, IModGroup? group, IModOption? option, IModDataContainer? container, int moveIndex)
{
switch (type)
{
Expand Down
4 changes: 3 additions & 1 deletion Penumbra/Collections/Cache/CollectionCacheManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
using Penumbra.Interop.ResourceLoading;
using Penumbra.Meta;
using Penumbra.Mods;
using Penumbra.Mods.Groups;
using Penumbra.Mods.Manager;
using Penumbra.Mods.Settings;
using Penumbra.Mods.SubMods;
using Penumbra.Services;
using Penumbra.String.Classes;

Expand Down Expand Up @@ -257,7 +259,7 @@ private void RemoveCache(ModCollection? collection)
}

/// <summary> Prepare Changes by removing mods from caches with collections or add or reload mods. </summary>
private void OnModOptionChange(ModOptionChangeType type, Mod mod, int groupIdx, int optionIdx, int movedToIdx)
private void OnModOptionChange(ModOptionChangeType type, Mod mod, IModGroup? group, IModOption? option, IModDataContainer? container, int movedToIdx)
{
if (type is ModOptionChangeType.PrepareChange)
{
Expand Down
6 changes: 4 additions & 2 deletions Penumbra/Collections/Manager/CollectionStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
using Penumbra.Communication;
using Penumbra.Mods;
using Penumbra.Mods.Editor;
using Penumbra.Mods.Groups;
using Penumbra.Mods.Manager;
using Penumbra.Mods.Settings;
using Penumbra.Mods.SubMods;
using Penumbra.Services;

namespace Penumbra.Collections.Manager;
Expand Down Expand Up @@ -290,15 +292,15 @@ private void OnModPathChange(ModPathChangeType type, Mod mod, DirectoryInfo? old
}

/// <summary> Save all collections where the mod has settings and the change requires saving. </summary>
private void OnModOptionChange(ModOptionChangeType type, Mod mod, int groupIdx, int optionIdx, int movedToIdx)
private void OnModOptionChange(ModOptionChangeType type, Mod mod, IModGroup? group, IModOption? option, IModDataContainer? container, int movedToIdx)
{
type.HandlingInfo(out var requiresSaving, out _, out _);
if (!requiresSaving)
return;

foreach (var collection in this)
{
if (collection.Settings[mod.Index]?.HandleChanges(type, mod, groupIdx, optionIdx, movedToIdx) ?? false)
if (collection.Settings[mod.Index]?.HandleChanges(type, mod, group, option, movedToIdx) ?? false)
_saveService.QueueSave(new ModCollectionSave(_modStorage, collection));
}
}
Expand Down
17 changes: 10 additions & 7 deletions Penumbra/Communication/ModOptionChanged.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using OtterGui.Classes;
using Penumbra.Api;
using Penumbra.Api.Api;
using Penumbra.Mods;
using Penumbra.Mods.Groups;
using Penumbra.Mods.Manager;
using Penumbra.Mods.SubMods;
using static Penumbra.Communication.ModOptionChanged;

namespace Penumbra.Communication;

Expand All @@ -11,22 +13,23 @@ namespace Penumbra.Communication;
/// <list type="number">
/// <item>Parameter is the type option change. </item>
/// <item>Parameter is the changed mod. </item>
/// <item>Parameter is the index of the changed group inside the mod. </item>
/// <item>Parameter is the index of the changed option inside the group or -1 if it does not concern a specific option. </item>
/// <item>Parameter is the index of the group an option was moved to. </item>
/// <item>Parameter is the changed group inside the mod. </item>
/// <item>Parameter is the changed option inside the group or null if it does not concern a specific option. </item>
/// <item>Parameter is the changed data container inside the group or null if it does not concern a specific data container. </item>
/// <item>Parameter is the index of the group or option moved or deleted from. </item>
/// </list> </summary>
public sealed class ModOptionChanged()
: EventWrapper<ModOptionChangeType, Mod, int, int, int, ModOptionChanged.Priority>(nameof(ModOptionChanged))
: EventWrapper<ModOptionChangeType, Mod, IModGroup?, IModOption?, IModDataContainer?, int, Priority>(nameof(ModOptionChanged))
{
public enum Priority
{
/// <seealso cref="PenumbraApi.OnModOptionEdited"/>
/// <seealso cref="ModSettingsApi.OnModOptionEdited"/>
Api = int.MinValue,

/// <seealso cref="Collections.Cache.CollectionCacheManager.OnModOptionChange"/>
CollectionCacheManager = -100,

/// <seealso cref="Mods.Manager.ModCacheManager.OnModOptionChange"/>
/// <seealso cref="ModCacheManager.OnModOptionChange"/>
ModCacheManager = 0,

/// <seealso cref="UI.AdvancedWindow.ItemSwapTab.OnModOptionChange"/>
Expand Down
2 changes: 1 addition & 1 deletion Penumbra/Import/TexToolsImporter.ModPack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ private DirectoryInfo ImportExtendedV2ModPack(ZipArchive extractedModPack, strin
{
var option = group.OptionList[idx];
_currentOptionName = option.Name;
options.Insert(idx, MultiSubMod.CreateForSaving(option.Name, option.Description, ModPriority.Default));
options.Insert(idx, MultiSubMod.WithoutGroup(option.Name, option.Description, ModPriority.Default));
if (option.IsChecked)
defaultSettings = Setting.Single(idx);
}
Expand Down
13 changes: 4 additions & 9 deletions Penumbra/Mods/Editor/DuplicateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public void Clear()

private void HandleDuplicate(Mod mod, FullPath duplicate, FullPath remaining, bool useModManager)
{
ModEditor.ApplyToAllOptions(mod, HandleSubMod);
ModEditor.ApplyToAllContainers(mod, HandleSubMod);

try
{
Expand All @@ -73,7 +73,7 @@ private void HandleDuplicate(Mod mod, FullPath duplicate, FullPath remaining, bo

return;

void HandleSubMod(IModDataContainer subMod, int groupIdx, int optionIdx)
void HandleSubMod(IModDataContainer subMod)
{
var changes = false;
var dict = subMod.Files.ToDictionary(kvp => kvp.Key,
Expand All @@ -82,14 +82,9 @@ void HandleSubMod(IModDataContainer subMod, int groupIdx, int optionIdx)
return;

if (useModManager)
{
modManager.OptionEditor.OptionSetFiles(mod, groupIdx, optionIdx, dict, SaveType.ImmediateSync);
}
modManager.OptionEditor.SetFiles(subMod, dict, SaveType.ImmediateSync);
else
{
subMod.Files = dict;
saveService.ImmediateSaveSync(new ModSaveGroup(mod, groupIdx, config.ReplaceNonAsciiOnImport));
}
saveService.ImmediateSaveSync(new ModSaveGroup(mod.ModPath, subMod, config.ReplaceNonAsciiOnImport));
}
}

Expand Down
46 changes: 17 additions & 29 deletions Penumbra/Mods/Editor/ModEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public class ModEditor(
public int GroupIdx { get; private set; }
public int DataIdx { get; private set; }

public IModGroup? Group { get; private set; }
public IModDataContainer? Option { get; private set; }
public IModGroup? Group { get; private set; }
public IModDataContainer? Option { get; private set; }

public void LoadMod(Mod mod)
=> LoadMod(mod, -1, 0);
Expand Down Expand Up @@ -63,10 +63,10 @@ private void LoadOption(int groupIdx, int dataIdx, bool message)
{
if (groupIdx == -1 && dataIdx == 0)
{
Group = null;
Option = Mod.Default;
GroupIdx = groupIdx;
DataIdx = dataIdx;
Group = null;
Option = Mod.Default;
GroupIdx = groupIdx;
DataIdx = dataIdx;
return;
}

Expand All @@ -75,18 +75,18 @@ private void LoadOption(int groupIdx, int dataIdx, bool message)
Group = Mod.Groups[groupIdx];
if (dataIdx >= 0 && dataIdx < Group.DataContainers.Count)
{
Option = Group.DataContainers[dataIdx];
GroupIdx = groupIdx;
DataIdx = dataIdx;
Option = Group.DataContainers[dataIdx];
GroupIdx = groupIdx;
DataIdx = dataIdx;
return;
}
}
}

Group = null;
Option = Mod?.Default;
GroupIdx = -1;
DataIdx = 0;
Group = null;
Option = Mod?.Default;
GroupIdx = -1;
DataIdx = 0;
if (message)
Penumbra.Log.Error($"Loading invalid option {groupIdx} {dataIdx} for Mod {Mod?.Name ?? "Unknown"}.");
}
Expand All @@ -105,23 +105,11 @@ public void Dispose()
=> Clear();

/// <summary> Apply a option action to all available option in a mod, including the default option. </summary>
public static void ApplyToAllOptions(Mod mod, Action<IModDataContainer, int, int> action)
public static void ApplyToAllContainers(Mod mod, Action<IModDataContainer> action)
{
action(mod.Default, -1, 0);
foreach (var (group, groupIdx) in mod.Groups.WithIndex())
{
switch (group)
{
case SingleModGroup single:
for (var optionIdx = 0; optionIdx < single.OptionData.Count; ++optionIdx)
action(single.OptionData[optionIdx], groupIdx, optionIdx);
break;
case MultiModGroup multi:
for (var optionIdx = 0; optionIdx < multi.OptionData.Count; ++optionIdx)
action(multi.OptionData[optionIdx], groupIdx, optionIdx);
break;
}
}
action(mod.Default);
foreach (var container in mod.Groups.SelectMany(g => g.DataContainers))
action(container);
}

// Does not delete the base directory itself even if it is completely empty at the end.
Expand Down
9 changes: 4 additions & 5 deletions Penumbra/Mods/Editor/ModFileEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ public int Apply(Mod mod, IModDataContainer option)
num += dict.TryAdd(path.Item2, file.File) ? 0 : 1;
}

var (groupIdx, dataIdx) = option.GetDataIndices();
modManager.OptionEditor.OptionSetFiles(mod, groupIdx, dataIdx, dict);
modManager.OptionEditor.SetFiles(option, dict);
files.UpdatePaths(mod, option);
Changes = false;
return num;
Expand All @@ -40,15 +39,15 @@ public void Revert(Mod mod, IModDataContainer option)
/// <summary> Remove all path redirections where the pointed-to file does not exist. </summary>
public void RemoveMissingPaths(Mod mod, IModDataContainer option)
{
void HandleSubMod(IModDataContainer subMod, int groupIdx, int optionIdx)
void HandleSubMod(IModDataContainer subMod)
{
var newDict = subMod.Files.Where(kvp => CheckAgainstMissing(mod, subMod, kvp.Value, kvp.Key, subMod == option))
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
if (newDict.Count != subMod.Files.Count)
modManager.OptionEditor.OptionSetFiles(mod, groupIdx, optionIdx, newDict);
modManager.OptionEditor.SetFiles(subMod, newDict);
}

ModEditor.ApplyToAllOptions(mod, HandleSubMod);
ModEditor.ApplyToAllContainers(mod, HandleSubMod);
files.ClearMissingFiles();
}

Expand Down
Loading

0 comments on commit 1e5ed1c

Please sign in to comment.