From 6438cbe4370b0dabde7711d5fde81a0892baeb94 Mon Sep 17 00:00:00 2001 From: EmoSaru Date: Sun, 10 May 2026 12:28:06 -0700 Subject: [PATCH] Persist tracking settings as defaults and seed them on new pack load (issue #83) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the user toggles a tracking setting via the UI (which binds directly to SessionSettings), the change now propagates back to ApplicationSettings' seed fields and writes to application_settings.json — so the preference survives restart and becomes the default for future sessions. When a new pack/variant is activated, SessionSettings is seeded from the saved defaults before init.lua executes, so pack scripts start from the user's preferences and may optionally override them. Reloading the same pack leaves the current settings unchanged (no seed reset). Pack-script-driven changes (i.e. those made while PackageLoader.IsLoading is true) are suppressed from writing the seeds, so init.lua cannot accidentally overwrite the user's saved preferences. Co-Authored-By: Claude Sonnet 4.6 --- EmoTracker.Data/ApplicationSettings.cs | 52 +++++++++++++++++++ EmoTracker.Data/Sessions/PackageLoader.cs | 8 +++ EmoTracker.Data/Sessions/SessionSettings.cs | 10 ++++ .../Sessions/TrackerState.PackageOps.cs | 5 ++ 4 files changed, 75 insertions(+) diff --git a/EmoTracker.Data/ApplicationSettings.cs b/EmoTracker.Data/ApplicationSettings.cs index c3bf92f..1f71dd8 100644 --- a/EmoTracker.Data/ApplicationSettings.cs +++ b/EmoTracker.Data/ApplicationSettings.cs @@ -86,6 +86,10 @@ Sessions.SessionSettings ActiveSessionSettings /// Called from 's adoption ctor /// so a primary state inherits the user's pre-existing preferences /// loaded from ApplicationSettings.json. + /// Also called from + /// to reset settings to the saved defaults before init.lua runs, + /// ensuring pack scripts start from the user's preferences and may + /// optionally override them. /// internal void SeedIntoSession(Sessions.SessionSettings target) { @@ -97,6 +101,54 @@ internal void SeedIntoSession(Sessions.SessionSettings target) target.PinLocationsOnItemCapture = mbSeedPinLocationsOnItemCapture; } + /// + /// Called by when a tracked + /// property changes, so UI-driven setting changes are persisted to + /// ApplicationSettings.json as the new defaults for future + /// sessions / pack loads. + /// + /// + /// No-ops when called while a pack is loading (i.e. + /// is true) to avoid + /// init.lua-driven changes overwriting the user's saved preferences. + /// + /// + internal void SyncSeedsFromSession(Sessions.SessionSettings source) + { + if (source == null) return; + if (Sessions.PackageLoader.IsLoading) return; + + bool changed = false; + if (mbSeedIgnoreAllLogic != source.IgnoreAllLogic) + { + mbSeedIgnoreAllLogic = source.IgnoreAllLogic; + changed = true; + } + if (mbSeedDisplayAllLocations != source.DisplayAllLocations) + { + mbSeedDisplayAllLocations = source.DisplayAllLocations; + changed = true; + } + if (mbSeedAlwaysAllowClearing != source.AlwaysAllowClearing) + { + mbSeedAlwaysAllowClearing = source.AlwaysAllowClearing; + changed = true; + } + if (mbSeedAutoUnpinLocationsOnClear != source.AutoUnpinLocationsOnClear) + { + mbSeedAutoUnpinLocationsOnClear = source.AutoUnpinLocationsOnClear; + changed = true; + } + if (mbSeedPinLocationsOnItemCapture != source.PinLocationsOnItemCapture) + { + mbSeedPinLocationsOnItemCapture = source.PinLocationsOnItemCapture; + changed = true; + } + + if (changed) + WriteSettings(); + } + public bool IgnoreAllLogic { get diff --git a/EmoTracker.Data/Sessions/PackageLoader.cs b/EmoTracker.Data/Sessions/PackageLoader.cs index a633562..e5379e2 100644 --- a/EmoTracker.Data/Sessions/PackageLoader.cs +++ b/EmoTracker.Data/Sessions/PackageLoader.cs @@ -75,6 +75,14 @@ public PackageLoadEventArgs(TrackerState target, IGamePackage package, IGamePack [ThreadStatic] static bool mInProgress; + /// + /// True while is executing on this thread. + /// Used by to + /// suppress seed-writes driven by pack-script (init.lua) changes, + /// so only explicit user UI changes update the saved defaults. + /// + internal static bool IsLoading => mInProgress; + /// /// Loads (with optional ) /// into 's catalogs. Caller is responsible for diff --git a/EmoTracker.Data/Sessions/SessionSettings.cs b/EmoTracker.Data/Sessions/SessionSettings.cs index 72b648e..089f1fa 100644 --- a/EmoTracker.Data/Sessions/SessionSettings.cs +++ b/EmoTracker.Data/Sessions/SessionSettings.cs @@ -54,15 +54,19 @@ public partial class SessionSettings : TransactableModelTypeBase public partial bool IgnoreAllLogic { get; set; } [KVMutable] + [OnChanged(nameof(SyncSeedsToApplicationSettings))] public partial bool DisplayAllLocations { get; set; } [KVMutable] + [OnChanged(nameof(SyncSeedsToApplicationSettings))] public partial bool AlwaysAllowClearing { get; set; } [KVMutable] + [OnChanged(nameof(SyncSeedsToApplicationSettings))] public partial bool AutoUnpinLocationsOnClear { get; set; } [KVMutable] + [OnChanged(nameof(SyncSeedsToApplicationSettings))] public partial bool PinLocationsOnItemCapture { get; set; } [KVMutable] @@ -111,6 +115,12 @@ protected void OnIgnoreAllLogicChanged() // ApplicationSettings.IgnoreAllLogic's setter. var state = OwnerState as TrackerState; state?.Locations.RefreshAccessibility(); + SyncSeedsToApplicationSettings(); + } + + protected void SyncSeedsToApplicationSettings() + { + ApplicationSettings.Instance?.SyncSeedsFromSession(this); } // ----------- Fork support --------------------------------------------- diff --git a/EmoTracker.Data/Sessions/TrackerState.PackageOps.cs b/EmoTracker.Data/Sessions/TrackerState.PackageOps.cs index 58615af..9c94ae1 100644 --- a/EmoTracker.Data/Sessions/TrackerState.PackageOps.cs +++ b/EmoTracker.Data/Sessions/TrackerState.PackageOps.cs @@ -134,6 +134,11 @@ public void ActivatePackage(IGamePackage package, IGamePackageVariant variant) PackageManager.Instance.RefreshActiveState(); NotifyPropertyChanged(nameof(ActiveVariantUID)); + // Reset tracking settings to the user's saved defaults before + // running init.lua, so pack scripts start from the user's + // preferences and may optionally override them (issue #83). + ApplicationSettings.Instance.SeedIntoSession(Settings); + PackageLoader.LoadInto(this, package, variant); } finally