mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Try to make the cache a bit more stable and resetting the cached list more sensible.
This commit is contained in:
parent
1bf144e1f5
commit
afcb481dd2
11 changed files with 132 additions and 72 deletions
|
|
@ -5,11 +5,19 @@ using Penumbra.Util;
|
|||
|
||||
namespace Penumbra.Mods
|
||||
{
|
||||
public delegate void OnModFileSystemChange();
|
||||
|
||||
public static partial class ModFileSystem
|
||||
{
|
||||
// The root folder that should be used as the base for all structured mods.
|
||||
public static ModFolder Root = ModFolder.CreateRoot();
|
||||
|
||||
// Gets invoked every time the file system changes.
|
||||
public static event OnModFileSystemChange? ModFileSystemChanged;
|
||||
|
||||
internal static void InvokeChange()
|
||||
=> ModFileSystemChanged?.Invoke();
|
||||
|
||||
// Find a specific mod folder by its path from Root.
|
||||
// Returns true if the folder was found, and false if not.
|
||||
// The out parameter will contain the furthest existing folder.
|
||||
|
|
@ -69,7 +77,6 @@ namespace Penumbra.Mods
|
|||
|
||||
// Move a mod to the filesystem location specified by sortOrder and rename its SortOrderName.
|
||||
// Creates all necessary Subfolders.
|
||||
// Does NOT save.
|
||||
public static void Move( this ModData mod, string sortOrder )
|
||||
{
|
||||
var split = sortOrder.Split( new[] { '/' }, StringSplitOptions.RemoveEmptyEntries );
|
||||
|
|
@ -79,8 +86,10 @@ namespace Penumbra.Mods
|
|||
folder = folder.FindOrCreateSubFolder( split[ i ] ).Item1;
|
||||
}
|
||||
|
||||
MoveNoSave( mod, folder );
|
||||
RenameNoSave( mod, split.Last() );
|
||||
if( MoveNoSave( mod, folder ) || RenameNoSave( mod, split.Last() ) )
|
||||
{
|
||||
SaveMod( mod );
|
||||
}
|
||||
}
|
||||
|
||||
// Moves folder to target.
|
||||
|
|
@ -126,6 +135,7 @@ namespace Penumbra.Mods
|
|||
}
|
||||
|
||||
config.Save();
|
||||
InvokeChange();
|
||||
}
|
||||
|
||||
// Sets and saves the sort order of a single mod, removing the entry if it is unnecessary.
|
||||
|
|
@ -143,6 +153,7 @@ namespace Penumbra.Mods
|
|||
}
|
||||
|
||||
config.Save();
|
||||
InvokeChange();
|
||||
}
|
||||
|
||||
private static bool RenameNoSave( this ModFolder target, string newName )
|
||||
|
|
|
|||
|
|
@ -148,10 +148,14 @@ namespace Penumbra.Mods
|
|||
PluginLog.Error( $"Could not delete the mod {modFolder.Name}:\n{e}" );
|
||||
}
|
||||
|
||||
if( Mods.TryGetValue( modFolder.Name, out var mod ) )
|
||||
{
|
||||
mod.SortOrder.ParentFolder.RemoveMod( mod );
|
||||
Mods.Remove( modFolder.Name );
|
||||
Collections.RemoveModFromCaches( modFolder );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool AddMod( DirectoryInfo modFolder )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -80,9 +80,6 @@ namespace Penumbra
|
|||
|
||||
SettingsInterface = new SettingsInterface( this );
|
||||
|
||||
PluginInterface.UiBuilder.DisableGposeUiHide = true;
|
||||
PluginInterface.UiBuilder.OnBuildUi += SettingsInterface.Draw;
|
||||
|
||||
if( Configuration.EnableHttpApi )
|
||||
{
|
||||
CreateWebServer();
|
||||
|
|
@ -147,9 +144,9 @@ namespace Penumbra
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
SettingsInterface.Dispose();
|
||||
ActorRefresher.Dispose();
|
||||
PlayerWatcher.Dispose();
|
||||
PluginInterface.UiBuilder.OnBuildUi -= SettingsInterface.Draw;
|
||||
|
||||
PluginInterface.CommandManager.RemoveHandler( CommandName );
|
||||
PluginInterface.Dispose();
|
||||
|
|
|
|||
|
|
@ -141,22 +141,19 @@ namespace Penumbra.UI
|
|||
|
||||
_manager.Collections.SetCurrentCollection( _collections[ idx + 1 ] );
|
||||
_currentCollectionIndex = idx;
|
||||
_selector.ReloadSelection();
|
||||
_selector.Cache.ResetModList();
|
||||
_selector.Cache.TriggerListReset();
|
||||
if( _selector.Mod != null )
|
||||
{
|
||||
_selector.SelectModByDir( _selector.Mod.Data.BasePath.Name );
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCurrentCollection( ModCollection collection )
|
||||
{
|
||||
var idx = Array.IndexOf( _collections, collection ) - 1;
|
||||
if( idx >= 0 && idx != _currentCollectionIndex )
|
||||
if( idx >= 0 )
|
||||
{
|
||||
_manager.Collections.SetCurrentCollection( _collections[ idx + 1 ] );
|
||||
_currentCollectionIndex = idx;
|
||||
_selector.Cache.ResetModList();
|
||||
if( _selector.Mod != null )
|
||||
{
|
||||
_selector.SelectModByDir( _selector.Mod.Data.BasePath.Name );
|
||||
}
|
||||
SetCurrentCollection( idx );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Dalamud.Plugin;
|
||||
|
|
@ -5,7 +6,7 @@ using Penumbra.Mods;
|
|||
|
||||
namespace Penumbra.UI
|
||||
{
|
||||
public class ModListCache
|
||||
public class ModListCache : IDisposable
|
||||
{
|
||||
public const uint DisabledModColor = 0xFF666666u;
|
||||
public const uint ConflictingModColor = 0xFFAAAAFFu;
|
||||
|
|
@ -21,6 +22,9 @@ namespace Penumbra.UI
|
|||
private string _modFilterChanges = "";
|
||||
private string _modFilterAuthor = "";
|
||||
private ModFilter _stateFilter = ModFilterExtensions.UnfilteredStateMods;
|
||||
private bool _listResetNecessary = false;
|
||||
private bool _filterResetNecessary = false;
|
||||
|
||||
|
||||
public ModFilter StateFilter
|
||||
{
|
||||
|
|
@ -31,7 +35,7 @@ namespace Penumbra.UI
|
|||
_stateFilter = value;
|
||||
if( diff )
|
||||
{
|
||||
ResetFilters();
|
||||
TriggerFilterReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -40,11 +44,41 @@ namespace Penumbra.UI
|
|||
{
|
||||
_manager = manager;
|
||||
ResetModList();
|
||||
ModFileSystem.ModFileSystemChanged += TriggerListReset;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ModFileSystem.ModFileSystemChanged -= TriggerListReset;
|
||||
}
|
||||
|
||||
public int Count
|
||||
=> _modsInOrder.Count;
|
||||
|
||||
|
||||
public bool Update()
|
||||
{
|
||||
if( _listResetNecessary )
|
||||
{
|
||||
ResetModList();
|
||||
return true;
|
||||
}
|
||||
|
||||
if( _filterResetNecessary )
|
||||
{
|
||||
ResetFilters();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void TriggerListReset()
|
||||
=> _listResetNecessary = true;
|
||||
|
||||
public void TriggerFilterReset()
|
||||
=> _filterResetNecessary = true;
|
||||
|
||||
public void RemoveMod( Mod.Mod mod )
|
||||
{
|
||||
var idx = _modsInOrder.IndexOf( mod );
|
||||
|
|
@ -103,7 +137,7 @@ namespace Penumbra.UI
|
|||
ResetFilters();
|
||||
}
|
||||
|
||||
public void ResetModList()
|
||||
private void ResetModList()
|
||||
{
|
||||
_modsInOrder.Clear();
|
||||
_visibleMods.Clear();
|
||||
|
|
@ -119,9 +153,12 @@ namespace Penumbra.UI
|
|||
_visibleMods.Add( CheckFilters( mod ) );
|
||||
}
|
||||
}
|
||||
|
||||
_listResetNecessary = false;
|
||||
_filterResetNecessary = false;
|
||||
}
|
||||
|
||||
public void ResetFilters()
|
||||
private void ResetFilters()
|
||||
{
|
||||
_visibleMods.Clear();
|
||||
_visibleFolders.Clear();
|
||||
|
|
@ -130,6 +167,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
_visibleMods.Add( CheckFilters( mod ) );
|
||||
}
|
||||
_filterResetNecessary = false;
|
||||
}
|
||||
|
||||
public (Mod.Mod? mod, int idx) GetModByName( string name )
|
||||
|
|
|
|||
|
|
@ -442,7 +442,7 @@ namespace Penumbra.UI
|
|||
// If the mod is enabled in the current collection, its conflicts may have changed.
|
||||
if( Mod!.Settings.Enabled )
|
||||
{
|
||||
_selector.Cache.ResetFilters();
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
if( _modManager.ChangeModGroup( group.GroupName, groupName, Mod.Data ) && Mod.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
_selector.Cache.ResetFilters();
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -132,7 +132,7 @@ namespace Penumbra.UI
|
|||
_selector.SaveCurrentMod();
|
||||
if( Mod!.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
_selector.Cache.ResetFilters();
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -173,7 +173,7 @@ namespace Penumbra.UI
|
|||
|
||||
if( Mod!.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
_selector.Cache.ResetFilters();
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -190,7 +190,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
if( _modManager.ChangeModGroup( group.GroupName, groupName, Mod.Data ) && Mod.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
_selector.Cache.ResetFilters();
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -238,7 +238,7 @@ namespace Penumbra.UI
|
|||
|
||||
if( Mod.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
_selector.Cache.ResetFilters();
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -347,7 +347,6 @@ namespace Penumbra.UI
|
|||
|
||||
_selector.SaveCurrentMod();
|
||||
_selector.ReloadCurrentMod();
|
||||
_selector.Cache.ResetModList();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -369,8 +368,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
Meta.FileSwaps[ key ] = newValue;
|
||||
_selector.SaveCurrentMod();
|
||||
_selector.ReloadCurrentMod();
|
||||
_selector.Cache.ResetModList();
|
||||
_selector.Cache.TriggerListReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,9 +75,9 @@ namespace Penumbra.UI
|
|||
if( Custom.ImGuiCustom.InputOrText( _editMode, LabelEditName, ref name, 64 ) && _modManager.RenameMod( name, Mod!.Data ) )
|
||||
{
|
||||
_selector.SelectModByDir( Mod.Data.BasePath.Name );
|
||||
if( !_modManager.Config.ModSortOrder.ContainsKey( Mod!.Data.BasePath.Name ) && Mod.Data.Rename( name ) )
|
||||
if( !_modManager.Config.ModSortOrder.ContainsKey( Mod!.Data.BasePath.Name ) )
|
||||
{
|
||||
_selector.Cache.ResetModList();
|
||||
Mod.Data.Rename( name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -122,7 +122,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
Meta.Author = author;
|
||||
_selector.SaveCurrentMod();
|
||||
_selector.Cache.ResetFilters();
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
|
||||
ImGui.EndGroup();
|
||||
|
|
@ -205,7 +205,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
Mod.Settings.Priority = priority;
|
||||
_base.SaveCurrentCollection( Mod.Data.Resources.MetaManipulations.Count > 0 );
|
||||
_selector.Cache.ResetFilters();
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
|
|
@ -222,7 +222,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
Mod.Settings.Enabled = enabled;
|
||||
_base.SaveCurrentCollection( Mod.Data.Resources.MetaManipulations.Count > 0 );
|
||||
_selector.Cache.ResetFilters();
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -233,7 +233,6 @@ namespace Penumbra.UI
|
|||
if( ImGui.InputText( "Sort Order", ref currentSortOrder, 256, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
manager.ChangeSortOrder( mod, currentSortOrder );
|
||||
selector.Cache.ResetModList();
|
||||
selector.SelectModByDir( mod.BasePath.Name );
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ namespace Penumbra.UI
|
|||
var mod = Mod;
|
||||
Cache.RemoveMod( mod );
|
||||
_modManager.DeleteMod( mod.Data.BasePath );
|
||||
ModFileSystem.InvokeChange();
|
||||
ClearSelection();
|
||||
}
|
||||
|
||||
|
|
@ -166,7 +167,7 @@ namespace Penumbra.UI
|
|||
var metaFile = new FileInfo( Path.Combine( newDir.FullName, "meta.json" ) );
|
||||
modMeta.SaveToFile( metaFile );
|
||||
_modManager.AddMod( newDir );
|
||||
Cache.ResetModList();
|
||||
ModFileSystem.InvokeChange();
|
||||
SelectModByDir( newDir.Name );
|
||||
}
|
||||
catch( Exception e )
|
||||
|
|
@ -367,10 +368,7 @@ namespace Penumbra.UI
|
|||
var mod = Cache.GetMod( modIndex ).Item1;
|
||||
if( mod != null )
|
||||
{
|
||||
if( mod.Data.Move( folder ) )
|
||||
{
|
||||
Cache.ResetModList();
|
||||
}
|
||||
mod.Data.Move( folder );
|
||||
}
|
||||
}
|
||||
else if( IsDropping( DraggedFolderLabel ) )
|
||||
|
|
@ -381,10 +379,7 @@ namespace Penumbra.UI
|
|||
&& !ReferenceEquals( droppedFolder, folder )
|
||||
&& !folder.FullName.StartsWith( folderName, StringComparison.InvariantCultureIgnoreCase ) )
|
||||
{
|
||||
if( droppedFolder.Move( folder ) )
|
||||
{
|
||||
Cache.ResetModList();
|
||||
}
|
||||
droppedFolder.Move( folder );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -484,7 +479,6 @@ namespace Penumbra.UI
|
|||
|
||||
if( _index >= 0 && _modManager.UpdateMod( Mod.Data, reloadMeta, recomputeMeta ) )
|
||||
{
|
||||
Cache.ResetModList();
|
||||
SelectModByDir( Mod.Data.BasePath.Name );
|
||||
_base._menu.InstalledTab.ModPanel.Details.ResetState();
|
||||
}
|
||||
|
|
@ -541,7 +535,7 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
Cache.ResetFilters();
|
||||
Cache.TriggerFilterReset();
|
||||
var collection = _modManager.Collections.CurrentCollection;
|
||||
if( collection.Cache != null )
|
||||
{
|
||||
|
|
@ -561,21 +555,15 @@ namespace Penumbra.UI
|
|||
return;
|
||||
}
|
||||
|
||||
bool changes;
|
||||
if( _newFolderName.Any() )
|
||||
{
|
||||
changes = folder.Rename( _newFolderName );
|
||||
_newFolderName = string.Empty;
|
||||
folder.Rename( _newFolderName );
|
||||
}
|
||||
else
|
||||
{
|
||||
changes = folder.Merge( folder.Parent! );
|
||||
}
|
||||
|
||||
if( changes )
|
||||
{
|
||||
Cache.ResetModList();
|
||||
folder.Merge( folder.Parent! );
|
||||
}
|
||||
_newFolderName = string.Empty;
|
||||
}
|
||||
|
||||
private void DrawFolderContextMenu( ModFolder folder, int currentIdx, string treeName )
|
||||
|
|
@ -629,8 +617,12 @@ namespace Penumbra.UI
|
|||
{
|
||||
_base._menu.CollectionsTab.SetCurrentCollection( collection );
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
ImGui.SetTooltip( $"Switches to the currently set {tooltipLabel} collection, if it is not set to None and it is not the current collection already." );
|
||||
{
|
||||
ImGui.SetTooltip(
|
||||
$"Switches to the currently set {tooltipLabel} collection, if it is not set to None and it is not the current collection already." );
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawHeaderBar()
|
||||
|
|
@ -641,7 +633,11 @@ namespace Penumbra.UI
|
|||
var comboSize = size * ImGui.GetIO().FontGlobalScale;
|
||||
var offset = comboSize + textSize;
|
||||
|
||||
var buttonSize = (ImGui.GetWindowContentRegionWidth() - offset - SelectorPanelWidth * _selectorScalingFactor - 4 * ImGui.GetStyle().ItemSpacing.X) / 2;
|
||||
var buttonSize = ( ImGui.GetWindowContentRegionWidth()
|
||||
- offset
|
||||
- SelectorPanelWidth * _selectorScalingFactor
|
||||
- 4 * ImGui.GetStyle().ItemSpacing.X )
|
||||
/ 2;
|
||||
ImGui.SameLine();
|
||||
DrawCollectionButton( "Default", "default", buttonSize, _modManager.Collections.DefaultCollection );
|
||||
|
||||
|
|
@ -767,6 +763,11 @@ namespace Penumbra.UI
|
|||
true, ImGuiWindowFlags.HorizontalScrollbar );
|
||||
|
||||
ImGui.PushStyleVar( ImGuiStyleVar.IndentSpacing, 12.5f );
|
||||
if( Cache.Update() && Mod != null )
|
||||
{
|
||||
SelectModByDir( Mod.Data.BasePath.Name );
|
||||
}
|
||||
|
||||
var modIndex = 0;
|
||||
DrawFolderContent( _modManager.StructuredMods, ref modIndex );
|
||||
ImGui.PopStyleVar();
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ namespace Penumbra.UI
|
|||
if( ImGui.Checkbox( LabelSortFoldersFirst, ref foldersFirst ) )
|
||||
{
|
||||
_config.SortFoldersFirst = foldersFirst;
|
||||
_base._menu.InstalledTab.Selector.Cache.ResetModList();
|
||||
_base._menu.InstalledTab.Selector.Cache.TriggerListReset();
|
||||
_configChanged = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI
|
||||
{
|
||||
public partial class SettingsInterface
|
||||
public partial class SettingsInterface : IDisposable
|
||||
{
|
||||
private const float DefaultVerticalSpace = 20f;
|
||||
|
||||
|
|
@ -25,8 +26,22 @@ namespace Penumbra.UI
|
|||
_menuBar = new MenuBar( this );
|
||||
_menu = new SettingsMenu( this );
|
||||
_modManager = Service< ModManager >.Get();
|
||||
|
||||
_plugin.PluginInterface.UiBuilder.DisableGposeUiHide = true;
|
||||
_plugin.PluginInterface.UiBuilder.OnBuildUi += Draw;
|
||||
_plugin.PluginInterface.UiBuilder.OnOpenConfigUi += OpenConfig;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_menu.InstalledTab.Selector.Cache.Dispose();
|
||||
_plugin.PluginInterface.UiBuilder.OnBuildUi -= Draw;
|
||||
_plugin.PluginInterface.UiBuilder.OnOpenConfigUi -= OpenConfig;
|
||||
}
|
||||
|
||||
private void OpenConfig( object _1, EventArgs _2 )
|
||||
=> _menu.Visible = true;
|
||||
|
||||
public void FlipVisibility()
|
||||
=> _menu.Visible = !_menu.Visible;
|
||||
|
||||
|
|
@ -44,7 +59,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
_menu.InstalledTab.Selector.ClearSelection();
|
||||
_modManager.DiscoverMods( _plugin.Configuration.ModDirectory );
|
||||
_menu.InstalledTab.Selector.Cache.ResetModList();
|
||||
_menu.InstalledTab.Selector.Cache.TriggerListReset();
|
||||
}
|
||||
|
||||
private void SaveCurrentCollection( bool recalculateMeta )
|
||||
|
|
@ -61,7 +76,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
current.CalculateEffectiveFileList( _modManager.BasePath, recalculateMeta,
|
||||
current == _modManager.Collections.ActiveCollection );
|
||||
_menu.InstalledTab.Selector.Cache.ResetFilters();
|
||||
_menu.InstalledTab.Selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue