using System; using System.Collections.Generic; using UnityEngine; namespace Coffee.UIParticleInternal { internal static class FrameCache { private static readonly Dictionary s_Caches = new Dictionary(); static FrameCache() { s_Caches.Clear(); UIExtraCallbacks.onLateAfterCanvasRebuild += ClearAllCache; } #if UNITY_EDITOR [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void Clear() { s_Caches.Clear(); } #endif /// /// Tries to retrieve a value from the frame cache with a specified key. /// public static bool TryGet(object key1, string key2, out T result) { return GetFrameCache().TryGet((key1.GetHashCode(), key2.GetHashCode()), out result); } /// /// Tries to retrieve a value from the frame cache with a specified key. /// public static bool TryGet(object key1, string key2, int key3, out T result) { return GetFrameCache().TryGet((key1.GetHashCode(), key2.GetHashCode() + key3), out result); } /// /// Sets a value in the frame cache with a specified key. /// public static void Set(object key1, string key2, T result) { GetFrameCache().Set((key1.GetHashCode(), key2.GetHashCode()), result); } /// /// Sets a value in the frame cache with a specified key. /// public static void Set(object key1, string key2, int key3, T result) { GetFrameCache().Set((key1.GetHashCode(), key2.GetHashCode() + key3), result); } private static void ClearAllCache() { foreach (var cache in s_Caches.Values) { cache.Clear(); } } private static FrameCacheContainer GetFrameCache() { var t = typeof(T); if (s_Caches.TryGetValue(t, out var frameCache)) return frameCache as FrameCacheContainer; frameCache = new FrameCacheContainer(); s_Caches.Add(t, frameCache); return (FrameCacheContainer)frameCache; } private interface IFrameCache { void Clear(); } private class FrameCacheContainer : IFrameCache { private readonly Dictionary<(int, int), T> _caches = new Dictionary<(int, int), T>(); public void Clear() { _caches.Clear(); } public bool TryGet((int, int) key, out T result) { return _caches.TryGetValue(key, out result); } public void Set((int, int) key, T result) { _caches[key] = result; } } } }