summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2018-04-21 20:37:17 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2018-04-21 20:37:17 -0400
commiteead352af26d0fcc5cac147d0eb5ec384854d931 (patch)
tree78895ff201953f065667976c0e861168dddcebc1 /src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs
parentb346d28d3858b79c6c4cde55faac34ecdedeaff1 (diff)
downloadSMAPI-eead352af26d0fcc5cac147d0eb5ec384854d931.tar.gz
SMAPI-eead352af26d0fcc5cac147d0eb5ec384854d931.tar.bz2
SMAPI-eead352af26d0fcc5cac147d0eb5ec384854d931.zip
rewrite world/player state tracking (#453)
Diffstat (limited to 'src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs')
-rw-r--r--src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs b/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs
new file mode 100644
index 00000000..34a97097
--- /dev/null
+++ b/src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs
@@ -0,0 +1,86 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.Linq;
+
+namespace StardewModdingAPI.Framework.StateTracking.FieldWatchers
+{
+ /// <summary>A watcher which detects changes to an observable collection.</summary>
+ internal class ObservableCollectionWatcher<TValue> : BaseDisposableWatcher, ICollectionWatcher<TValue>
+ {
+ /*********
+ ** Properties
+ *********/
+ /// <summary>The field being watched.</summary>
+ private readonly ObservableCollection<TValue> Field;
+
+ /// <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 collection 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="field">The field to watch.</param>
+ public ObservableCollectionWatcher(ObservableCollection<TValue> field)
+ {
+ this.Field = field;
+ field.CollectionChanged += this.OnCollectionChanged;
+ }
+
+ /// <summary>Update the current value if needed.</summary>
+ public void Update()
+ {
+ this.AssertNotDisposed();
+ }
+
+ /// <summary>Set the current value as the baseline.</summary>
+ public void Reset()
+ {
+ this.AssertNotDisposed();
+
+ this.AddedImpl.Clear();
+ this.RemovedImpl.Clear();
+ }
+
+ /// <summary>Stop watching the field and release all references.</summary>
+ public override void Dispose()
+ {
+ if (!this.IsDisposed)
+ this.Field.CollectionChanged -= this.OnCollectionChanged;
+ base.Dispose();
+ }
+
+
+ /*********
+ ** Private methods
+ *********/
+ /// <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)
+ {
+ if (e.NewItems != null)
+ this.AddedImpl.AddRange(e.NewItems.Cast<TValue>());
+ if (e.OldItems != null)
+ this.RemovedImpl.AddRange(e.OldItems.Cast<TValue>());
+ }
+ }
+}