diff options
Diffstat (limited to 'src/SMAPI/Framework/StateTracking')
18 files changed, 90 insertions, 78 deletions
diff --git a/src/SMAPI/Framework/StateTracking/ChestTracker.cs b/src/SMAPI/Framework/StateTracking/ChestTracker.cs index 65f58ee7..c33a7498 100644 --- a/src/SMAPI/Framework/StateTracking/ChestTracker.cs +++ b/src/SMAPI/Framework/StateTracking/ChestTracker.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using StardewModdingAPI.Framework.StateTracking.Comparers; using StardewModdingAPI.Framework.StateTracking.FieldWatchers; @@ -18,10 +19,10 @@ namespace StardewModdingAPI.Framework.StateTracking private readonly IDictionary<Item, int> StackSizes; /// <summary>Items added since the last update.</summary> - private readonly HashSet<Item> Added = new HashSet<Item>(new ObjectReferenceComparer<Item>()); + private readonly HashSet<Item> Added = new(new ObjectReferenceComparer<Item>()); /// <summary>Items removed since the last update.</summary> - private readonly HashSet<Item> Removed = new HashSet<Item>(new ObjectReferenceComparer<Item>()); + private readonly HashSet<Item> Removed = new(new ObjectReferenceComparer<Item>()); /// <summary>The underlying inventory watcher.</summary> private readonly ICollectionWatcher<Item> InventoryWatcher; @@ -84,7 +85,7 @@ namespace StardewModdingAPI.Framework.StateTracking /// <summary>Get the inventory changes since the last update, if anything changed.</summary> /// <param name="changes">The inventory changes, or <c>null</c> if nothing changed.</param> /// <returns>Returns whether anything changed.</returns> - public bool TryGetInventoryChanges(out SnapshotItemListDiff changes) + public bool TryGetInventoryChanges([NotNullWhen(true)] out SnapshotItemListDiff? changes) { return SnapshotItemListDiff.TryGetChanges(added: this.Added, removed: this.Removed, stackSizes: this.StackSizes, out changes); } diff --git a/src/SMAPI/Framework/StateTracking/Comparers/EquatableComparer.cs b/src/SMAPI/Framework/StateTracking/Comparers/EquatableComparer.cs index a96ffdb6..9d8559b4 100644 --- a/src/SMAPI/Framework/StateTracking/Comparers/EquatableComparer.cs +++ b/src/SMAPI/Framework/StateTracking/Comparers/EquatableComparer.cs @@ -15,7 +15,7 @@ namespace StardewModdingAPI.Framework.StateTracking.Comparers /// <returns>true if the specified objects are equal; otherwise, false.</returns> /// <param name="x">The first object to compare.</param> /// <param name="y">The second object to compare.</param> - public bool Equals(T x, T y) + public bool Equals(T? x, T? y) { if (x == null) return y == null; diff --git a/src/SMAPI/Framework/StateTracking/Comparers/GenericEqualsComparer.cs b/src/SMAPI/Framework/StateTracking/Comparers/GenericEqualsComparer.cs index cc1d6553..41b17e10 100644 --- a/src/SMAPI/Framework/StateTracking/Comparers/GenericEqualsComparer.cs +++ b/src/SMAPI/Framework/StateTracking/Comparers/GenericEqualsComparer.cs @@ -14,7 +14,7 @@ namespace StardewModdingAPI.Framework.StateTracking.Comparers /// <returns>true if the specified objects are equal; otherwise, false.</returns> /// <param name="x">The first object to compare.</param> /// <param name="y">The second object to compare.</param> - public bool Equals(T x, T y) + public bool Equals(T? x, T? y) { if (x == null) return y == null; diff --git a/src/SMAPI/Framework/StateTracking/Comparers/ObjectReferenceComparer.cs b/src/SMAPI/Framework/StateTracking/Comparers/ObjectReferenceComparer.cs index ef9adafb..e6ece854 100644 --- a/src/SMAPI/Framework/StateTracking/Comparers/ObjectReferenceComparer.cs +++ b/src/SMAPI/Framework/StateTracking/Comparers/ObjectReferenceComparer.cs @@ -14,7 +14,7 @@ namespace StardewModdingAPI.Framework.StateTracking.Comparers /// <returns>true if the specified objects are equal; otherwise, false.</returns> /// <param name="x">The first object to compare.</param> /// <param name="y">The second object to compare.</param> - public bool Equals(T x, T y) + public bool Equals(T? x, T? y) { return object.ReferenceEquals(x, y); } diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs index 32ec8c7e..256370ce 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs @@ -17,10 +17,10 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers private HashSet<TValue> LastValues; /// <summary>The pairs added since the last reset.</summary> - private readonly List<TValue> AddedImpl = new List<TValue>(); + private readonly List<TValue> AddedImpl = new(); /// <summary>The pairs removed since the last reset.</summary> - private readonly List<TValue> RemovedImpl = new List<TValue>(); + private readonly List<TValue> RemovedImpl = new(); /********* diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableWatcher.cs index 5ca4b9f4..5f76fe0a 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableWatcher.cs @@ -40,7 +40,8 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers { this.GetValue = getValue; this.Comparer = comparer; - this.PreviousValue = getValue(); + this.CurrentValue = getValue(); + this.PreviousValue = this.CurrentValue; } /// <summary>Update the current value if needed.</summary> diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/ImmutableCollectionWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/ImmutableCollectionWatcher.cs index 30e6274f..84340fbf 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/ImmutableCollectionWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/ImmutableCollectionWatcher.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers @@ -10,16 +11,16 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers ** Accessors *********/ /// <summary>A singleton collection watcher instance.</summary> - public static ImmutableCollectionWatcher<TValue> Instance { get; } = new ImmutableCollectionWatcher<TValue>(); + public static ImmutableCollectionWatcher<TValue> Instance { get; } = new(); /// <summary>Whether the collection changed since the last reset.</summary> public bool IsChanged { get; } = false; /// <summary>The values added since the last reset.</summary> - public IEnumerable<TValue> Added { get; } = new TValue[0]; + public IEnumerable<TValue> Added { get; } = Array.Empty<TValue>(); /// <summary>The values removed since the last reset.</summary> - public IEnumerable<TValue> Removed { get; } = new TValue[0]; + public IEnumerable<TValue> Removed { get; } = Array.Empty<TValue>(); /********* diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetCollectionWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetCollectionWatcher.cs index 21e84c47..676c9fb4 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetCollectionWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetCollectionWatcher.cs @@ -15,10 +15,10 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers private readonly NetCollection<TValue> Field; /// <summary>The pairs added since the last reset.</summary> - private readonly List<TValue> AddedImpl = new List<TValue>(); + private readonly List<TValue> AddedImpl = new(); /// <summary>The pairs removed since the last reset.</summary> - private readonly List<TValue> RemovedImpl = new List<TValue>(); + private readonly List<TValue> RemovedImpl = new(); /********* diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetDictionaryWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetDictionaryWatcher.cs index e6882f7e..f55e4cea 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetDictionaryWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetDictionaryWatcher.cs @@ -10,6 +10,7 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// <typeparam name="TSerialDict">The serializable dictionary type that can store the keys and values.</typeparam> /// <typeparam name="TSelf">The net field instance type.</typeparam> internal class NetDictionaryWatcher<TKey, TValue, TField, TSerialDict, TSelf> : BaseDisposableWatcher, IDictionaryWatcher<TKey, TValue> + where TKey : notnull where TField : class, INetObject<INetSerializable>, new() where TSerialDict : IDictionary<TKey, TValue>, new() where TSelf : NetDictionary<TKey, TValue, TField, TSerialDict, TSelf> diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs index c29d2783..97aedca8 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs @@ -16,13 +16,13 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers private readonly ObservableCollection<TValue> Field; /// <summary>The pairs added since the last reset.</summary> - private readonly List<TValue> AddedImpl = new List<TValue>(); + private readonly List<TValue> AddedImpl = new(); /// <summary>The pairs removed since the last reset.</summary> - private readonly List<TValue> RemovedImpl = new List<TValue>(); + private readonly List<TValue> RemovedImpl = new(); /// <summary>The previous values as of the last update.</summary> - private readonly List<TValue> PreviousValues = new List<TValue>(); + private readonly List<TValue> PreviousValues = new(); /********* @@ -79,7 +79,7 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// <summary>A callback invoked when an entry is added or removed from the collection.</summary> /// <param name="sender">The event sender.</param> /// <param name="e">The event arguments.</param> - private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Reset) { @@ -88,8 +88,8 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers } else { - TValue[] added = e.NewItems?.Cast<TValue>().ToArray(); - TValue[] removed = e.OldItems?.Cast<TValue>().ToArray(); + TValue[]? added = e.NewItems?.Cast<TValue>().ToArray(); + TValue[]? removed = e.OldItems?.Cast<TValue>().ToArray(); if (removed != null) { diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs index bde43486..c4a4d0b9 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs @@ -18,7 +18,8 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// <summary>Get a watcher which compares values using their <see cref="object.Equals(object)"/> method. This method should only be used when <see cref="ForEquatable{T}"/> won't work, since this doesn't validate whether they're comparable.</summary> /// <typeparam name="T">The value type.</typeparam> /// <param name="getValue">Get the current value.</param> - public static IValueWatcher<T> ForGenericEquality<T>(Func<T> getValue) where T : struct + public static IValueWatcher<T> ForGenericEquality<T>(Func<T> getValue) + where T : struct { return new ComparableWatcher<T>(getValue, new GenericEqualsComparer<T>()); } @@ -26,7 +27,8 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// <summary>Get a watcher for an <see cref="IEquatable{T}"/> value.</summary> /// <typeparam name="T">The value type.</typeparam> /// <param name="getValue">Get the current value.</param> - public static IValueWatcher<T> ForEquatable<T>(Func<T> getValue) where T : IEquatable<T> + public static IValueWatcher<T> ForEquatable<T>(Func<T> getValue) + where T : IEquatable<T> { return new ComparableWatcher<T>(getValue, new EquatableComparer<T>()); } @@ -77,7 +79,8 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// <summary>Get a watcher for a net collection.</summary> /// <typeparam name="T">The value type.</typeparam> /// <param name="collection">The net collection.</param> - public static ICollectionWatcher<T> ForNetCollection<T>(NetCollection<T> collection) where T : class, INetObject<INetSerializable> + public static ICollectionWatcher<T> ForNetCollection<T>(NetCollection<T> collection) + where T : class, INetObject<INetSerializable> { return new NetCollectionWatcher<T>(collection); } @@ -85,7 +88,8 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// <summary>Get a watcher for a net list.</summary> /// <typeparam name="T">The value type.</typeparam> /// <param name="collection">The net list.</param> - public static ICollectionWatcher<T> ForNetList<T>(NetList<T, NetRef<T>> collection) where T : class, INetObject<INetSerializable> + public static ICollectionWatcher<T> ForNetList<T>(NetList<T, NetRef<T>> collection) + where T : class, INetObject<INetSerializable> { return new NetListWatcher<T>(collection); } @@ -98,6 +102,7 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// <typeparam name="TSelf">The net field instance type.</typeparam> /// <param name="field">The net field.</param> public static NetDictionaryWatcher<TKey, TValue, TField, TSerialDict, TSelf> ForNetDictionary<TKey, TValue, TField, TSerialDict, TSelf>(NetDictionary<TKey, TValue, TField, TSerialDict, TSelf> field) + where TKey : notnull where TField : class, INetObject<INetSerializable>, new() where TSerialDict : IDictionary<TKey, TValue>, new() where TSelf : NetDictionary<TKey, TValue, TField, TSerialDict, TSelf> diff --git a/src/SMAPI/Framework/StateTracking/LocationTracker.cs b/src/SMAPI/Framework/StateTracking/LocationTracker.cs index 6d3a62bb..ff72a19b 100644 --- a/src/SMAPI/Framework/StateTracking/LocationTracker.cs +++ b/src/SMAPI/Framework/StateTracking/LocationTracker.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; @@ -18,7 +19,7 @@ namespace StardewModdingAPI.Framework.StateTracking ** Fields *********/ /// <summary>The underlying watchers.</summary> - private readonly List<IWatcher> Watchers = new List<IWatcher>(); + private readonly List<IWatcher> Watchers = new(); /********* @@ -84,7 +85,7 @@ namespace StardewModdingAPI.Framework.StateTracking this.FurnitureWatcher }); - this.UpdateChestWatcherList(added: location.Objects.Pairs, removed: new KeyValuePair<Vector2, SObject>[0]); + this.UpdateChestWatcherList(added: location.Objects.Pairs, removed: Array.Empty<KeyValuePair<Vector2, SObject>>()); } /// <summary>Update the current value if needed.</summary> @@ -129,20 +130,20 @@ namespace StardewModdingAPI.Framework.StateTracking private void UpdateChestWatcherList(IEnumerable<KeyValuePair<Vector2, SObject>> added, IEnumerable<KeyValuePair<Vector2, SObject>> removed) { // remove unused watchers - foreach (KeyValuePair<Vector2, SObject> pair in removed) + foreach ((Vector2 tile, SObject? obj) in removed) { - if (pair.Value is Chest && this.ChestWatchers.TryGetValue(pair.Key, out ChestTracker watcher)) + if (obj is Chest && this.ChestWatchers.TryGetValue(tile, out ChestTracker? watcher)) { watcher.Dispose(); - this.ChestWatchers.Remove(pair.Key); + this.ChestWatchers.Remove(tile); } } // add new watchers - foreach (KeyValuePair<Vector2, SObject> pair in added) + foreach ((Vector2 tile, SObject? obj) in added) { - if (pair.Value is Chest chest && !this.ChestWatchers.ContainsKey(pair.Key)) - this.ChestWatchers.Add(pair.Key, new ChestTracker(chest)); + if (obj is Chest chest && !this.ChestWatchers.ContainsKey(tile)) + this.ChestWatchers.Add(tile, new ChestTracker(chest)); } } } diff --git a/src/SMAPI/Framework/StateTracking/PlayerTracker.cs b/src/SMAPI/Framework/StateTracking/PlayerTracker.cs index cf49a7c1..5433ac8e 100644 --- a/src/SMAPI/Framework/StateTracking/PlayerTracker.cs +++ b/src/SMAPI/Framework/StateTracking/PlayerTracker.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using StardewModdingAPI.Enums; using StardewModdingAPI.Framework.StateTracking.Comparers; @@ -21,10 +22,10 @@ namespace StardewModdingAPI.Framework.StateTracking private IDictionary<Item, int> CurrentInventory; /// <summary>The player's last valid location.</summary> - private GameLocation LastValidLocation; + private GameLocation? LastValidLocation; /// <summary>The underlying watchers.</summary> - private readonly List<IWatcher> Watchers = new List<IWatcher>(); + private readonly List<IWatcher> Watchers = new(); /********* @@ -34,7 +35,7 @@ namespace StardewModdingAPI.Framework.StateTracking public Farmer Player { get; } /// <summary>The player's current location.</summary> - public IValueWatcher<GameLocation> LocationWatcher { get; } + public IValueWatcher<GameLocation?> LocationWatcher { get; } /// <summary>Tracks changes to the player's skill levels.</summary> public IDictionary<SkillType, IValueWatcher<int>> SkillWatchers { get; } @@ -49,7 +50,8 @@ namespace StardewModdingAPI.Framework.StateTracking { // init player data this.Player = player; - this.PreviousInventory = this.GetInventory(); + this.CurrentInventory = this.GetInventory(); + this.PreviousInventory = new Dictionary<Item, int>(this.CurrentInventory); // init trackers this.LocationWatcher = WatcherFactory.ForReference(this.GetCurrentLocation); @@ -93,7 +95,7 @@ namespace StardewModdingAPI.Framework.StateTracking /// <summary>Get the player's current location, ignoring temporary null values.</summary> /// <remarks>The game will set <see cref="Character.currentLocation"/> to null in some cases, e.g. when they're a secondary player in multiplayer and transition to a location that hasn't been synced yet. While that's happening, this returns the player's last valid location instead.</remarks> - public GameLocation GetCurrentLocation() + public GameLocation? GetCurrentLocation() { return this.Player.currentLocation ?? this.LastValidLocation; } @@ -101,7 +103,7 @@ namespace StardewModdingAPI.Framework.StateTracking /// <summary>Get the inventory changes since the last update, if anything changed.</summary> /// <param name="changes">The inventory changes, or <c>null</c> if nothing changed.</param> /// <returns>Returns whether anything changed.</returns> - public bool TryGetInventoryChanges(out SnapshotItemListDiff changes) + public bool TryGetInventoryChanges([NotNullWhen(true)] out SnapshotItemListDiff? changes) { IDictionary<Item, int> current = this.GetInventory(); @@ -122,7 +124,7 @@ namespace StardewModdingAPI.Framework.StateTracking public void Dispose() { this.PreviousInventory.Clear(); - this.CurrentInventory?.Clear(); + this.CurrentInventory.Clear(); foreach (IWatcher watcher in this.Watchers) watcher.Dispose(); diff --git a/src/SMAPI/Framework/StateTracking/Snapshots/LocationSnapshot.cs b/src/SMAPI/Framework/StateTracking/Snapshots/LocationSnapshot.cs index 6c9cc4f5..0d0469d7 100644 --- a/src/SMAPI/Framework/StateTracking/Snapshots/LocationSnapshot.cs +++ b/src/SMAPI/Framework/StateTracking/Snapshots/LocationSnapshot.cs @@ -17,25 +17,25 @@ namespace StardewModdingAPI.Framework.StateTracking.Snapshots public GameLocation Location { get; } /// <summary>Tracks added or removed buildings.</summary> - public SnapshotListDiff<Building> Buildings { get; } = new SnapshotListDiff<Building>(); + public SnapshotListDiff<Building> Buildings { get; } = new(); /// <summary>Tracks added or removed debris.</summary> - public SnapshotListDiff<Debris> Debris { get; } = new SnapshotListDiff<Debris>(); + public SnapshotListDiff<Debris> Debris { get; } = new(); /// <summary>Tracks added or removed large terrain features.</summary> - public SnapshotListDiff<LargeTerrainFeature> LargeTerrainFeatures { get; } = new SnapshotListDiff<LargeTerrainFeature>(); + public SnapshotListDiff<LargeTerrainFeature> LargeTerrainFeatures { get; } = new(); /// <summary>Tracks added or removed NPCs.</summary> - public SnapshotListDiff<NPC> Npcs { get; } = new SnapshotListDiff<NPC>(); + public SnapshotListDiff<NPC> Npcs { get; } = new(); /// <summary>Tracks added or removed objects.</summary> - public SnapshotListDiff<KeyValuePair<Vector2, Object>> Objects { get; } = new SnapshotListDiff<KeyValuePair<Vector2, Object>>(); + public SnapshotListDiff<KeyValuePair<Vector2, Object>> Objects { get; } = new(); /// <summary>Tracks added or removed terrain features.</summary> - public SnapshotListDiff<KeyValuePair<Vector2, TerrainFeature>> TerrainFeatures { get; } = new SnapshotListDiff<KeyValuePair<Vector2, TerrainFeature>>(); + public SnapshotListDiff<KeyValuePair<Vector2, TerrainFeature>> TerrainFeatures { get; } = new(); /// <summary>Tracks added or removed furniture.</summary> - public SnapshotListDiff<Furniture> Furniture { get; } = new SnapshotListDiff<Furniture>(); + public SnapshotListDiff<Furniture> Furniture { get; } = new(); /// <summary>Tracks changed chest inventories.</summary> public IDictionary<Chest, SnapshotItemListDiff> ChestItems { get; } = new Dictionary<Chest, SnapshotItemListDiff>(); @@ -68,7 +68,7 @@ namespace StardewModdingAPI.Framework.StateTracking.Snapshots this.ChestItems.Clear(); foreach (ChestTracker tracker in watcher.ChestWatchers.Values) { - if (tracker.TryGetInventoryChanges(out SnapshotItemListDiff changes)) + if (tracker.TryGetInventoryChanges(out SnapshotItemListDiff? changes)) this.ChestItems[tracker.Chest] = changes; } } diff --git a/src/SMAPI/Framework/StateTracking/Snapshots/PlayerSnapshot.cs b/src/SMAPI/Framework/StateTracking/Snapshots/PlayerSnapshot.cs index 0908b02a..6a24ec30 100644 --- a/src/SMAPI/Framework/StateTracking/Snapshots/PlayerSnapshot.cs +++ b/src/SMAPI/Framework/StateTracking/Snapshots/PlayerSnapshot.cs @@ -14,7 +14,7 @@ namespace StardewModdingAPI.Framework.StateTracking.Snapshots ** Fields *********/ /// <summary>An empty item list diff.</summary> - private readonly SnapshotItemListDiff EmptyItemListDiff = new SnapshotItemListDiff(new Item[0], new Item[0], new ItemStackSizeChange[0]); + private readonly SnapshotItemListDiff EmptyItemListDiff = new(Array.Empty<Item>(), Array.Empty<Item>(), Array.Empty<ItemStackSizeChange>()); /********* @@ -24,14 +24,14 @@ namespace StardewModdingAPI.Framework.StateTracking.Snapshots public Farmer Player { get; } /// <summary>The player's current location.</summary> - public SnapshotDiff<GameLocation> Location { get; } = new SnapshotDiff<GameLocation>(); + public SnapshotDiff<GameLocation> Location { get; } = new(); /// <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>()); + .ToDictionary(skill => skill, _ => new SnapshotDiff<int>()); /// <summary>Get a list of inventory changes.</summary> public SnapshotItemListDiff Inventory { get; private set; } @@ -45,17 +45,18 @@ namespace StardewModdingAPI.Framework.StateTracking.Snapshots public PlayerSnapshot(Farmer player) { this.Player = player; + this.Inventory = this.EmptyItemListDiff; } /// <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.Location.Update(watcher.LocationWatcher!); + foreach ((SkillType skill, var value) in this.Skills) + value.Update(watcher.SkillWatchers[skill]); - this.Inventory = watcher.TryGetInventoryChanges(out SnapshotItemListDiff itemChanges) + this.Inventory = watcher.TryGetInventoryChanges(out SnapshotItemListDiff? itemChanges) ? itemChanges : this.EmptyItemListDiff; } diff --git a/src/SMAPI/Framework/StateTracking/Snapshots/WatcherSnapshot.cs b/src/SMAPI/Framework/StateTracking/Snapshots/WatcherSnapshot.cs index cf51e040..27a891de 100644 --- a/src/SMAPI/Framework/StateTracking/Snapshots/WatcherSnapshot.cs +++ b/src/SMAPI/Framework/StateTracking/Snapshots/WatcherSnapshot.cs @@ -11,31 +11,31 @@ namespace StardewModdingAPI.Framework.StateTracking.Snapshots ** Accessors *********/ /// <summary>Tracks changes to the window size.</summary> - public SnapshotDiff<Point> WindowSize { get; } = new SnapshotDiff<Point>(); + public SnapshotDiff<Point> WindowSize { get; } = new(); /// <summary>Tracks changes to the current player.</summary> - public PlayerSnapshot CurrentPlayer { get; private set; } + 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>(); + public SnapshotDiff<int> Time { get; } = new(); /// <summary>Tracks changes to the save ID.</summary> - public SnapshotDiff<ulong> SaveID { get; } = new SnapshotDiff<ulong>(); + public SnapshotDiff<ulong> SaveID { get; } = new(); /// <summary>Tracks changes to the game's locations.</summary> - public WorldLocationsSnapshot Locations { get; } = new WorldLocationsSnapshot(); + public WorldLocationsSnapshot Locations { get; } = new(); /// <summary>Tracks changes to <see cref="Game1.activeClickableMenu"/>.</summary> - public SnapshotDiff<IClickableMenu> ActiveMenu { get; } = new SnapshotDiff<IClickableMenu>(); + public SnapshotDiff<IClickableMenu> ActiveMenu { get; } = new(); /// <summary>Tracks changes to the cursor position.</summary> - public SnapshotDiff<ICursorPosition> Cursor { get; } = new SnapshotDiff<ICursorPosition>(); + public SnapshotDiff<ICursorPosition> Cursor { get; } = new(); /// <summary>Tracks changes to the mouse wheel scroll.</summary> - public SnapshotDiff<int> MouseWheelScroll { get; } = new SnapshotDiff<int>(); + public SnapshotDiff<int> MouseWheelScroll { get; } = new(); /// <summary>Tracks changes to the content locale.</summary> - public SnapshotDiff<LocalizedContentManager.LanguageCode> Locale { get; } = new SnapshotDiff<LocalizedContentManager.LanguageCode>(); + public SnapshotDiff<LocalizedContentManager.LanguageCode> Locale { get; } = new(); /********* @@ -54,7 +54,7 @@ namespace StardewModdingAPI.Framework.StateTracking.Snapshots // update snapshots this.WindowSize.Update(watchers.WindowSizeWatcher); this.Locale.Update(watchers.LocaleWatcher); - this.CurrentPlayer?.Update(watchers.CurrentPlayerTracker); + this.CurrentPlayer?.Update(watchers.CurrentPlayerTracker!); this.Time.Update(watchers.TimeWatcher); this.SaveID.Update(watchers.SaveIdWatcher); this.Locations.Update(watchers.LocationsWatcher); diff --git a/src/SMAPI/Framework/StateTracking/Snapshots/WorldLocationsSnapshot.cs b/src/SMAPI/Framework/StateTracking/Snapshots/WorldLocationsSnapshot.cs index 73ed2d8f..59f94942 100644 --- a/src/SMAPI/Framework/StateTracking/Snapshots/WorldLocationsSnapshot.cs +++ b/src/SMAPI/Framework/StateTracking/Snapshots/WorldLocationsSnapshot.cs @@ -12,14 +12,14 @@ namespace StardewModdingAPI.Framework.StateTracking.Snapshots ** Fields *********/ /// <summary>A map of tracked locations.</summary> - private readonly Dictionary<GameLocation, LocationSnapshot> LocationsDict = new Dictionary<GameLocation, LocationSnapshot>(new ObjectReferenceComparer<GameLocation>()); + private readonly Dictionary<GameLocation, LocationSnapshot> LocationsDict = new(new ObjectReferenceComparer<GameLocation>()); /********* ** Accessors *********/ /// <summary>Tracks changes to the location list.</summary> - public SnapshotListDiff<GameLocation> LocationList { get; } = new SnapshotListDiff<GameLocation>(); + public SnapshotListDiff<GameLocation> LocationList { get; } = new(); /// <summary>The tracked locations.</summary> public IEnumerable<LocationSnapshot> Locations => this.LocationsDict.Values; @@ -42,7 +42,7 @@ namespace StardewModdingAPI.Framework.StateTracking.Snapshots // update locations foreach (LocationTracker locationWatcher in watcher.Locations) { - if (!this.LocationsDict.TryGetValue(locationWatcher.Location, out LocationSnapshot snapshot)) + if (!this.LocationsDict.TryGetValue(locationWatcher.Location, out LocationSnapshot? snapshot)) this.LocationsDict[locationWatcher.Location] = snapshot = new LocationSnapshot(locationWatcher.Location); snapshot.Update(locationWatcher); diff --git a/src/SMAPI/Framework/StateTracking/WorldLocationsTracker.cs b/src/SMAPI/Framework/StateTracking/WorldLocationsTracker.cs index e968d79c..817a6011 100644 --- a/src/SMAPI/Framework/StateTracking/WorldLocationsTracker.cs +++ b/src/SMAPI/Framework/StateTracking/WorldLocationsTracker.cs @@ -25,10 +25,10 @@ namespace StardewModdingAPI.Framework.StateTracking private readonly ICollectionWatcher<GameLocation> VolcanoLocationListWatcher; /// <summary>A lookup of the tracked locations.</summary> - private IDictionary<GameLocation, LocationTracker> LocationDict { get; } = new Dictionary<GameLocation, LocationTracker>(new ObjectReferenceComparer<GameLocation>()); + private Dictionary<GameLocation, LocationTracker> LocationDict { get; } = new(new ObjectReferenceComparer<GameLocation>()); /// <summary>A lookup of registered buildings and their indoor location.</summary> - private readonly IDictionary<Building, GameLocation> BuildingIndoors = new Dictionary<Building, GameLocation>(new ObjectReferenceComparer<Building>()); + private readonly Dictionary<Building, GameLocation?> BuildingIndoors = new(new ObjectReferenceComparer<Building>()); /********* @@ -99,10 +99,9 @@ namespace StardewModdingAPI.Framework.StateTracking } // detect building interiors changed (e.g. construction completed) - foreach (KeyValuePair<Building, GameLocation> pair in this.BuildingIndoors.Where(p => !object.Equals(p.Key.indoors.Value, p.Value))) + foreach ((Building building, GameLocation? oldIndoors) in this.BuildingIndoors.Where(p => !object.Equals(p.Key.indoors.Value, p.Value))) { - GameLocation oldIndoors = pair.Value; - GameLocation newIndoors = pair.Key.indoors.Value; + GameLocation? newIndoors = building.indoors.Value; if (oldIndoors != null) this.Added.Add(oldIndoors); @@ -187,19 +186,19 @@ namespace StardewModdingAPI.Framework.StateTracking ****/ /// <summary>Add the given building.</summary> /// <param name="building">The building to add.</param> - public void Add(Building building) + public void Add(Building? building) { if (building == null) return; - GameLocation indoors = building.indoors.Value; + GameLocation? indoors = building.indoors.Value; this.BuildingIndoors[building] = indoors; this.Add(indoors); } /// <summary>Add the given location.</summary> /// <param name="location">The location to add.</param> - public void Add(GameLocation location) + public void Add(GameLocation? location) { if (location == null) return; @@ -218,7 +217,7 @@ namespace StardewModdingAPI.Framework.StateTracking /// <summary>Remove the given building.</summary> /// <param name="building">The building to remove.</param> - public void Remove(Building building) + public void Remove(Building? building) { if (building == null) return; @@ -229,12 +228,12 @@ namespace StardewModdingAPI.Framework.StateTracking /// <summary>Remove the given location.</summary> /// <param name="location">The location to remove.</param> - public void Remove(GameLocation location) + public void Remove(GameLocation? location) { if (location == null) return; - if (this.LocationDict.TryGetValue(location, out LocationTracker watcher)) + if (this.LocationDict.TryGetValue(location, out LocationTracker? watcher)) { // track change this.Removed.Add(location); |