summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/StateTracking/Snapshots
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI/Framework/StateTracking/Snapshots')
-rw-r--r--src/SMAPI/Framework/StateTracking/Snapshots/LocationSnapshot.cs59
-rw-r--r--src/SMAPI/Framework/StateTracking/Snapshots/PlayerSnapshot.cs53
-rw-r--r--src/SMAPI/Framework/StateTracking/Snapshots/WatcherSnapshot.cs66
-rw-r--r--src/SMAPI/Framework/StateTracking/Snapshots/WorldLocationsSnapshot.cs52
4 files changed, 230 insertions, 0 deletions
diff --git a/src/SMAPI/Framework/StateTracking/Snapshots/LocationSnapshot.cs b/src/SMAPI/Framework/StateTracking/Snapshots/LocationSnapshot.cs
new file mode 100644
index 00000000..d3029540
--- /dev/null
+++ b/src/SMAPI/Framework/StateTracking/Snapshots/LocationSnapshot.cs
@@ -0,0 +1,59 @@
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+using StardewValley;
+using StardewValley.Buildings;
+using StardewValley.TerrainFeatures;
+
+namespace StardewModdingAPI.Framework.StateTracking.Snapshots
+{
+ /// <summary>A frozen snapshot of a tracked game location.</summary>
+ internal class LocationSnapshot
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The tracked location.</summary>
+ public GameLocation Location { get; }
+
+ /// <summary>Tracks added or removed buildings.</summary>
+ public SnapshotListDiff<Building> Buildings { get; } = new SnapshotListDiff<Building>();
+
+ /// <summary>Tracks added or removed debris.</summary>
+ public SnapshotListDiff<Debris> Debris { get; } = new SnapshotListDiff<Debris>();
+
+ /// <summary>Tracks added or removed large terrain features.</summary>
+ public SnapshotListDiff<LargeTerrainFeature> LargeTerrainFeatures { get; } = new SnapshotListDiff<LargeTerrainFeature>();
+
+ /// <summary>Tracks added or removed NPCs.</summary>
+ public SnapshotListDiff<NPC> Npcs { get; } = new SnapshotListDiff<NPC>();
+
+ /// <summary>Tracks added or removed objects.</summary>
+ public SnapshotListDiff<KeyValuePair<Vector2, Object>> Objects { get; } = new SnapshotListDiff<KeyValuePair<Vector2, Object>>();
+
+ /// <summary>Tracks added or removed terrain features.</summary>
+ public SnapshotListDiff<KeyValuePair<Vector2, TerrainFeature>> TerrainFeatures { get; } = new SnapshotListDiff<KeyValuePair<Vector2, TerrainFeature>>();
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Construct an instance.</summary>
+ /// <param name="location">The tracked location.</param>
+ public LocationSnapshot(GameLocation location)
+ {
+ this.Location = location;
+ }
+
+ /// <summary>Update the tracked values.</summary>
+ /// <param name="watcher">The watcher to snapshot.</param>
+ public void Update(LocationTracker watcher)
+ {
+ this.Buildings.Update(watcher.BuildingsWatcher);
+ this.Debris.Update(watcher.DebrisWatcher);
+ this.LargeTerrainFeatures.Update(watcher.LargeTerrainFeaturesWatcher);
+ this.Npcs.Update(watcher.NpcsWatcher);
+ this.Objects.Update(watcher.ObjectsWatcher);
+ this.TerrainFeatures.Update(watcher.TerrainFeaturesWatcher);
+ }
+ }
+}
diff --git a/src/SMAPI/Framework/StateTracking/Snapshots/PlayerSnapshot.cs b/src/SMAPI/Framework/StateTracking/Snapshots/PlayerSnapshot.cs
new file mode 100644
index 00000000..7bcd9f82
--- /dev/null
+++ b/src/SMAPI/Framework/StateTracking/Snapshots/PlayerSnapshot.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using StardewModdingAPI.Enums;
+using StardewModdingAPI.Events;
+using StardewValley;
+
+namespace StardewModdingAPI.Framework.StateTracking.Snapshots
+{
+ /// <summary>A frozen snapshot of a tracked player.</summary>
+ internal class PlayerSnapshot
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The player being tracked.</summary>
+ public Farmer Player { get; }
+
+ /// <summary>The player's current location.</summary>
+ public SnapshotDiff<GameLocation> Location { get; } = new SnapshotDiff<GameLocation>();
+
+ /// <summary>Tracks changes to the player's skill levels.</summary>
+ public IDictionary<SkillType, SnapshotDiff<int>> Skills { get; } =
+ Enum
+ .GetValues(typeof(SkillType))
+ .Cast<SkillType>()
+ .ToDictionary(skill => skill, skill => new SnapshotDiff<int>());
+
+ /// <summary>Get a list of inventory changes.</summary>
+ public IEnumerable<ItemStackChange> InventoryChanges { get; private set; }
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Construct an instance.</summary>
+ /// <param name="player">The player being tracked.</param>
+ public PlayerSnapshot(Farmer player)
+ {
+ this.Player = player;
+ }
+
+ /// <summary>Update the tracked values.</summary>
+ /// <param name="watcher">The player watcher to snapshot.</param>
+ public void Update(PlayerTracker watcher)
+ {
+ this.Location.Update(watcher.LocationWatcher);
+ foreach (var pair in this.Skills)
+ pair.Value.Update(watcher.SkillWatchers[pair.Key]);
+ this.InventoryChanges = watcher.GetInventoryChanges().ToArray();
+ }
+ }
+}
diff --git a/src/SMAPI/Framework/StateTracking/Snapshots/WatcherSnapshot.cs b/src/SMAPI/Framework/StateTracking/Snapshots/WatcherSnapshot.cs
new file mode 100644
index 00000000..cf51e040
--- /dev/null
+++ b/src/SMAPI/Framework/StateTracking/Snapshots/WatcherSnapshot.cs
@@ -0,0 +1,66 @@
+using Microsoft.Xna.Framework;
+using StardewValley;
+using StardewValley.Menus;
+
+namespace StardewModdingAPI.Framework.StateTracking.Snapshots
+{
+ /// <summary>A frozen snapshot of the game state watchers.</summary>
+ internal class WatcherSnapshot
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>Tracks changes to the window size.</summary>
+ public SnapshotDiff<Point> WindowSize { get; } = new SnapshotDiff<Point>();
+
+ /// <summary>Tracks changes to the current player.</summary>
+ public PlayerSnapshot CurrentPlayer { get; private set; }
+
+ /// <summary>Tracks changes to the time of day (in 24-hour military format).</summary>
+ public SnapshotDiff<int> Time { get; } = new SnapshotDiff<int>();
+
+ /// <summary>Tracks changes to the save ID.</summary>
+ public SnapshotDiff<ulong> SaveID { get; } = new SnapshotDiff<ulong>();
+
+ /// <summary>Tracks changes to the game's locations.</summary>
+ public WorldLocationsSnapshot Locations { get; } = new WorldLocationsSnapshot();
+
+ /// <summary>Tracks changes to <see cref="Game1.activeClickableMenu"/>.</summary>
+ public SnapshotDiff<IClickableMenu> ActiveMenu { get; } = new SnapshotDiff<IClickableMenu>();
+
+ /// <summary>Tracks changes to the cursor position.</summary>
+ public SnapshotDiff<ICursorPosition> Cursor { get; } = new SnapshotDiff<ICursorPosition>();
+
+ /// <summary>Tracks changes to the mouse wheel scroll.</summary>
+ public SnapshotDiff<int> MouseWheelScroll { get; } = new SnapshotDiff<int>();
+
+ /// <summary>Tracks changes to the content locale.</summary>
+ public SnapshotDiff<LocalizedContentManager.LanguageCode> Locale { get; } = new SnapshotDiff<LocalizedContentManager.LanguageCode>();
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Update the tracked values.</summary>
+ /// <param name="watchers">The watchers to snapshot.</param>
+ public void Update(WatcherCore watchers)
+ {
+ // update player instance
+ if (watchers.CurrentPlayerTracker == null)
+ this.CurrentPlayer = null;
+ else if (watchers.CurrentPlayerTracker.Player != this.CurrentPlayer?.Player)
+ this.CurrentPlayer = new PlayerSnapshot(watchers.CurrentPlayerTracker.Player);
+
+ // update snapshots
+ this.WindowSize.Update(watchers.WindowSizeWatcher);
+ this.Locale.Update(watchers.LocaleWatcher);
+ this.CurrentPlayer?.Update(watchers.CurrentPlayerTracker);
+ this.Time.Update(watchers.TimeWatcher);
+ this.SaveID.Update(watchers.SaveIdWatcher);
+ this.Locations.Update(watchers.LocationsWatcher);
+ this.ActiveMenu.Update(watchers.ActiveMenuWatcher);
+ this.Cursor.Update(watchers.CursorWatcher);
+ this.MouseWheelScroll.Update(watchers.MouseWheelScrollWatcher);
+ }
+ }
+}
diff --git a/src/SMAPI/Framework/StateTracking/Snapshots/WorldLocationsSnapshot.cs b/src/SMAPI/Framework/StateTracking/Snapshots/WorldLocationsSnapshot.cs
new file mode 100644
index 00000000..73ed2d8f
--- /dev/null
+++ b/src/SMAPI/Framework/StateTracking/Snapshots/WorldLocationsSnapshot.cs
@@ -0,0 +1,52 @@
+using System.Collections.Generic;
+using System.Linq;
+using StardewModdingAPI.Framework.StateTracking.Comparers;
+using StardewValley;
+
+namespace StardewModdingAPI.Framework.StateTracking.Snapshots
+{
+ /// <summary>A frozen snapshot of the tracked game locations.</summary>
+ internal class WorldLocationsSnapshot
+ {
+ /*********
+ ** Fields
+ *********/
+ /// <summary>A map of tracked locations.</summary>
+ private readonly Dictionary<GameLocation, LocationSnapshot> LocationsDict = new Dictionary<GameLocation, LocationSnapshot>(new ObjectReferenceComparer<GameLocation>());
+
+
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>Tracks changes to the location list.</summary>
+ public SnapshotListDiff<GameLocation> LocationList { get; } = new SnapshotListDiff<GameLocation>();
+
+ /// <summary>The tracked locations.</summary>
+ public IEnumerable<LocationSnapshot> Locations => this.LocationsDict.Values;
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Update the tracked values.</summary>
+ /// <param name="watcher">The watcher to snapshot.</param>
+ public void Update(WorldLocationsTracker watcher)
+ {
+ // update location list
+ this.LocationList.Update(watcher.IsLocationListChanged, watcher.Added, watcher.Removed);
+
+ // remove missing locations
+ foreach (var key in this.LocationsDict.Keys.Where(key => !watcher.HasLocationTracker(key)).ToArray())
+ this.LocationsDict.Remove(key);
+
+ // update locations
+ foreach (LocationTracker locationWatcher in watcher.Locations)
+ {
+ if (!this.LocationsDict.TryGetValue(locationWatcher.Location, out LocationSnapshot snapshot))
+ this.LocationsDict[locationWatcher.Location] = snapshot = new LocationSnapshot(locationWatcher.Location);
+
+ snapshot.Update(locationWatcher);
+ }
+ }
+ }
+}