diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-08-21 16:39:21 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-08-21 16:39:21 -0400 |
commit | 8ba54a682fd7de3756b6ddd262b232cf40d23ea0 (patch) | |
tree | 7e44d53b733d95b05b232da46306a0d3d57e9231 /src/StardewModdingAPI/Framework/Utilities/ContextHash.cs | |
parent | 674ad0d90f8780130a5fcefb3869acfe2315df2a (diff) | |
parent | eea5100acea0bceaf440f9d1bd50ee2b24cf8ebc (diff) | |
download | SMAPI-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.cs | 62 |
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); + } + } + } +} |