diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2018-12-04 23:16:13 -0500 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2018-12-04 23:49:09 -0500 |
commit | dad67e213e68eb85c534d7c1c4035dfde90ff822 (patch) | |
tree | c041f2e3ae3e3d648709c0c57e2e91fc3967b708 /src/SMAPI/Framework/StateTracking/FieldWatchers | |
parent | e8ae2d627d59f9cd28d797d2178b7acdead5ace1 (diff) | |
download | SMAPI-dad67e213e68eb85c534d7c1c4035dfde90ff822.tar.gz SMAPI-dad67e213e68eb85c534d7c1c4035dfde90ff822.tar.bz2 SMAPI-dad67e213e68eb85c534d7c1c4035dfde90ff822.zip |
fix world events in the mines (#603)
Diffstat (limited to 'src/SMAPI/Framework/StateTracking/FieldWatchers')
-rw-r--r-- | src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs | 82 | ||||
-rw-r--r-- | src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs | 8 |
2 files changed, 90 insertions, 0 deletions
diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs new file mode 100644 index 00000000..95e9ef16 --- /dev/null +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/ComparableListWatcher.cs @@ -0,0 +1,82 @@ +using System.Collections.Generic; +using System.Linq; + +namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers +{ + /// <summary>A watcher which detects changes to a collection of values using a specified <see cref="IEqualityComparer{T}"/> instance.</summary> + internal class ComparableListWatcher<TValue> : BaseDisposableWatcher, ICollectionWatcher<TValue> + { + /********* + ** Properties + *********/ + /// <summary>The collection to watch.</summary> + private readonly ICollection<TValue> CurrentValues; + + /// <summary>The values during the previous update.</summary> + private HashSet<TValue> LastValues; + + /// <summary>The pairs added since the last reset.</summary> + private readonly List<TValue> AddedImpl = new List<TValue>(); + + /// <summary>The pairs demoved since the last reset.</summary> + private readonly List<TValue> RemovedImpl = new List<TValue>(); + + + /********* + ** Accessors + *********/ + /// <summary>Whether the value changed since the last reset.</summary> + public bool IsChanged => this.AddedImpl.Count > 0 || this.RemovedImpl.Count > 0; + + /// <summary>The values added since the last reset.</summary> + public IEnumerable<TValue> Added => this.AddedImpl; + + /// <summary>The values removed since the last reset.</summary> + public IEnumerable<TValue> Removed => this.RemovedImpl; + + + /********* + ** Public methods + *********/ + /// <summary>Construct an instance.</summary> + /// <param name="values">The collection to watch.</param> + /// <param name="comparer">The equality comparer which indicates whether two values are the same.</param> + public ComparableListWatcher(ICollection<TValue> values, IEqualityComparer<TValue> comparer) + { + this.CurrentValues = values; + this.LastValues = new HashSet<TValue>(comparer); + } + + /// <summary>Update the current value if needed.</summary> + public void Update() + { + this.AssertNotDisposed(); + + // optimise for zero items + if (this.CurrentValues.Count == 0) + { + if (this.LastValues.Count > 0) + { + this.AddedImpl.AddRange(this.LastValues); + this.LastValues.Clear(); + } + return; + } + + // detect changes + HashSet<TValue> curValues = new HashSet<TValue>(this.CurrentValues, this.LastValues.Comparer); + this.RemovedImpl.AddRange(from value in this.LastValues where !curValues.Contains(value) select value); + this.AddedImpl.AddRange(from value in curValues where !this.LastValues.Contains(value) select value); + this.LastValues = curValues; + } + + /// <summary>Set the current value as the baseline.</summary> + public void Reset() + { + this.AssertNotDisposed(); + + this.AddedImpl.Clear(); + this.RemovedImpl.Clear(); + } + } +} diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs index ab4ab0d5..8301351e 100644 --- a/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs +++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/WatcherFactory.cs @@ -36,6 +36,14 @@ namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers return new ComparableWatcher<T>(getValue, new ObjectReferenceComparer<T>()); } + /// <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) + { + return new ComparableListWatcher<T>(collection, new ObjectReferenceComparer<T>()); + } + /// <summary>Get a watcher for an observable collection.</summary> /// <typeparam name="T">The value type.</typeparam> /// <param name="collection">The observable collection.</param> |