using System; using System.Collections.Generic; using GameFramework.Resource; using GeometryTD.CustomUtility; using UnityEngine; using UnityGameFramework.Runtime; namespace GeometryTD.CustomComponent { public class SpriteCacheComponent : GameFrameworkComponent { [SerializeField] private float _pixelsPerUnit = 100f; [SerializeField] private Vector2 _defaultPivot = new(0.5f, 0.5f); private Dictionary _spriteCache; private Dictionary>> _pendingCallbacks; private ResourceComponent _resource; void Start() { _spriteCache = new Dictionary(); _pendingCallbacks = new Dictionary>>(); _resource = GameEntry.Resource; } public void GetSprite(string assetName, Action callback) { if (_spriteCache.TryGetValue(assetName, out var sprite)) { callback?.Invoke(sprite); return; } if (_pendingCallbacks.TryGetValue(assetName, out var pendingList)) { pendingList.Add(callback); return; } _pendingCallbacks[assetName] = new List> { callback }; _resource.LoadAsset ( AssetUtility.GetTextureAsset(assetName), Constant.AssetPriority.UIFormAsset, new LoadAssetCallbacks( (resourcePath, asset, duration, userData) => { Log.Debug(resourcePath); Texture2D texture = asset as Texture2D; Sprite loadedSprite = null; if (texture != null) { loadedSprite = Sprite.Create( texture, new Rect(0, 0, texture.width, texture.height), _defaultPivot, _pixelsPerUnit); _spriteCache[assetName] = loadedSprite; } if (_pendingCallbacks.TryGetValue(assetName, out var callbacks)) { _pendingCallbacks.Remove(assetName); for (int i = 0; i < callbacks.Count; i++) { callbacks[i]?.Invoke(loadedSprite); } } }, (resourcePath, status, errorMessage, userData) => { Log.Error("Can not load icon '{0}' from '{1}' with error message '{2}'.", assetName, resourcePath, errorMessage); if (_pendingCallbacks.TryGetValue(assetName, out var callbacks)) { _pendingCallbacks.Remove(assetName); for (int i = 0; i < callbacks.Count; i++) { callbacks[i]?.Invoke(null); } } } ) ); } private void OnDestroy() { _spriteCache.Clear(); _pendingCallbacks.Clear(); _resource = null; } } }