summaryrefslogtreecommitdiff
path: root/src/StardewModdingAPI/Framework/Utilities/ContextHash.cs
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2017-08-21 16:39:21 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2017-08-21 16:39:21 -0400
commit8ba54a682fd7de3756b6ddd262b232cf40d23ea0 (patch)
tree7e44d53b733d95b05b232da46306a0d3d57e9231 /src/StardewModdingAPI/Framework/Utilities/ContextHash.cs
parent674ad0d90f8780130a5fcefb3869acfe2315df2a (diff)
parenteea5100acea0bceaf440f9d1bd50ee2b24cf8ebc (diff)
downloadSMAPI-8ba54a682fd7de3756b6ddd262b232cf40d23ea0.tar.gz
SMAPI-8ba54a682fd7de3756b6ddd262b232cf40d23ea0.tar.bz2
SMAPI-8ba54a682fd7de3756b6ddd262b232cf40d23ea0.zip
Merge branch 'develop' into stable
Diffstat (limited to 'src/StardewModdingAPI/Framework/Utilities/ContextHash.cs')
-rw-r--r--src/StardewModdingAPI/Framework/Utilities/ContextHash.cs62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/StardewModdingAPI/Framework/Utilities/ContextHash.cs b/src/StardewModdingAPI/Framework/Utilities/ContextHash.cs
new file mode 100644
index 00000000..0d8487bb
--- /dev/null
+++ b/src/StardewModdingAPI/Framework/Utilities/ContextHash.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections;
+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);
+ }
+ }
+ }
+}