summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/Utilities
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2017-10-07 23:07:10 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2017-10-07 23:07:10 -0400
commit929dccb75a1405737975d76648e015a3e7c00177 (patch)
tree659fe16509327e694555db363caf7f47f326443b /src/SMAPI/Framework/Utilities
parent926894f8f52c2a5cf104fcac2f7f34b637f7b531 (diff)
downloadSMAPI-929dccb75a1405737975d76648e015a3e7c00177.tar.gz
SMAPI-929dccb75a1405737975d76648e015a3e7c00177.tar.bz2
SMAPI-929dccb75a1405737975d76648e015a3e7c00177.zip
reorganise repo structure
Diffstat (limited to 'src/SMAPI/Framework/Utilities')
-rw-r--r--src/SMAPI/Framework/Utilities/ContextHash.cs61
-rw-r--r--src/SMAPI/Framework/Utilities/Countdown.cs44
2 files changed, 105 insertions, 0 deletions
diff --git a/src/SMAPI/Framework/Utilities/ContextHash.cs b/src/SMAPI/Framework/Utilities/ContextHash.cs
new file mode 100644
index 00000000..6c0fdc90
--- /dev/null
+++ b/src/SMAPI/Framework/Utilities/ContextHash.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+
+namespace StardewModdingAPI.Framework.Utilities
+{
+ /// <summary>A <see cref="HashSet{T}"/> wrapper meant for tracking recursive contexts.</summary>
+ /// <typeparam name="T">The key type.</typeparam>
+ internal class ContextHash<T> : HashSet<T>
+ {
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Construct an instance.</summary>
+ public ContextHash() { }
+
+ /// <summary>Construct an instance.</summary>
+ /// <param name="comparer">The <see cref="IEqualityComparer{T}"/> implementation to use when comparing values in the set, or <c>null</c> to use the default comparer for the set type.</param>
+ public ContextHash(IEqualityComparer<T> comparer)
+ : base(comparer) { }
+
+ /// <summary>Add a key while an action is in progress, and remove it when it completes.</summary>
+ /// <param name="key">The key to add.</param>
+ /// <param name="action">The action to perform.</param>
+ /// <exception cref="InvalidOperationException">The specified key is already added.</exception>
+ public void Track(T key, Action action)
+ {
+ if (this.Contains(key))
+ throw new InvalidOperationException($"Can't track context for key {key} because it's already added.");
+
+ this.Add(key);
+ try
+ {
+ action();
+ }
+ finally
+ {
+ this.Remove(key);
+ }
+ }
+
+ /// <summary>Add a key while an action is in progress, and remove it when it completes.</summary>
+ /// <typeparam name="TResult">The value type returned by the method.</typeparam>
+ /// <param name="key">The key to add.</param>
+ /// <param name="action">The action to perform.</param>
+ public TResult Track<TResult>(T key, Func<TResult> action)
+ {
+ if (this.Contains(key))
+ throw new InvalidOperationException($"Can't track context for key {key} because it's already added.");
+
+ this.Add(key);
+ try
+ {
+ return action();
+ }
+ finally
+ {
+ this.Remove(key);
+ }
+ }
+ }
+}
diff --git a/src/SMAPI/Framework/Utilities/Countdown.cs b/src/SMAPI/Framework/Utilities/Countdown.cs
new file mode 100644
index 00000000..921a35ce
--- /dev/null
+++ b/src/SMAPI/Framework/Utilities/Countdown.cs
@@ -0,0 +1,44 @@
+namespace StardewModdingAPI.Framework.Utilities
+{
+ /// <summary>Counts down from a baseline value.</summary>
+ internal class Countdown
+ {
+ /*********
+ ** Accessors
+ *********/
+ /// <summary>The initial value from which to count down.</summary>
+ public int Initial { get; }
+
+ /// <summary>The current value.</summary>
+ public int Current { get; private set; }
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Construct an instance.</summary>
+ /// <param name="initial">The initial value from which to count down.</param>
+ public Countdown(int initial)
+ {
+ this.Initial = initial;
+ this.Current = initial;
+ }
+
+ /// <summary>Reduce the current value by one.</summary>
+ /// <returns>Returns whether the value was decremented (i.e. wasn't already zero).</returns>
+ public bool Decrement()
+ {
+ if (this.Current <= 0)
+ return false;
+
+ this.Current--;
+ return true;
+ }
+
+ /// <summary>Restart the countdown.</summary>
+ public void Reset()
+ {
+ this.Current = this.Initial;
+ }
+ }
+}