diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2019-09-04 18:57:07 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2019-09-14 19:19:30 -0400 |
commit | 2d6175fcd27d83f7f09e570252f9e45c44115b0a (patch) | |
tree | ace6eba0171f2dba75f595bfbbc97845081b82cc /src | |
parent | 1db1a8fa2346c3aa77547c22b4d069fbc8b8ea60 (diff) | |
download | SMAPI-2d6175fcd27d83f7f09e570252f9e45c44115b0a.tar.gz SMAPI-2d6175fcd27d83f7f09e570252f9e45c44115b0a.tar.bz2 SMAPI-2d6175fcd27d83f7f09e570252f9e45c44115b0a.zip |
add immutable collection watcher
Diffstat (limited to 'src')
3 files changed, 62 insertions, 15 deletions
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 +{ + /// <summary>A collection watcher which never changes.</summary> + /// <typeparam name="TValue">The value type within the collection.</typeparam> + internal class ImmutableCollectionWatcher<TValue> : BaseDisposableWatcher, ICollectionWatcher<TValue> + { + /********* + ** Accessors + *********/ + /// <summary>A singleton collection watcher instance.</summary> + public static ImmutableCollectionWatcher<TValue> Instance { get; } = new ImmutableCollectionWatcher<TValue>(); + + /// <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]; + + /// <summary>The values removed since the last reset.</summary> + public IEnumerable<TValue> Removed { get; } = new TValue[0]; + + + /********* + ** Public methods + *********/ + /// <summary>Update the current value if needed.</summary> + public void Update() { } + + /// <summary>Set the current value as the baseline.</summary> + public void Reset() { } + + /// <summary>Stop watching the field and release all references.</summary> + 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 + ****/ /// <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 ComparableWatcher<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>()); } @@ -23,7 +26,7 @@ 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 ComparableWatcher<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>()); } @@ -31,15 +34,27 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// <summary>Get a watcher which detects when an object reference changes.</summary> /// <typeparam name="T">The value type.</typeparam> /// <param name="getValue">Get the current value.</param> - public static ComparableWatcher<T> ForReference<T>(Func<T> getValue) + public static IValueWatcher<T> ForReference<T>(Func<T> getValue) { return new ComparableWatcher<T>(getValue, new ObjectReferenceComparer<T>()); } + /// <summary>Get a watcher for a net collection.</summary> + /// <typeparam name="T">The value type.</typeparam> + /// <typeparam name="TSelf">The net field instance type.</typeparam> + /// <param name="field">The net collection.</param> + public static IValueWatcher<T> ForNetValue<T, TSelf>(NetFieldBase<T, TSelf> field) where TSelf : NetFieldBase<T, TSelf> + { + return new NetValueWatcher<T, TSelf>(field); + } + + /**** + ** Collections + ****/ /// <summary>Get a watcher which detects when an object reference in a collection changes.</summary> /// <typeparam name="T">The value type.</typeparam> /// <param name="collection">The observable collection.</param> - public static ComparableListWatcher<T> ForReferenceList<T>(ICollection<T> collection) + public static ICollectionWatcher<T> ForReferenceList<T>(ICollection<T> collection) { return new ComparableListWatcher<T>(collection, new ObjectReferenceComparer<T>()); } @@ -47,24 +62,22 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers /// <summary>Get a watcher for an observable collection.</summary> /// <typeparam name="T">The value type.</typeparam> /// <param name="collection">The observable collection.</param> - public static ObservableCollectionWatcher<T> ForObservableCollection<T>(ObservableCollection<T> collection) + public static ICollectionWatcher<T> ForObservableCollection<T>(ObservableCollection<T> collection) { return new ObservableCollectionWatcher<T>(collection); } - /// <summary>Get a watcher for a net collection.</summary> + /// <summary>Get a watcher for a collection that never changes.</summary> /// <typeparam name="T">The value type.</typeparam> - /// <typeparam name="TSelf">The net field instance type.</typeparam> - /// <param name="field">The net collection.</param> - public static NetValueWatcher<T, TSelf> ForNetValue<T, TSelf>(NetFieldBase<T, TSelf> field) where TSelf : NetFieldBase<T, TSelf> + public static ICollectionWatcher<T> ForImmutableCollection<T>() { - return new NetValueWatcher<T, TSelf>(field); + return ImmutableCollectionWatcher<T>.Instance; } /// <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 NetCollectionWatcher<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); } 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<Building>)WatcherFactory.ForObservableCollection(new ObservableCollection<Building>()); + this.BuildingsWatcher = location is BuildableGameLocation buildableLocation ? WatcherFactory.ForNetCollection(buildableLocation.buildings) : WatcherFactory.ForImmutableCollection<Building>(); this.DebrisWatcher = WatcherFactory.ForNetCollection(location.debris); this.LargeTerrainFeaturesWatcher = WatcherFactory.ForNetCollection(location.largeTerrainFeatures); this.NpcsWatcher = WatcherFactory.ForNetCollection(location.characters); |