diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-04-21 20:37:17 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-04-21 20:37:17 -0400 |
commit | eead352af26d0fcc5cac147d0eb5ec384854d931 (patch) | |
tree | 78895ff201953f065667976c0e861168dddcebc1 /src/SMAPI/Framework/StateTracking/FieldWatchers/ObservableCollectionWatcher.cs | |
parent | b346d28d3858b79c6c4cde55faac34ecdedeaff1 (diff) | |
download | SMAPI-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.cs | 86 |
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>()); + } + } +} |