From 5550c27744cf3e0fa4895522654847891fbf4150 Mon Sep 17 00:00:00 2001 From: KoalaTrapLord Date: Wed, 18 Mar 2026 02:06:08 -0400 Subject: [PATCH] Unity: Add ImageCache.cs singleton for card art Sprite caching (#50) --- .../Assets/Scripts/Services/ImageCache.cs | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 unity-client/Assets/Scripts/Services/ImageCache.cs diff --git a/unity-client/Assets/Scripts/Services/ImageCache.cs b/unity-client/Assets/Scripts/Services/ImageCache.cs new file mode 100644 index 0000000..d6ba017 --- /dev/null +++ b/unity-client/Assets/Scripts/Services/ImageCache.cs @@ -0,0 +1,55 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Networking; + +namespace CommanderAILab.Services +{ + /// + /// Singleton texture cache for card images. + /// Downloads and caches Scryfall card art as Sprite objects. + /// + public class ImageCache : MonoBehaviour + { + public static ImageCache Instance { get; private set; } + + private readonly Dictionary cache = new(); + [SerializeField] private int maxCacheSize = 500; + + private void Awake() + { + if (Instance != null && Instance != this) { Destroy(gameObject); return; } + Instance = this; + DontDestroyOnLoad(gameObject); + } + + public void GetSprite(string url, System.Action callback) + { + if (string.IsNullOrEmpty(url)) { callback?.Invoke(null); return; } + if (cache.TryGetValue(url, out var cached)) { callback?.Invoke(cached); return; } + StartCoroutine(DownloadImage(url, callback)); + } + + private IEnumerator DownloadImage(string url, System.Action callback) + { + using var request = UnityWebRequestTexture.GetTexture(url); + yield return request.SendWebRequest(); + + if (request.result != UnityWebRequest.Result.Success) + { + Debug.LogWarning($"[ImageCache] Failed to load {url}: {request.error}"); + callback?.Invoke(null); + yield break; + } + + var tex = DownloadHandlerTexture.GetContent(request); + var sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.one * 0.5f); + + if (cache.Count >= maxCacheSize) cache.Clear(); + cache[url] = sprite; + callback?.Invoke(sprite); + } + + public void ClearCache() => cache.Clear(); + } +}