Add EphemeralConfig.

This commit is contained in:
Ottermandias 2023-11-17 16:51:09 +01:00
parent dc1c8f42c0
commit ea65296ab7
17 changed files with 264 additions and 125 deletions

View file

@ -184,8 +184,8 @@ public class CommandHandler : IDisposable
private bool SetUiLockState(string arguments)
{
var value = ParseTrueFalseToggle(arguments) ?? !_config.FixMainWindow;
if (value == _config.FixMainWindow)
var value = ParseTrueFalseToggle(arguments) ?? !_config.Ephemeral.FixMainWindow;
if (value == _config.Ephemeral.FixMainWindow)
return false;
if (value)
@ -199,8 +199,8 @@ public class CommandHandler : IDisposable
_configWindow.Flags &= ~(ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoResize);
}
_config.FixMainWindow = value;
_config.Save();
_config.Ephemeral.FixMainWindow = value;
_config.Ephemeral.Save();
return true;
}

View file

@ -5,17 +5,13 @@ using OtterGui;
using OtterGui.Classes;
using OtterGui.Filesystem;
using OtterGui.Widgets;
using Penumbra.Api.Enums;
using Penumbra.Enums;
using Penumbra.Import.Structs;
using Penumbra.Interop.Services;
using Penumbra.Mods;
using Penumbra.Mods.Manager;
using Penumbra.Services;
using Penumbra.UI;
using Penumbra.UI.Classes;
using Penumbra.UI.ResourceWatcher;
using Penumbra.UI.Tabs;
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
namespace Penumbra;
@ -26,9 +22,11 @@ public class Configuration : IPluginConfiguration, ISavable
[JsonIgnore]
private readonly SaveService _saveService;
[JsonIgnore]
public readonly EphemeralConfig Ephemeral;
public int Version { get; set; } = Constants.CurrentVersion;
public int LastSeenVersion { get; set; } = PenumbraChangelog.LastChangelogVersion;
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New;
public bool EnableMods { get; set; } = true;
@ -53,52 +51,33 @@ public class Configuration : IPluginConfiguration, ISavable
public bool HideRedrawBar { get; set; } = false;
public int OptionGroupCollapsibleMin { get; set; } = 5;
public bool DebugSeparateWindow = false;
public Vector2 MinimumSize = new(Constants.MinimumSizeX, Constants.MinimumSizeY);
public Vector2 MinimumSize = new(Constants.MinimumSizeX, Constants.MinimumSizeY);
#if DEBUG
public bool DebugMode { get; set; } = true;
#else
public bool DebugMode { get; set; } = false;
#endif
public int TutorialStep { get; set; } = 0;
public bool EnableResourceLogging { get; set; } = false;
public string ResourceLoggingFilter { get; set; } = string.Empty;
public bool EnableResourceWatcher { get; set; } = false;
public bool OnlyAddMatchingResources { get; set; } = true;
public int MaxResourceWatcherRecords { get; set; } = ResourceWatcher.DefaultMaxEntries;
public ResourceTypeFlag ResourceWatcherResourceTypes { get; set; } = ResourceExtensions.AllResourceTypes;
public ResourceCategoryFlag ResourceWatcherResourceCategories { get; set; } = ResourceExtensions.AllResourceCategories;
public RecordType ResourceWatcherRecordTypes { get; set; } = ResourceWatcher.AllRecords;
public int MaxResourceWatcherRecords { get; set; } = ResourceWatcher.DefaultMaxEntries;
[JsonConverter(typeof(SortModeConverter))]
[JsonProperty(Order = int.MaxValue)]
public ISortMode<Mod> SortMode = ISortMode<Mod>.FoldersFirst;
public bool ScaleModSelector { get; set; } = false;
public float ModSelectorAbsoluteSize { get; set; } = Constants.DefaultAbsoluteSize;
public int ModSelectorScaledSize { get; set; } = Constants.DefaultScaledSize;
public bool OpenFoldersByDefault { get; set; } = false;
public int SingleGroupRadioMax { get; set; } = 2;
public string DefaultImportFolder { get; set; } = string.Empty;
public string QuickMoveFolder1 { get; set; } = string.Empty;
public string QuickMoveFolder2 { get; set; } = string.Empty;
public string QuickMoveFolder3 { get; set; } = string.Empty;
public DoubleModifier DeleteModModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
public CollectionsTab.PanelMode CollectionPanel { get; set; } = CollectionsTab.PanelMode.SimpleAssignment;
public TabType SelectedTab { get; set; } = TabType.Settings;
public ChangedItemDrawer.ChangedItemIcon ChangedItemFilter { get; set; } = ChangedItemDrawer.DefaultFlags;
public bool PrintSuccessfulCommandsToChat { get; set; } = true;
public bool FixMainWindow { get; set; } = false;
public bool AutoDeduplicateOnImport { get; set; } = true;
public bool UseFileSystemCompression { get; set; } = true;
public bool EnableHttpApi { get; set; } = true;
public bool ScaleModSelector { get; set; } = false;
public float ModSelectorAbsoluteSize { get; set; } = Constants.DefaultAbsoluteSize;
public int ModSelectorScaledSize { get; set; } = Constants.DefaultScaledSize;
public bool OpenFoldersByDefault { get; set; } = false;
public int SingleGroupRadioMax { get; set; } = 2;
public string DefaultImportFolder { get; set; } = string.Empty;
public string QuickMoveFolder1 { get; set; } = string.Empty;
public string QuickMoveFolder2 { get; set; } = string.Empty;
public string QuickMoveFolder3 { get; set; } = string.Empty;
public DoubleModifier DeleteModModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
public bool PrintSuccessfulCommandsToChat { get; set; } = true;
public bool AutoDeduplicateOnImport { get; set; } = true;
public bool UseFileSystemCompression { get; set; } = true;
public bool EnableHttpApi { get; set; } = true;
public string DefaultModImportPath { get; set; } = string.Empty;
public bool AlwaysOpenDefaultImport { get; set; } = false;
@ -112,9 +91,10 @@ public class Configuration : IPluginConfiguration, ISavable
/// Load the current configuration.
/// Includes adding new colors and migrating from old versions.
/// </summary>
public Configuration(CharacterUtility utility, ConfigMigrationService migrator, SaveService saveService)
public Configuration(CharacterUtility utility, ConfigMigrationService migrator, SaveService saveService, EphemeralConfig ephemeral)
{
_saveService = saveService;
Ephemeral = ephemeral;
Load(utility, migrator);
}
@ -148,12 +128,12 @@ public class Configuration : IPluginConfiguration, ISavable
/// <summary> Save the current configuration. </summary>
public void Save()
=> _saveService.DelaySave(this);
=> _saveService.QueueSave(this);
/// <summary> Contains some default values or boundaries for config values. </summary>
public static class Constants
{
public const int CurrentVersion = 7;
public const int CurrentVersion = 8;
public const float MaxAbsoluteSize = 600;
public const int DefaultAbsoluteSize = 250;
public const float MinAbsoluteSize = 50;

View file

@ -0,0 +1,86 @@
using Dalamud.Interface.Internal.Notifications;
using Newtonsoft.Json;
using OtterGui.Classes;
using Penumbra.Api.Enums;
using Penumbra.Enums;
using Penumbra.Interop.Services;
using Penumbra.Services;
using Penumbra.UI;
using Penumbra.UI.ResourceWatcher;
using Penumbra.UI.Tabs;
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
namespace Penumbra;
public class EphemeralConfig : ISavable
{
[JsonIgnore]
private readonly SaveService _saveService;
public int Version { get; set; } = Configuration.Constants.CurrentVersion;
public int LastSeenVersion { get; set; } = PenumbraChangelog.LastChangelogVersion;
public bool DebugSeparateWindow { get; set; } = false;
public int TutorialStep { get; set; } = 0;
public bool EnableResourceLogging { get; set; } = false;
public string ResourceLoggingFilter { get; set; } = string.Empty;
public bool EnableResourceWatcher { get; set; } = false;
public bool OnlyAddMatchingResources { get; set; } = true;
public ResourceTypeFlag ResourceWatcherResourceTypes { get; set; } = ResourceExtensions.AllResourceTypes;
public ResourceCategoryFlag ResourceWatcherResourceCategories { get; set; } = ResourceExtensions.AllResourceCategories;
public RecordType ResourceWatcherRecordTypes { get; set; } = ResourceWatcher.AllRecords;
public CollectionsTab.PanelMode CollectionPanel { get; set; } = CollectionsTab.PanelMode.SimpleAssignment;
public TabType SelectedTab { get; set; } = TabType.Settings;
public ChangedItemDrawer.ChangedItemIcon ChangedItemFilter { get; set; } = ChangedItemDrawer.DefaultFlags;
public bool FixMainWindow { get; set; } = false;
/// <summary>
/// Load the current configuration.
/// Includes adding new colors and migrating from old versions.
/// </summary>
public EphemeralConfig(SaveService saveService)
{
_saveService = saveService;
Load();
}
private void Load()
{
static void HandleDeserializationError(object? sender, ErrorEventArgs errorArgs)
{
Penumbra.Log.Error(
$"Error parsing Configuration at {errorArgs.ErrorContext.Path}, using default or migrating:\n{errorArgs.ErrorContext.Error}");
errorArgs.ErrorContext.Handled = true;
}
if (File.Exists(_saveService.FileNames.EphemeralConfigFile))
try
{
var text = File.ReadAllText(_saveService.FileNames.EphemeralConfigFile);
JsonConvert.PopulateObject(text, this, new JsonSerializerSettings
{
Error = HandleDeserializationError,
});
}
catch (Exception ex)
{
Penumbra.Messager.NotificationMessage(ex,
"Error reading ephemeral Configuration, reverting to default.",
"Error reading ephemeral Configuration", NotificationType.Error);
}
}
/// <summary> Save the current configuration. </summary>
public void Save()
=> _saveService.DelaySave(this, TimeSpan.FromSeconds(5));
public string ToFilename(FilenameService fileNames)
=> fileNames.EphemeralConfigFile;
public void Save(StreamWriter writer)
{
using var jWriter = new JsonTextWriter(writer) { Formatting = Formatting.Indented };
var serializer = new JsonSerializer { Formatting = Formatting.Indented };
serializer.Serialize(jWriter, this);
}
}

View file

@ -201,7 +201,7 @@ public class Penumbra : IDalamudPlugin
sb.Append(
$"> **`Synchronous Load (Dalamud): `** {(_services.GetRequiredService<DalamudServices>().GetDalamudConfig(DalamudServices.WaitingForPluginsOption, out bool v) ? v.ToString() : "Unknown")}\n");
sb.Append(
$"> **`Logging: `** Log: {_config.EnableResourceLogging}, Watcher: {_config.EnableResourceWatcher} ({_config.MaxResourceWatcherRecords})\n");
$"> **`Logging: `** Log: {_config.Ephemeral.EnableResourceLogging}, Watcher: {_config.Ephemeral.EnableResourceWatcher} ({_config.MaxResourceWatcherRecords})\n");
sb.Append($"> **`Use Ownership: `** {_config.UseOwnerNameForCharacterCollection}\n");
sb.AppendLine("**Mods**");
sb.Append($"> **`Installed Mods: `** {_modManager.Count}\n");

View file

@ -14,6 +14,10 @@ public class BackupService
Backup.CreateAutomaticBackup(logger, new DirectoryInfo(fileNames.ConfigDirectory), files);
}
public static void CreatePermanentBackup(FilenameService fileNames)
=> Backup.CreatePermanentBackup(Penumbra.Log, new DirectoryInfo(fileNames.ConfigDirectory), PenumbraFiles(fileNames),
"pre_ephemeral_config");
// Collect all relevant files for penumbra configuration.
private static IReadOnlyList<FileInfo> PenumbraFiles(FilenameService fileNames)
{

View file

@ -1,14 +1,20 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OtterGui.Classes;
using OtterGui.Filesystem;
using Penumbra.Api.Enums;
using Penumbra.Collections;
using Penumbra.Collections.Manager;
using Penumbra.Enums;
using Penumbra.Interop.Services;
using Penumbra.Mods;
using Penumbra.Mods.Editor;
using Penumbra.Mods.Manager;
using Penumbra.Mods.Subclasses;
using Penumbra.UI;
using Penumbra.UI.Classes;
using Penumbra.UI.ResourceWatcher;
using Penumbra.UI.Tabs;
namespace Penumbra.Services;
@ -26,7 +32,7 @@ public class ConfigMigrationService
public string CurrentCollection = ModCollection.DefaultCollectionName;
public string DefaultCollection = ModCollection.DefaultCollectionName;
public string ForcedCollection = string.Empty;
public Dictionary<string, string> CharacterCollections = new();
public Dictionary<string, string> CharacterCollections = [];
public Dictionary<string, string> ModSortOrder = new();
public bool InvertModListOrder;
public bool SortFoldersFirst;
@ -71,9 +77,41 @@ public class ConfigMigrationService
Version4To5();
Version5To6();
Version6To7();
Version7To8();
AddColors(config, true);
}
// Migrate to ephemeral config.
private void Version7To8()
{
if (_config.Version != 7)
return;
_config.Version = 8;
_config.Ephemeral.Version = 8;
_config.Ephemeral.LastSeenVersion = _data["LastSeenVersion"]?.ToObject<int>() ?? _config.Ephemeral.LastSeenVersion;
_config.Ephemeral.DebugSeparateWindow = _data["DebugSeparateWindow"]?.ToObject<bool>() ?? _config.Ephemeral.DebugSeparateWindow;
_config.Ephemeral.TutorialStep = _data["TutorialStep"]?.ToObject<int>() ?? _config.Ephemeral.TutorialStep;
_config.Ephemeral.EnableResourceLogging = _data["EnableResourceLogging"]?.ToObject<bool>() ?? _config.Ephemeral.EnableResourceLogging;
_config.Ephemeral.ResourceLoggingFilter = _data["ResourceLoggingFilter"]?.ToObject<string>() ?? _config.Ephemeral.ResourceLoggingFilter;
_config.Ephemeral.EnableResourceWatcher = _data["EnableResourceWatcher"]?.ToObject<bool>() ?? _config.Ephemeral.EnableResourceWatcher;
_config.Ephemeral.OnlyAddMatchingResources =
_data["OnlyAddMatchingResources"]?.ToObject<bool>() ?? _config.Ephemeral.OnlyAddMatchingResources;
_config.Ephemeral.ResourceWatcherResourceTypes = _data["ResourceWatcherResourceTypes"]?.ToObject<ResourceTypeFlag>()
?? _config.Ephemeral.ResourceWatcherResourceTypes;
_config.Ephemeral.ResourceWatcherResourceCategories = _data["ResourceWatcherResourceCategories"]?.ToObject<ResourceCategoryFlag>()
?? _config.Ephemeral.ResourceWatcherResourceCategories;
_config.Ephemeral.ResourceWatcherRecordTypes =
_data["ResourceWatcherRecordTypes"]?.ToObject<RecordType>() ?? _config.Ephemeral.ResourceWatcherRecordTypes;
_config.Ephemeral.CollectionPanel = _data["CollectionPanel"]?.ToObject<CollectionsTab.PanelMode>() ?? _config.Ephemeral.CollectionPanel;
_config.Ephemeral.SelectedTab = _data["SelectedTab"]?.ToObject<TabType>() ?? _config.Ephemeral.SelectedTab;
_config.Ephemeral.ChangedItemFilter = _data["ChangedItemFilter"]?.ToObject<ChangedItemDrawer.ChangedItemIcon>()
?? _config.Ephemeral.ChangedItemFilter;
_config.Ephemeral.FixMainWindow = _data["FixMainWindow"]?.ToObject<bool>() ?? _config.Ephemeral.FixMainWindow;
_config.Ephemeral.Save();
}
// Gendered special collections were added.
private void Version6To7()
{
@ -93,8 +131,8 @@ public class ConfigMigrationService
if (_config.Version != 5)
return;
if (_config.TutorialStep == 25)
_config.TutorialStep = 27;
if (_config.Ephemeral.TutorialStep == 25)
_config.Ephemeral.TutorialStep = 27;
_config.Version = 6;
}

View file

@ -11,17 +11,19 @@ public class FilenameService
public readonly string CollectionDirectory;
public readonly string LocalDataDirectory;
public readonly string ConfigFile;
public readonly string EphemeralConfigFile;
public readonly string FilesystemFile;
public readonly string ActiveCollectionsFile;
public FilenameService(DalamudPluginInterface pi)
{
ConfigDirectory = pi.ConfigDirectory.FullName;
CollectionDirectory = Path.Combine(pi.GetPluginConfigDirectory(), "collections");
LocalDataDirectory = Path.Combine(pi.ConfigDirectory.FullName, "mod_data");
CollectionDirectory = Path.Combine(pi.ConfigDirectory.FullName, "collections");
LocalDataDirectory = Path.Combine(pi.ConfigDirectory.FullName, "mod_data");
ConfigFile = pi.ConfigFile.FullName;
FilesystemFile = Path.Combine(pi.GetPluginConfigDirectory(), "sort_order.json");
ActiveCollectionsFile = Path.Combine(pi.ConfigDirectory.FullName, "active_collections.json");
FilesystemFile = Path.Combine(pi.ConfigDirectory.FullName, "sort_order.json");
ActiveCollectionsFile = Path.Combine(pi.ConfigDirectory.FullName, "active_collections.json");
EphemeralConfigFile = Path.Combine(pi.ConfigDirectory.FullName, "ephemeral_config.json");
}
/// <summary> Obtain the path of a collection file given its name.</summary>

View file

@ -95,7 +95,8 @@ public static class ServiceManager
private static IServiceCollection AddConfiguration(this IServiceCollection services)
=> services.AddTransient<ConfigMigrationService>()
.AddSingleton<Configuration>();
.AddSingleton<Configuration>()
.AddSingleton<EphemeralConfig>();
private static IServiceCollection AddCollections(this IServiceCollection services)
=> services.AddSingleton<CollectionStorage>()

View file

@ -70,7 +70,7 @@ public class ChangedItemDrawer : IDisposable
/// <summary> Check if a changed item should be drawn based on its category. </summary>
public bool FilterChangedItem(string name, object? data, LowerString filter)
=> (_config.ChangedItemFilter == AllFlags || _config.ChangedItemFilter.HasFlag(GetCategoryIcon(name, data)))
=> (_config.Ephemeral.ChangedItemFilter == AllFlags || _config.Ephemeral.ChangedItemFilter.HasFlag(GetCategoryIcon(name, data)))
&& (filter.IsEmpty || filter.IsContained(ChangedItemFilterName(name, data)));
/// <summary> Draw the icon corresponding to the category of a changed item. </summary>
@ -172,20 +172,20 @@ public class ChangedItemDrawer : IDisposable
void DrawIcon(ChangedItemIcon type)
{
var icon = _icons[type];
var flag = _config.ChangedItemFilter.HasFlag(type);
var flag = _config.Ephemeral.ChangedItemFilter.HasFlag(type);
ImGui.Image(icon.ImGuiHandle, size, Vector2.Zero, Vector2.One, flag ? Vector4.One : new Vector4(0.6f, 0.3f, 0.3f, 1f));
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
{
_config.ChangedItemFilter = flag ? _config.ChangedItemFilter & ~type : _config.ChangedItemFilter | type;
_config.Save();
_config.Ephemeral.ChangedItemFilter = flag ? _config.Ephemeral.ChangedItemFilter & ~type : _config.Ephemeral.ChangedItemFilter | type;
_config.Ephemeral.Save();
}
using var popup = ImRaii.ContextPopupItem(type.ToString());
if (popup)
if (ImGui.MenuItem("Enable Only This"))
{
_config.ChangedItemFilter = type;
_config.Save();
_config.Ephemeral.ChangedItemFilter = type;
_config.Ephemeral.Save();
ImGui.CloseCurrentPopup();
}
@ -206,12 +206,12 @@ public class ChangedItemDrawer : IDisposable
ImGui.SetCursorPosX(ImGui.GetContentRegionMax().X - size.X);
ImGui.Image(_icons[AllFlags].ImGuiHandle, size, Vector2.Zero, Vector2.One,
_config.ChangedItemFilter == 0 ? new Vector4(0.6f, 0.3f, 0.3f, 1f) :
_config.ChangedItemFilter == AllFlags ? new Vector4(0.75f, 0.75f, 0.75f, 1f) : new Vector4(0.5f, 0.5f, 1f, 1f));
_config.Ephemeral.ChangedItemFilter == 0 ? new Vector4(0.6f, 0.3f, 0.3f, 1f) :
_config.Ephemeral.ChangedItemFilter == AllFlags ? new Vector4(0.75f, 0.75f, 0.75f, 1f) : new Vector4(0.5f, 0.5f, 1f, 1f));
if (ImGui.IsItemClicked())
{
_config.ChangedItemFilter = _config.ChangedItemFilter == AllFlags ? 0 : AllFlags;
_config.Save();
_config.Ephemeral.ChangedItemFilter = _config.Ephemeral.ChangedItemFilter == AllFlags ? 0 : AllFlags;
_config.Ephemeral.Save();
}
}

View file

@ -627,12 +627,20 @@ public class PenumbraChangelog
#endregion
private (int, ChangeLogDisplayType) ConfigData()
=> (_config.LastSeenVersion, _config.ChangeLogDisplayType);
=> (_config.Ephemeral.LastSeenVersion, _config.ChangeLogDisplayType);
private void Save(int version, ChangeLogDisplayType type)
{
_config.LastSeenVersion = version;
_config.ChangeLogDisplayType = type;
_config.Save();
if (_config.Ephemeral.LastSeenVersion != version)
{
_config.Ephemeral.LastSeenVersion = version;
_config.Ephemeral.Save();
}
if (_config.ChangeLogDisplayType != type)
{
_config.ChangeLogDisplayType = type;
_config.Save();
}
}
}

View file

@ -39,7 +39,7 @@ public sealed class ConfigWindow : Window
{
_penumbra = penumbra;
_configTabs = configTabs;
_configTabs.SelectTab = _config.SelectedTab;
_configTabs.SelectTab = _config.Ephemeral.SelectedTab;
}
public override bool DrawConditions()
@ -47,7 +47,7 @@ public sealed class ConfigWindow : Window
public override void PreDraw()
{
if (_config.FixMainWindow)
if (_config.Ephemeral.FixMainWindow)
Flags |= ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove;
else
Flags &= ~(ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove);
@ -99,10 +99,10 @@ public sealed class ConfigWindow : Window
else
{
var type = _configTabs.Draw();
if (type != _config.SelectedTab)
if (type != _config.Ephemeral.SelectedTab)
{
_config.SelectedTab = type;
_config.Save();
_config.Ephemeral.SelectedTab = type;
_config.Ephemeral.Save();
}
}

View file

@ -21,6 +21,7 @@ public class ResourceWatcher : IDisposable, ITab
public const RecordType AllRecords = RecordType.Request | RecordType.ResourceLoad | RecordType.FileLoad | RecordType.Destruction;
private readonly Configuration _config;
private readonly EphemeralConfig _ephemeral;
private readonly ResourceService _resources;
private readonly ResourceLoader _loader;
private readonly ActorService _actors;
@ -35,14 +36,15 @@ public class ResourceWatcher : IDisposable, ITab
{
_actors = actors;
_config = config;
_ephemeral = config.Ephemeral;
_resources = resources;
_loader = loader;
_table = new ResourceWatcherTable(config, _records);
_table = new ResourceWatcherTable(config.Ephemeral, _records);
_resources.ResourceRequested += OnResourceRequested;
_resources.ResourceHandleDestructor += OnResourceDestroyed;
_loader.ResourceLoaded += OnResourceLoaded;
_loader.FileLoaded += OnFileLoaded;
UpdateFilter(_config.ResourceLoggingFilter, false);
UpdateFilter(_ephemeral.ResourceLoggingFilter, false);
_newMaxEntries = _config.MaxResourceWatcherRecords;
}
@ -71,11 +73,11 @@ public class ResourceWatcher : IDisposable, ITab
UpdateRecords();
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + ImGui.GetTextLineHeightWithSpacing() / 2);
var isEnabled = _config.EnableResourceWatcher;
var isEnabled = _ephemeral.EnableResourceWatcher;
if (ImGui.Checkbox("Enable", ref isEnabled))
{
_config.EnableResourceWatcher = isEnabled;
_config.Save();
_ephemeral.EnableResourceWatcher = isEnabled;
_ephemeral.Save();
}
ImGui.SameLine();
@ -85,19 +87,19 @@ public class ResourceWatcher : IDisposable, ITab
Clear();
ImGui.SameLine();
var onlyMatching = _config.OnlyAddMatchingResources;
var onlyMatching = _ephemeral.OnlyAddMatchingResources;
if (ImGui.Checkbox("Store Only Matching", ref onlyMatching))
{
_config.OnlyAddMatchingResources = onlyMatching;
_config.Save();
_ephemeral.OnlyAddMatchingResources = onlyMatching;
_ephemeral.Save();
}
ImGui.SameLine();
var writeToLog = _config.EnableResourceLogging;
var writeToLog = _ephemeral.EnableResourceLogging;
if (ImGui.Checkbox("Write to Log", ref writeToLog))
{
_config.EnableResourceLogging = writeToLog;
_config.Save();
_ephemeral.EnableResourceLogging = writeToLog;
_ephemeral.Save();
}
ImGui.SameLine();
@ -136,8 +138,8 @@ public class ResourceWatcher : IDisposable, ITab
if (config)
{
_config.ResourceLoggingFilter = newString;
_config.Save();
_ephemeral.ResourceLoggingFilter = newString;
_ephemeral.Save();
}
}
@ -196,20 +198,20 @@ public class ResourceWatcher : IDisposable, ITab
Utf8GamePath original,
GetResourceParameters* parameters, ref bool sync, ref ResourceHandle* returnValue)
{
if (_config.EnableResourceLogging && FilterMatch(original.Path, out var match))
if (_ephemeral.EnableResourceLogging && FilterMatch(original.Path, out var match))
Penumbra.Log.Information($"[ResourceLoader] [REQ] {match} was requested {(sync ? "synchronously." : "asynchronously.")}");
if (!_config.EnableResourceWatcher)
if (!_ephemeral.EnableResourceWatcher)
return;
var record = Record.CreateRequest(original.Path, sync);
if (!_config.OnlyAddMatchingResources || _table.WouldBeVisible(record))
if (!_ephemeral.OnlyAddMatchingResources || _table.WouldBeVisible(record))
_newRecords.Enqueue(record);
}
private unsafe void OnResourceLoaded(ResourceHandle* handle, Utf8GamePath path, FullPath? manipulatedPath, ResolveData data)
{
if (_config.EnableResourceLogging)
if (_ephemeral.EnableResourceLogging)
{
var log = FilterMatch(path.Path, out var name);
var name2 = string.Empty;
@ -224,41 +226,41 @@ public class ResourceWatcher : IDisposable, ITab
}
}
if (!_config.EnableResourceWatcher)
if (!_ephemeral.EnableResourceWatcher)
return;
var record = manipulatedPath == null
? Record.CreateDefaultLoad(path.Path, handle, data.ModCollection, Name(data))
: Record.CreateLoad(manipulatedPath.Value.InternalName, path.Path, handle, data.ModCollection, Name(data));
if (!_config.OnlyAddMatchingResources || _table.WouldBeVisible(record))
if (!_ephemeral.OnlyAddMatchingResources || _table.WouldBeVisible(record))
_newRecords.Enqueue(record);
}
private unsafe void OnFileLoaded(ResourceHandle* resource, ByteString path, bool success, bool custom, ByteString _)
{
if (_config.EnableResourceLogging && FilterMatch(path, out var match))
if (_ephemeral.EnableResourceLogging && FilterMatch(path, out var match))
Penumbra.Log.Information(
$"[ResourceLoader] [FILE] [{resource->FileType}] Loading {match} from {(custom ? "local files" : "SqPack")} into 0x{(ulong)resource:X} returned {success}.");
if (!_config.EnableResourceWatcher)
if (!_ephemeral.EnableResourceWatcher)
return;
var record = Record.CreateFileLoad(path, resource, success, custom);
if (!_config.OnlyAddMatchingResources || _table.WouldBeVisible(record))
if (!_ephemeral.OnlyAddMatchingResources || _table.WouldBeVisible(record))
_newRecords.Enqueue(record);
}
private unsafe void OnResourceDestroyed(ResourceHandle* resource)
{
if (_config.EnableResourceLogging && FilterMatch(resource->FileName(), out var match))
if (_ephemeral.EnableResourceLogging && FilterMatch(resource->FileName(), out var match))
Penumbra.Log.Information(
$"[ResourceLoader] [DEST] [{resource->FileType}] Destroyed {match} at 0x{(ulong)resource:X}.");
if (!_config.EnableResourceWatcher)
if (!_ephemeral.EnableResourceWatcher)
return;
var record = Record.CreateDestruction(resource);
if (!_config.OnlyAddMatchingResources || _table.WouldBeVisible(record))
if (!_ephemeral.OnlyAddMatchingResources || _table.WouldBeVisible(record))
_newRecords.Enqueue(record);
}

View file

@ -13,7 +13,7 @@ namespace Penumbra.UI.ResourceWatcher;
internal sealed class ResourceWatcherTable : Table<Record>
{
public ResourceWatcherTable(Configuration config, IReadOnlyCollection<Record> records)
public ResourceWatcherTable(EphemeralConfig config, IReadOnlyCollection<Record> records)
: base("##records",
records,
new PathColumn { Label = "Path" },
@ -86,9 +86,9 @@ internal sealed class ResourceWatcherTable : Table<Record>
private sealed class RecordTypeColumn : ColumnFlags<RecordType, Record>
{
private readonly Configuration _config;
private readonly EphemeralConfig _config;
public RecordTypeColumn(Configuration config)
public RecordTypeColumn(EphemeralConfig config)
{
AllFlags = ResourceWatcher.AllRecords;
_config = config;
@ -174,9 +174,9 @@ internal sealed class ResourceWatcherTable : Table<Record>
private sealed class ResourceCategoryColumn : ColumnFlags<ResourceCategoryFlag, Record>
{
private readonly Configuration _config;
private readonly EphemeralConfig _config;
public ResourceCategoryColumn(Configuration config)
public ResourceCategoryColumn(EphemeralConfig config)
{
_config = config;
AllFlags = ResourceExtensions.AllResourceCategories;
@ -209,9 +209,9 @@ internal sealed class ResourceWatcherTable : Table<Record>
private sealed class ResourceTypeColumn : ColumnFlags<ResourceTypeFlag, Record>
{
private readonly Configuration _config;
private readonly EphemeralConfig _config;
public ResourceTypeColumn(Configuration config)
public ResourceTypeColumn(EphemeralConfig config)
{
_config = config;
AllFlags = Enum.GetValues<ResourceTypeFlag>().Aggregate((v, f) => v | f);

View file

@ -16,7 +16,7 @@ namespace Penumbra.UI.Tabs;
public class CollectionsTab : IDisposable, ITab
{
private readonly Configuration _config;
private readonly EphemeralConfig _config;
private readonly CollectionSelector _selector;
private readonly CollectionPanel _panel;
private readonly TutorialService _tutorial;
@ -42,7 +42,7 @@ public class CollectionsTab : IDisposable, ITab
public CollectionsTab(DalamudPluginInterface pi, Configuration configuration, CommunicatorService communicator,
CollectionManager collectionManager, ModStorage modStorage, ActorService actors, ITargetManager targets, TutorialService tutorial)
{
_config = configuration;
_config = configuration.Ephemeral;
_tutorial = tutorial;
_selector = new CollectionSelector(configuration, communicator, collectionManager.Storage, collectionManager.Active, _tutorial);
_panel = new CollectionPanel(pi, communicator, collectionManager, _selector, actors, targets, modStorage);

View file

@ -115,7 +115,7 @@ public class DebugTab : Window, ITab
=> "Debug"u8;
public bool IsVisible
=> _config.DebugMode && !_config.DebugSeparateWindow;
=> _config is { DebugMode: true, Ephemeral.DebugSeparateWindow: false };
#if DEBUG
private const string DebugVersionString = "(Debug)";
@ -201,12 +201,12 @@ public class DebugTab : Window, ITab
if (!ImGui.CollapsingHeader("General"))
return;
var separateWindow = _config.DebugSeparateWindow;
var separateWindow = _config.Ephemeral.DebugSeparateWindow;
if (ImGui.Checkbox("Draw as Separate Window", ref separateWindow))
{
IsOpen = true;
_config.DebugSeparateWindow = separateWindow;
_config.Save();
IsOpen = true;
_config.Ephemeral.DebugSeparateWindow = separateWindow;
_config.Ephemeral.Save();
}
using (var table = Table("##DebugGeneralTable", 2, ImGuiTableFlags.SizingFixedFit))
@ -949,11 +949,11 @@ public class DebugTab : Window, ITab
=> DrawContent();
public override bool DrawConditions()
=> _config.DebugMode && _config.DebugSeparateWindow;
=> _config.DebugMode && _config.Ephemeral.DebugSeparateWindow;
public override void OnClose()
{
_config.DebugSeparateWindow = false;
_config.Save();
_config.Ephemeral.DebugSeparateWindow = false;
_config.Ephemeral.Save();
}
}

View file

@ -78,8 +78,8 @@ public class SettingsTab : ITab
return;
DrawEnabledBox();
Checkbox("Lock Main Window", "Prevent the main window from being resized or moved.", _config.FixMainWindow,
v => _config.FixMainWindow = v);
EphemeralCheckbox("Lock Main Window", "Prevent the main window from being resized or moved.", _config.Ephemeral.FixMainWindow,
v => _config.Ephemeral.FixMainWindow = v);
ImGui.NewLine();
DrawRootFolder();
@ -107,6 +107,21 @@ public class SettingsTab : ITab
ImGuiUtil.LabeledHelpMarker(label, tooltip);
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private void EphemeralCheckbox(string label, string tooltip, bool current, Action<bool> setter)
{
using var id = ImRaii.PushId(label);
var tmp = current;
if (ImGui.Checkbox(string.Empty, ref tmp) && tmp != current)
{
setter(tmp);
_config.Ephemeral.Save();
}
ImGui.SameLine();
ImGuiUtil.LabeledHelpMarker(label, tooltip);
}
#region Main Settings
/// <summary>
@ -384,7 +399,10 @@ public class SettingsTab : ITab
{
_config.HideChangedItemFilters = v;
if (v)
_config.ChangedItemFilter = ChangedItemDrawer.AllFlags;
{
_config.Ephemeral.ChangedItemFilter = ChangedItemDrawer.AllFlags;
_config.Ephemeral.Save();
}
});
Checkbox("Hide Priority Numbers in Mod Selector",
"Hides the bracketed non-zero priority numbers displayed in the mod selector when there is enough space for them.",
@ -863,8 +881,8 @@ public class SettingsTab : ITab
ImGui.SetCursorPos(new Vector2(xPos, 3 * ImGui.GetFrameHeightWithSpacing()));
if (ImGui.Button("Restart Tutorial", new Vector2(width, 0)))
{
_config.TutorialStep = 0;
_config.Save();
_config.Ephemeral.TutorialStep = 0;
_config.Ephemeral.Save();
}
ImGui.SetCursorPos(new Vector2(xPos, 4 * ImGui.GetFrameHeightWithSpacing()));

View file

@ -55,10 +55,10 @@ public class TutorialService
+ " - 'furniture': most indoor furniture, does not currently work outdoors\n"
+ " - any specific actor name to redraw all actors of that exactly matching name.";
private readonly Configuration _config;
private readonly Tutorial _tutorial;
private readonly EphemeralConfig _config;
private readonly Tutorial _tutorial;
public TutorialService(Configuration config)
public TutorialService(EphemeralConfig config)
{
_config = config;
_tutorial = new Tutorial()