206 lines
6.5 KiB
C#
206 lines
6.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using CustomUtility;
|
|
using Definition;
|
|
using GameFramework.Resource;
|
|
using UnityEngine;
|
|
using UnityGameFramework.Runtime;
|
|
|
|
namespace CustomComponent
|
|
{
|
|
public class SpriteCacheComponent : GameFrameworkComponent
|
|
{
|
|
[SerializeField] private float _pixelsPerUnit = 100f;
|
|
[SerializeField] private Vector2 _defaultPivot = new(0.5f, 0.5f);
|
|
|
|
private Dictionary<string, Sprite> _spriteCache;
|
|
private Dictionary<string, List<Action<Sprite>>> _pendingCallbacks;
|
|
private HashSet<string> _loadingSpriteAssets;
|
|
private ResourceComponent _resource;
|
|
|
|
void Start()
|
|
{
|
|
EnsureRuntimeCaches();
|
|
}
|
|
|
|
private void EnsureRuntimeCaches()
|
|
{
|
|
_spriteCache ??= new Dictionary<string, Sprite>();
|
|
_pendingCallbacks ??= new Dictionary<string, List<Action<Sprite>>>();
|
|
_loadingSpriteAssets ??= new HashSet<string>();
|
|
_resource ??= GameEntry.Resource;
|
|
}
|
|
|
|
public bool TryGetCachedSprite(string assetName, out Sprite sprite)
|
|
{
|
|
EnsureRuntimeCaches();
|
|
if (string.IsNullOrWhiteSpace(assetName))
|
|
{
|
|
sprite = null;
|
|
return false;
|
|
}
|
|
|
|
return _spriteCache.TryGetValue(assetName, out sprite);
|
|
}
|
|
|
|
public void GetSprite(string assetName, Action<Sprite> callback)
|
|
{
|
|
EnsureRuntimeCaches();
|
|
if (string.IsNullOrWhiteSpace(assetName))
|
|
{
|
|
callback?.Invoke(null);
|
|
return;
|
|
}
|
|
|
|
if (_spriteCache.TryGetValue(assetName, out var sprite))
|
|
{
|
|
callback?.Invoke(sprite);
|
|
return;
|
|
}
|
|
|
|
if (callback != null)
|
|
{
|
|
AddPendingCallback(assetName, callback);
|
|
}
|
|
|
|
if (_loadingSpriteAssets.Contains(assetName))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_loadingSpriteAssets.Add(assetName);
|
|
StartLoadSprite(assetName);
|
|
}
|
|
|
|
public void PreloadSprite(string assetName)
|
|
{
|
|
EnsureRuntimeCaches();
|
|
if (string.IsNullOrWhiteSpace(assetName) || _spriteCache.ContainsKey(assetName) ||
|
|
_loadingSpriteAssets.Contains(assetName))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_loadingSpriteAssets.Add(assetName);
|
|
StartLoadSprite(assetName);
|
|
}
|
|
|
|
public void PreloadSprites(IEnumerable<string> assetNames)
|
|
{
|
|
EnsureRuntimeCaches();
|
|
if (assetNames == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
foreach (string assetName in assetNames)
|
|
{
|
|
PreloadSprite(assetName);
|
|
}
|
|
}
|
|
|
|
public void RegisterSprite(string assetName, Sprite sprite, bool overwrite = true)
|
|
{
|
|
EnsureRuntimeCaches();
|
|
if (string.IsNullOrWhiteSpace(assetName) || sprite == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!overwrite && _spriteCache.ContainsKey(assetName))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_spriteCache[assetName] = sprite;
|
|
InvokeAndClearPendingCallbacks(assetName, sprite);
|
|
_loadingSpriteAssets.Remove(assetName);
|
|
}
|
|
|
|
private void StartLoadSprite(string assetName)
|
|
{
|
|
EnsureRuntimeCaches();
|
|
if (_resource == null)
|
|
{
|
|
InvokeAndClearPendingCallbacks(assetName, null);
|
|
_loadingSpriteAssets.Remove(assetName);
|
|
return;
|
|
}
|
|
|
|
_resource.LoadAsset
|
|
(
|
|
AssetUtility.GetUISpriteAsset(assetName),
|
|
Constant.AssetPriority.UIFormAsset,
|
|
new LoadAssetCallbacks(
|
|
(resourcePath, asset, duration, userData) =>
|
|
{
|
|
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;
|
|
}
|
|
else
|
|
{
|
|
Log.Warning("Load sprite succeeded but asset is not Texture2D. AssetName='{0}', Path='{1}'.",
|
|
assetName, resourcePath);
|
|
}
|
|
|
|
InvokeAndClearPendingCallbacks(assetName, loadedSprite);
|
|
_loadingSpriteAssets.Remove(assetName);
|
|
},
|
|
(resourcePath, status, errorMessage, userData) =>
|
|
{
|
|
Log.Error("Can not load icon '{0}' from '{1}' with error message '{2}'.",
|
|
assetName,
|
|
resourcePath,
|
|
errorMessage);
|
|
InvokeAndClearPendingCallbacks(assetName, null);
|
|
_loadingSpriteAssets.Remove(assetName);
|
|
}
|
|
)
|
|
);
|
|
}
|
|
|
|
private void AddPendingCallback(string assetName, Action<Sprite> callback)
|
|
{
|
|
EnsureRuntimeCaches();
|
|
if (!_pendingCallbacks.TryGetValue(assetName, out List<Action<Sprite>> callbackList))
|
|
{
|
|
callbackList = new List<Action<Sprite>>();
|
|
_pendingCallbacks.Add(assetName, callbackList);
|
|
}
|
|
|
|
callbackList.Add(callback);
|
|
}
|
|
|
|
private void InvokeAndClearPendingCallbacks(string assetName, Sprite sprite)
|
|
{
|
|
EnsureRuntimeCaches();
|
|
if (!_pendingCallbacks.TryGetValue(assetName, out List<Action<Sprite>> callbackList))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_pendingCallbacks.Remove(assetName);
|
|
for (int i = 0; i < callbackList.Count; i++)
|
|
{
|
|
callbackList[i]?.Invoke(sprite);
|
|
}
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
_spriteCache?.Clear();
|
|
_pendingCallbacks?.Clear();
|
|
_loadingSpriteAssets?.Clear();
|
|
_resource = null;
|
|
}
|
|
}
|
|
}
|