调整 SpriteCache 的读取资源方式

将原来 UGF 事件回调风格的调用改成使用 UniTask 的异步操作
This commit is contained in:
SepComet 2026-06-04 22:37:55 +08:00
parent 117dd123de
commit 2a0cbc8f0e
8 changed files with 88 additions and 83 deletions

View File

@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using SepCore.Event; using SepCore.Event;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
@ -10,7 +11,7 @@ namespace SepCore.UI
private RoleItemContext _context = null; private RoleItemContext _context = null;
public void OnInit(RoleItemContext context) public async UniTaskVoid OnInit(RoleItemContext context)
{ {
_context = context; _context = context;
if (_context == null || string.IsNullOrEmpty(_context.IconName)) if (_context == null || string.IsNullOrEmpty(_context.IconName))
@ -18,7 +19,7 @@ namespace SepCore.UI
return; return;
} }
GameEntry.SpriteCache.GetSprite(_context.IconName, sprite => _roleImage.sprite = sprite); _roleImage.sprite = await GameEntry.SpriteCache.GetSprite(_context.IconName);
} }
public void OnReset() public void OnReset()

View File

@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using SepCore.CustomUtility; using SepCore.CustomUtility;
using SepCore.DataTable; using SepCore.DataTable;
using SepCore.Definition; using SepCore.Definition;
@ -24,31 +25,37 @@ namespace SepCore.UI
ItemType = ItemType.None; ItemType = ItemType.None;
} }
public GoodsItemContext(GoodsItemRawData rawData) public static async UniTask<GoodsItemContext> CreateAsync(GoodsItemRawData rawData)
{ {
Price = rawData.Price; var context = new GoodsItemContext
Rarity = rawData.Rarity;
ItemType = rawData.ItemType;
if (ItemType == ItemType.None)
{ {
Description = string.Empty; Price = rawData.Price,
Icon = null; Rarity = rawData.Rarity,
Title = string.Empty; ItemType = rawData.ItemType
};
if (context.ItemType == ItemType.None)
{
context.Description = string.Empty;
context.Icon = null;
context.Title = string.Empty;
} }
else if (ItemType == ItemType.Weapon) else if (context.ItemType == ItemType.Weapon)
{ {
var weapon = (DRWeapon)rawData.DataRow; var weapon = (DRWeapon)rawData.DataRow;
Title = weapon.Title; context.Title = weapon.Title;
Description = ItemDescUtility.CreateWeaponDescription(weapon); context.Description = ItemDescUtility.CreateWeaponDescription(weapon);
GameEntry.SpriteCache.GetSprite(weapon.IconAssetName, sprite => Icon = sprite); context.Icon = await GameEntry.SpriteCache.GetSprite(weapon.IconAssetName);
} }
else else
{ {
var prop = (DRProp)rawData.DataRow; var prop = (DRProp)rawData.DataRow;
Title = prop.Title; context.Title = prop.Title;
Description = ItemDescUtility.CreatePropDescription(prop.Modifiers); context.Description = ItemDescUtility.CreatePropDescription(prop.Modifiers);
GameEntry.SpriteCache.GetSprite(prop.IconAssetName, sprite => Icon = sprite); context.Icon = await GameEntry.SpriteCache.GetSprite(prop.IconAssetName);
} }
return context;
} }
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using Cysharp.Threading.Tasks;
using SepCore.Event; using SepCore.Event;
using TMPro; using TMPro;
using UnityEngine; using UnityEngine;
@ -36,7 +37,7 @@ namespace SepCore.UI
private Vector3 _targetPos; private Vector3 _targetPos;
public void RefreshUI(DisplayItemInfoContext context) public async UniTaskVoid RefreshUI(DisplayItemInfoContext context)
{ {
if (context == null) if (context == null)
{ {
@ -64,21 +65,16 @@ namespace SepCore.UI
_recycleButton.gameObject.SetActive(_context.ItemType == ItemType.Weapon); _recycleButton.gameObject.SetActive(_context.ItemType == ItemType.Weapon);
} }
if (_iconArea != null) if (_iconArea != null && !string.IsNullOrEmpty(_context.IconAssetName))
{
if (!string.IsNullOrEmpty(_context.IconAssetName))
{ {
string iconAssetName = _context.IconAssetName; string iconAssetName = _context.IconAssetName;
GameEntry.SpriteCache.GetSprite(iconAssetName, sprite => var sprite = await GameEntry.SpriteCache.GetSprite(iconAssetName);
{
if (_context != null && _context.IconAssetName == iconAssetName) if (_context != null && _context.IconAssetName == iconAssetName)
{ {
_iconArea.OnInit(sprite, context.Rarity); _iconArea.OnInit(sprite, context.Rarity);
ResizeToFitContent(); ResizeToFitContent();
ApplyClampedTargetPos(); ApplyClampedTargetPos();
} }
});
}
} }
ResizeToFitContent(); ResizeToFitContent();

View File

@ -42,7 +42,7 @@ namespace SepCore.UI
#region BuildContext #region BuildContext
private ShopContext BuildContext(ShopRawData rawData) private async UniTask<ShopContext> BuildContext(ShopRawData rawData)
{ {
if (rawData == null) if (rawData == null)
{ {
@ -55,7 +55,7 @@ namespace SepCore.UI
List<GoodsItemContext> goodsItems = new List<GoodsItemContext>(); List<GoodsItemContext> goodsItems = new List<GoodsItemContext>();
foreach (var item in rawData.GoodsItems) foreach (var item in rawData.GoodsItems)
{ {
goodsItems.Add(new GoodsItemContext(item)); goodsItems.Add(await GoodsItemContext.CreateAsync(item));
} }
return new ShopContext return new ShopContext
@ -214,7 +214,7 @@ namespace SepCore.UI
public async UniTask<int?> OpenUIAsync(ShopRawData rawData, float timeout = 30f) public async UniTask<int?> OpenUIAsync(ShopRawData rawData, float timeout = 30f)
{ {
ShopContext context = BuildContext(rawData); ShopContext context = await BuildContext(rawData);
return await OpenFormAsync(context, timeout); return await OpenFormAsync(context, timeout);
} }
@ -256,7 +256,7 @@ namespace SepCore.UI
#region Service #region Service
private void RefreshGoodsItems(ShopRefreshResult result) private async UniTask RefreshGoodsItems(ShopRefreshResult result)
{ {
if (result == null) if (result == null)
{ {
@ -272,8 +272,8 @@ namespace SepCore.UI
for (int i = 0; i < result.GoodsItems.Count; i++) for (int i = 0; i < result.GoodsItems.Count; i++)
{ {
if (i < Context.GoodsItems.Count) Context.GoodsItems[i] = new GoodsItemContext(result.GoodsItems[i]); if (i < Context.GoodsItems.Count) Context.GoodsItems[i] = await GoodsItemContext.CreateAsync(result.GoodsItems[i]);
else Context.GoodsItems.Add(new GoodsItemContext(result.GoodsItems[i])); else Context.GoodsItems.Add(await GoodsItemContext.CreateAsync(result.GoodsItems[i]));
} }
if (Context.GoodsItems.Count != result.GoodsItems.Count) if (Context.GoodsItems.Count != result.GoodsItems.Count)
@ -425,7 +425,7 @@ namespace SepCore.UI
#region Event Handlers #region Event Handlers
private void Refresh(object sender, GameEventArgs e) private async void Refresh(object sender, GameEventArgs e)
{ {
if (sender is not ShopForm) if (sender is not ShopForm)
{ {
@ -443,7 +443,7 @@ namespace SepCore.UI
return; return;
} }
RefreshGoodsItems(result); await RefreshGoodsItems(result);
} }
private void ShopPurchase(object sender, GameEventArgs e) private void ShopPurchase(object sender, GameEventArgs e)

View File

@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using SepCore.Event; using SepCore.Event;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
@ -19,7 +20,7 @@ namespace SepCore.UI
_index = index; _index = index;
} }
public void OnInit(DisplayItemContext context, int index) public async UniTaskVoid OnInit(DisplayItemContext context, int index)
{ {
if (context == null) return; if (context == null) return;
@ -28,8 +29,8 @@ namespace SepCore.UI
if (_iconArea != null) if (_iconArea != null)
{ {
string iconName = _context.IconAssetName; var sprite = await GameEntry.SpriteCache.GetSprite(_context.IconAssetName);
GameEntry.SpriteCache.GetSprite(iconName, sprite => { _iconArea.OnInit(sprite, context.Rarity); }); _iconArea.OnInit(sprite, context.Rarity);
} }
} }

View File

@ -1,3 +1,4 @@
using Cysharp.Threading.Tasks;
using TMPro; using TMPro;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
@ -32,16 +33,17 @@ namespace SepCore.UI
if (_descriptionText != null) _descriptionText.text = context.Description; if (_descriptionText != null) _descriptionText.text = context.Description;
if (_iconArea != null) _iconArea.OnInit(context.Icon, context.ItemRarity); if (_iconArea != null) _iconArea.OnInit(context.Icon, context.ItemRarity);
LoadIcon(_context.IconAssetName); LoadIcon(_context.IconAssetName).Forget();
} }
private void LoadIcon(string iconAssetName) private async UniTaskVoid LoadIcon(string iconAssetName)
{ {
if (_iconArea == null) return; if (_iconArea == null) return;
if (string.IsNullOrEmpty(iconAssetName)) return; if (string.IsNullOrEmpty(iconAssetName)) return;
GameEntry.SpriteCache.GetSprite(iconAssetName, sprite => _iconArea.SetIcon(sprite)); var sprite = await GameEntry.SpriteCache.GetSprite(iconAssetName);
_iconArea.SetIcon(sprite);
} }
} }
} }

View File

@ -1,4 +1,6 @@
using System;
using Cysharp.Threading.Tasks; using Cysharp.Threading.Tasks;
using GameFramework.Resource;
using UnityGameFramework.Runtime; using UnityGameFramework.Runtime;
using ResourceApplySuccessEventArgs = UnityGameFramework.Runtime.ResourceApplySuccessEventArgs; using ResourceApplySuccessEventArgs = UnityGameFramework.Runtime.ResourceApplySuccessEventArgs;
using ResourceUpdateAllCompleteEventArgs = UnityGameFramework.Runtime.ResourceUpdateAllCompleteEventArgs; using ResourceUpdateAllCompleteEventArgs = UnityGameFramework.Runtime.ResourceUpdateAllCompleteEventArgs;
@ -11,6 +13,24 @@ namespace SepCore.AsyncTask
/// </summary> /// </summary>
public static class ResourceAsyncExtension public static class ResourceAsyncExtension
{ {
/// <summary>
/// 异步加载资源
/// </summary>
/// <typeparam name="T">资源类型</typeparam>
/// <param name="resourceComponent">资源组件</param>
/// <param name="assetName">资源名称</param>
/// <param name="priority">加载优先级</param>
/// <returns>加载完成的资源</returns>
public static UniTask<T> LoadAssetAsync<T>(this ResourceComponent resourceComponent, string assetName, int priority = 0)
{
var tcs = AutoResetUniTaskCompletionSource<T>.Create();
resourceComponent.LoadAsset(assetName, priority, new LoadAssetCallbacks(
(_, asset, _, _) => tcs.TrySetResult((T)asset),
(_, _, errorMessage, _) => tcs.TrySetException(new Exception(errorMessage))
));
return tcs.Task;
}
/// <summary> /// <summary>
/// 异步等待资源更新完成 /// 异步等待资源更新完成
/// </summary> /// </summary>

View File

@ -1,8 +1,9 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using SepCore.Definition; using Cysharp.Threading.Tasks;
using GameFramework.Resource; using GameFramework.Resource;
using SepCore.AsyncTask;
using SepCore.CustomUtility; using SepCore.CustomUtility;
using SepCore.Definition;
using UnityEngine; using UnityEngine;
using UnityGameFramework.Runtime; using UnityGameFramework.Runtime;
@ -22,45 +23,22 @@ namespace SepCore.SpriteCache
_resource = GameEntry.Resource; _resource = GameEntry.Resource;
} }
public void GetSprite(string assetName, Action<Sprite> callback) public async UniTask<Sprite> GetSprite(string assetName)
{ {
if (_spriteCache.TryGetValue(assetName, out var sprite)) if (_spriteCache.TryGetValue(assetName, out var sprite))
{ return sprite;
callback?.Invoke(sprite);
return; var texture = await _resource.LoadAssetAsync<Texture2D>(
}
else
{
_resource.LoadAsset
(
AssetUtility.GetUITextureIconAsset(assetName), AssetUtility.GetUITextureIconAsset(assetName),
Constant.AssetPriority.UIFormAsset, Constant.AssetPriority.UIFormAsset);
new LoadAssetCallbacks(
(resourcePath, asset, duration, userData) => var newSprite = Sprite.Create(
{
Log.Debug(resourcePath);
Texture2D texture = asset as Texture2D;
if (texture != null)
{
Sprite newSprite = Sprite.Create(
texture, texture,
new Rect(0, 0, texture.width, texture.height), new Rect(0, 0, texture.width, texture.height),
_defaultPivot, _defaultPivot,
_pixelsPerUnit); _pixelsPerUnit);
_spriteCache.TryAdd(assetName, newSprite); _spriteCache.TryAdd(assetName, newSprite);
callback?.Invoke(newSprite); return newSprite;
}
},
(resourcePath, status, errorMessage, userData) =>
{
Log.Error("Can not load icon '{0}' from '{1}' with error message '{2}'.",
assetName,
resourcePath,
errorMessage);
}
)
);
}
} }
private void OnDestroy() private void OnDestroy()