From f39da383a17b368e92fd243cf155b27ba42671f3 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 13 Apr 2022 20:24:14 -0400 Subject: enable nullable annotations in SMAPI where no logic changes are needed (#837) --- src/SMAPI/Framework/StateTracking/ChestTracker.cs | 5 ++--- .../StateTracking/Comparers/EquatableComparer.cs | 4 +--- .../Comparers/GenericEqualsComparer.cs | 4 +--- .../Comparers/ObjectReferenceComparer.cs | 4 +--- .../FieldWatchers/NetDictionaryWatcher.cs | 3 +-- .../FieldWatchers/ObservableCollectionWatcher.cs | 8 +++----- .../StateTracking/FieldWatchers/WatcherFactory.cs | 15 ++++++++------ .../Framework/StateTracking/LocationTracker.cs | 14 ++++++------- .../StateTracking/Snapshots/LocationSnapshot.cs | 4 +--- .../StateTracking/Snapshots/WatcherSnapshot.cs | 6 ++---- .../Snapshots/WorldLocationsSnapshot.cs | 4 +--- .../StateTracking/WorldLocationsTracker.cs | 23 ++++++++++------------ 12 files changed, 38 insertions(+), 56 deletions(-) (limited to 'src/SMAPI/Framework/StateTracking') diff --git a/src/SMAPI/Framework/StateTracking/ChestTracker.cs b/src/SMAPI/Framework/StateTracking/ChestTracker.cs index 28335200..c33a7498 100644 --- a/src/SMAPI/Framework/StateTracking/ChestTracker.cs +++ b/src/SMAPI/Framework/StateTracking/ChestTracker.cs @@ -1,7 +1,6 @@ -#nullable disable - using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using StardewModdingAPI.Framework.StateTracking.Comparers; using StardewModdingAPI.Framework.StateTracking.FieldWatchers; @@ -86,7 +85,7 @@ namespace StardewModdingAPI.Framework.StateTracking /// Get the inventory changes since the last update, if anything changed. /// The inventory changes, or null if nothing changed. /// Returns whether anything changed. - 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 987e1820..9d8559b4 100644 --- a/src/SMAPI/Framework/StateTracking/Comparers/EquatableComparer.cs +++ b/src/SMAPI/Framework/StateTracking/Comparers/EquatableComparer.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using System.Collections.Generic; using System.Runtime.CompilerServices; @@ -17,7 +15,7 @@ namespace StardewModdingAPI.Framework.StateTracking.Comparers /// true if the specified objects are equal; otherwise, false. /// The first object to compare. /// The second object to compare. - 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 f6b04583..41b17e10 100644 --- a/src/SMAPI/Framework/StateTracking/Comparers/GenericEqualsComparer.cs +++ b/src/SMAPI/Framework/StateTracking/Comparers/GenericEqualsComparer.cs @@ -1,5 +1,3 @@ -#nullable disable - using System.Collections.Generic; using System.Runtime.CompilerServices; @@ -16,7 +14,7 @@ namespace StardewModdingAPI.Framework.StateTracking.Comparers /// true if the specified objects are equal; otherwise, false. /// The first object to compare. /// The second object to compare. - 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 8d3a7eb9..e6ece854 100644 --- a/src/SMAPI/Framework/StateTracking/Comparers/ObjectReferenceComparer.cs +++ b/src/SMAPI/Framework/StateTracking/Comparers/ObjectReferenceComparer.cs @@ -1,5 +1,3 @@ -#nullable disable - using System.Collections.Generic; using System.Runtime.CompilerServices; @@ -16,7 +14,7 @@ namespace StardewModdingAPI.Framework.StateTracking.Comparers /// true if the specified objects are equal; otherwise, false. /// The first object to compare. /// The second object to compare. - 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/NetDictionaryWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetDictionaryWatcher.cs index 0d7f2ad2..f55e4cea 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/NetDictionaryWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/NetDictionaryWatcher.cs @@ -1,5 +1,3 @@ -#nullable disable - using System.Collections.Generic; using Netcode; @@ -12,6 +10,7 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// The serializable dictionary type that can store the keys and values. /// The net field instance type. internal class NetDictionaryWatcher : BaseDisposableWatcher, IDictionaryWatcher + where TKey : notnull where TField : class, INetObject, new() where TSerialDict : IDictionary, new() where TSelf : NetDictionary diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs index 82e5387e..97aedca8 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs @@ -1,5 +1,3 @@ -#nullable disable - using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; @@ -81,7 +79,7 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// A callback invoked when an entry is added or removed from the collection. /// The event sender. /// The event arguments. - private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Reset) { @@ -90,8 +88,8 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers } else { - TValue[] added = e.NewItems?.Cast().ToArray(); - TValue[] removed = e.OldItems?.Cast().ToArray(); + TValue[]? added = e.NewItems?.Cast().ToArray(); + TValue[]? removed = e.OldItems?.Cast().ToArray(); if (removed != null) { diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs index 0b99914c..c4a4d0b9 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -20,7 +18,8 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// Get a watcher which compares values using their method. This method should only be used when won't work, since this doesn't validate whether they're comparable. /// The value type. /// Get the current value. - public static IValueWatcher ForGenericEquality(Func getValue) where T : struct + public static IValueWatcher ForGenericEquality(Func getValue) + where T : struct { return new ComparableWatcher(getValue, new GenericEqualsComparer()); } @@ -28,7 +27,8 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// Get a watcher for an value. /// The value type. /// Get the current value. - public static IValueWatcher ForEquatable(Func getValue) where T : IEquatable + public static IValueWatcher ForEquatable(Func getValue) + where T : IEquatable { return new ComparableWatcher(getValue, new EquatableComparer()); } @@ -79,7 +79,8 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// Get a watcher for a net collection. /// The value type. /// The net collection. - public static ICollectionWatcher ForNetCollection(NetCollection collection) where T : class, INetObject + public static ICollectionWatcher ForNetCollection(NetCollection collection) + where T : class, INetObject { return new NetCollectionWatcher(collection); } @@ -87,7 +88,8 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// Get a watcher for a net list. /// The value type. /// The net list. - public static ICollectionWatcher ForNetList(NetList> collection) where T : class, INetObject + public static ICollectionWatcher ForNetList(NetList> collection) + where T : class, INetObject { return new NetListWatcher(collection); } @@ -100,6 +102,7 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// The net field instance type. /// The net field. public static NetDictionaryWatcher ForNetDictionary(NetDictionary field) + where TKey : notnull where TField : class, INetObject, new() where TSerialDict : IDictionary, new() where TSelf : NetDictionary diff --git a/src/SMAPI/Framework/StateTracking/LocationTracker.cs b/src/SMAPI/Framework/StateTracking/LocationTracker.cs index 9c2ff7f0..ff72a19b 100644 --- a/src/SMAPI/Framework/StateTracking/LocationTracker.cs +++ b/src/SMAPI/Framework/StateTracking/LocationTracker.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -132,20 +130,20 @@ namespace StardewModdingAPI.Framework.StateTracking private void UpdateChestWatcherList(IEnumerable> added, IEnumerable> removed) { // remove unused watchers - foreach (KeyValuePair 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 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/Snapshots/LocationSnapshot.cs b/src/SMAPI/Framework/StateTracking/Snapshots/LocationSnapshot.cs index 3d13f92b..0d0469d7 100644 --- a/src/SMAPI/Framework/StateTracking/Snapshots/LocationSnapshot.cs +++ b/src/SMAPI/Framework/StateTracking/Snapshots/LocationSnapshot.cs @@ -1,5 +1,3 @@ -#nullable disable - using System.Collections.Generic; using Microsoft.Xna.Framework; using StardewValley; @@ -70,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/WatcherSnapshot.cs b/src/SMAPI/Framework/StateTracking/Snapshots/WatcherSnapshot.cs index 1d43ef26..27a891de 100644 --- a/src/SMAPI/Framework/StateTracking/Snapshots/WatcherSnapshot.cs +++ b/src/SMAPI/Framework/StateTracking/Snapshots/WatcherSnapshot.cs @@ -1,5 +1,3 @@ -#nullable disable - using Microsoft.Xna.Framework; using StardewValley; using StardewValley.Menus; @@ -16,7 +14,7 @@ namespace StardewModdingAPI.Framework.StateTracking.Snapshots public SnapshotDiff WindowSize { get; } = new(); /// Tracks changes to the current player. - public PlayerSnapshot CurrentPlayer { get; private set; } + public PlayerSnapshot? CurrentPlayer { get; private set; } /// Tracks changes to the time of day (in 24-hour military format). public SnapshotDiff Time { get; } = new(); @@ -56,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 88aac0df..59f94942 100644 --- a/src/SMAPI/Framework/StateTracking/Snapshots/WorldLocationsSnapshot.cs +++ b/src/SMAPI/Framework/StateTracking/Snapshots/WorldLocationsSnapshot.cs @@ -1,5 +1,3 @@ -#nullable disable - using System.Collections.Generic; using System.Linq; using StardewModdingAPI.Framework.StateTracking.Comparers; @@ -44,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 ab02d7d5..817a6011 100644 --- a/src/SMAPI/Framework/StateTracking/WorldLocationsTracker.cs +++ b/src/SMAPI/Framework/StateTracking/WorldLocationsTracker.cs @@ -1,5 +1,3 @@ -#nullable disable - using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; @@ -27,10 +25,10 @@ namespace StardewModdingAPI.Framework.StateTracking private readonly ICollectionWatcher VolcanoLocationListWatcher; /// A lookup of the tracked locations. - private IDictionary LocationDict { get; } = new Dictionary(new ObjectReferenceComparer()); + private Dictionary LocationDict { get; } = new(new ObjectReferenceComparer()); /// A lookup of registered buildings and their indoor location. - private readonly IDictionary BuildingIndoors = new Dictionary(new ObjectReferenceComparer()); + private readonly Dictionary BuildingIndoors = new(new ObjectReferenceComparer()); /********* @@ -101,10 +99,9 @@ namespace StardewModdingAPI.Framework.StateTracking } // detect building interiors changed (e.g. construction completed) - foreach (KeyValuePair 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); @@ -189,19 +186,19 @@ namespace StardewModdingAPI.Framework.StateTracking ****/ /// Add the given building. /// The building to add. - 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); } /// Add the given location. /// The location to add. - public void Add(GameLocation location) + public void Add(GameLocation? location) { if (location == null) return; @@ -220,7 +217,7 @@ namespace StardewModdingAPI.Framework.StateTracking /// Remove the given building. /// The building to remove. - public void Remove(Building building) + public void Remove(Building? building) { if (building == null) return; @@ -231,12 +228,12 @@ namespace StardewModdingAPI.Framework.StateTracking /// Remove the given location. /// The location to remove. - 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); -- cgit