From b07d2340a9a6da22ee0fd95f2c6ccca3939cb7ab Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 22 Mar 2022 23:00:18 -0400 Subject: encapsulate & cache asset operation groups (#766) This is needed for the upcoming Stardew Valley 1.6 to avoid duplicate checks between DoesAssetExist and Load calls, and to make sure the answer doesn't change between them. --- .../Framework/Utilities/TickCacheDictionary.cs | 51 ++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/SMAPI/Framework/Utilities/TickCacheDictionary.cs (limited to 'src/SMAPI/Framework/Utilities') diff --git a/src/SMAPI/Framework/Utilities/TickCacheDictionary.cs b/src/SMAPI/Framework/Utilities/TickCacheDictionary.cs new file mode 100644 index 00000000..1613a480 --- /dev/null +++ b/src/SMAPI/Framework/Utilities/TickCacheDictionary.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using StardewValley; + +namespace StardewModdingAPI.Framework.Utilities +{ + /// An in-memory dictionary cache that stores data for the duration of a game update tick. + /// The dictionary key type. + /// The dictionary value type. + internal class TickCacheDictionary + { + /********* + ** Fields + *********/ + /// The last game tick for which data was cached. + private int LastGameTick = -1; + + /// The underlying cached data. + private readonly Dictionary Cache = new(); + + + /********* + ** Public methods + *********/ + /// Get a value from the cache, fetching it first if it's not cached yet. + /// The unique key for the cached value. + /// Get the latest data if it's not in the cache yet. + public TValue GetOrSet(TKey cacheKey, Func get) + { + // clear cache on new tick + if (Game1.ticks != this.LastGameTick) + { + this.Cache.Clear(); + this.LastGameTick = Game1.ticks; + } + + // fetch value + if (!this.Cache.TryGetValue(cacheKey, out TValue cached)) + this.Cache[cacheKey] = cached = get(); + return cached; + } + + /// Remove an entry from the cache. + /// The unique key for the cached value. + /// Returns whether the key was present in the dictionary. + public bool Remove(TKey cacheKey) + { + return this.Cache.Remove(cacheKey); + } + } +} -- cgit