From 2d6175fcd27d83f7f09e570252f9e45c44115b0a Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 4 Sep 2019 18:57:07 -0400 Subject: add immutable collection watcher --- .../FieldWatchers/ImmutableCollectionWatcher.cs | 37 ++++++++++++++++++++++ .../StateTracking/FieldWatchers/WatcherFactory.cs | 35 +++++++++++++------- .../Framework/StateTracking/LocationTracker.cs | 5 +-- 3 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 src/SMAPI/Framework/StateTracking/FieldWatchers/ImmutableCollectionWatcher.cs (limited to 'src/SMAPI/Framework') diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/ImmutableCollectionWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/ImmutableCollectionWatcher.cs new file mode 100644 index 00000000..30e6274f --- /dev/null +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/ImmutableCollectionWatcher.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; + +namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers +{ + /// A collection watcher which never changes. + /// The value type within the collection. + internal class ImmutableCollectionWatcher : BaseDisposableWatcher, ICollectionWatcher + { + /********* + ** Accessors + *********/ + /// A singleton collection watcher instance. + public static ImmutableCollectionWatcher Instance { get; } = new ImmutableCollectionWatcher(); + + /// Whether the collection changed since the last reset. + public bool IsChanged { get; } = false; + + /// The values added since the last reset. + public IEnumerable Added { get; } = new TValue[0]; + + /// The values removed since the last reset. + public IEnumerable Removed { get; } = new TValue[0]; + + + /********* + ** Public methods + *********/ + /// Update the current value if needed. + public void Update() { } + + /// Set the current value as the baseline. + public void Reset() { } + + /// Stop watching the field and release all references. + public override void Dispose() { } + } +} diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs index 8301351e..314ff7f5 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs @@ -12,10 +12,13 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /********* ** Public methods *********/ + /**** + ** Values + ****/ /// 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 ComparableWatcher ForGenericEquality(Func getValue) where T : struct + public static IValueWatcher ForGenericEquality(Func getValue) where T : struct { return new ComparableWatcher(getValue, new GenericEqualsComparer()); } @@ -23,7 +26,7 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// Get a watcher for an value. /// The value type. /// Get the current value. - public static ComparableWatcher ForEquatable(Func getValue) where T : IEquatable + public static IValueWatcher ForEquatable(Func getValue) where T : IEquatable { return new ComparableWatcher(getValue, new EquatableComparer()); } @@ -31,15 +34,27 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// Get a watcher which detects when an object reference changes. /// The value type. /// Get the current value. - public static ComparableWatcher ForReference(Func getValue) + public static IValueWatcher ForReference(Func getValue) { return new ComparableWatcher(getValue, new ObjectReferenceComparer()); } + /// Get a watcher for a net collection. + /// The value type. + /// The net field instance type. + /// The net collection. + public static IValueWatcher ForNetValue(NetFieldBase field) where TSelf : NetFieldBase + { + return new NetValueWatcher(field); + } + + /**** + ** Collections + ****/ /// Get a watcher which detects when an object reference in a collection changes. /// The value type. /// The observable collection. - public static ComparableListWatcher ForReferenceList(ICollection collection) + public static ICollectionWatcher ForReferenceList(ICollection collection) { return new ComparableListWatcher(collection, new ObjectReferenceComparer()); } @@ -47,24 +62,22 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// Get a watcher for an observable collection. /// The value type. /// The observable collection. - public static ObservableCollectionWatcher ForObservableCollection(ObservableCollection collection) + public static ICollectionWatcher ForObservableCollection(ObservableCollection collection) { return new ObservableCollectionWatcher(collection); } - /// Get a watcher for a net collection. + /// Get a watcher for a collection that never changes. /// The value type. - /// The net field instance type. - /// The net collection. - public static NetValueWatcher ForNetValue(NetFieldBase field) where TSelf : NetFieldBase + public static ICollectionWatcher ForImmutableCollection() { - return new NetValueWatcher(field); + return ImmutableCollectionWatcher.Instance; } /// Get a watcher for a net collection. /// The value type. /// The net collection. - public static NetCollectionWatcher ForNetCollection(NetCollection collection) where T : class, INetObject + public static ICollectionWatcher ForNetCollection(NetCollection collection) where T : class, INetObject { return new NetCollectionWatcher(collection); } diff --git a/src/SMAPI/Framework/StateTracking/LocationTracker.cs b/src/SMAPI/Framework/StateTracking/LocationTracker.cs index 2249e41b..1f479e12 100644 --- a/src/SMAPI/Framework/StateTracking/LocationTracker.cs +++ b/src/SMAPI/Framework/StateTracking/LocationTracker.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Linq; using Microsoft.Xna.Framework; using StardewModdingAPI.Framework.StateTracking.FieldWatchers; @@ -59,9 +58,7 @@ namespace StardewModdingAPI.Framework.StateTracking this.Location = location; // init watchers - this.BuildingsWatcher = location is BuildableGameLocation buildableLocation - ? WatcherFactory.ForNetCollection(buildableLocation.buildings) - : (ICollectionWatcher)WatcherFactory.ForObservableCollection(new ObservableCollection()); + this.BuildingsWatcher = location is BuildableGameLocation buildableLocation ? WatcherFactory.ForNetCollection(buildableLocation.buildings) : WatcherFactory.ForImmutableCollection(); this.DebrisWatcher = WatcherFactory.ForNetCollection(location.debris); this.LargeTerrainFeaturesWatcher = WatcherFactory.ForNetCollection(location.largeTerrainFeatures); this.NpcsWatcher = WatcherFactory.ForNetCollection(location.characters); -- cgit