From 2a0cbc8f0e053284d4ecea14613f9e4dd3576422 Mon Sep 17 00:00:00 2001 From: SepComet <202308010230@stu.csust.edu.cn> Date: Thu, 4 Jun 2026 22:37:55 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=20SpriteCache=20=E7=9A=84?= =?UTF-8?q?=E8=AF=BB=E5=8F=96=E8=B5=84=E6=BA=90=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将原来 UGF 事件回调风格的调用改成使用 UniTask 的异步操作 --- .../Presentation/Common/View/RoleItem.cs | 5 +- .../Main/Context/GoodsItemContext.cs | 37 +++++++----- .../DisplayItemInfo/DisplayItemInfoForm.cs | 22 +++----- .../Presentation/Main/Shop/ShopController.cs | 16 +++--- .../Presentation/Main/View/DisplayItem.cs | 7 ++- .../Main/View/LevelUpRewardItem.cs | 8 ++- .../AsyncTask/ResourceAsyncExtension.cs | 20 +++++++ .../SpriteCache/SpriteCacheComponent.cs | 56 ++++++------------- 8 files changed, 88 insertions(+), 83 deletions(-) diff --git a/Assets/GameMain/Scripts/Presentation/Common/View/RoleItem.cs b/Assets/GameMain/Scripts/Presentation/Common/View/RoleItem.cs index 65db07d..8e9043c 100644 --- a/Assets/GameMain/Scripts/Presentation/Common/View/RoleItem.cs +++ b/Assets/GameMain/Scripts/Presentation/Common/View/RoleItem.cs @@ -1,3 +1,4 @@ +using Cysharp.Threading.Tasks; using SepCore.Event; using UnityEngine; using UnityEngine.UI; @@ -10,7 +11,7 @@ namespace SepCore.UI private RoleItemContext _context = null; - public void OnInit(RoleItemContext context) + public async UniTaskVoid OnInit(RoleItemContext context) { _context = context; if (_context == null || string.IsNullOrEmpty(_context.IconName)) @@ -18,7 +19,7 @@ namespace SepCore.UI return; } - GameEntry.SpriteCache.GetSprite(_context.IconName, sprite => _roleImage.sprite = sprite); + _roleImage.sprite = await GameEntry.SpriteCache.GetSprite(_context.IconName); } public void OnReset() diff --git a/Assets/GameMain/Scripts/Presentation/Main/Context/GoodsItemContext.cs b/Assets/GameMain/Scripts/Presentation/Main/Context/GoodsItemContext.cs index c139629..1258a62 100644 --- a/Assets/GameMain/Scripts/Presentation/Main/Context/GoodsItemContext.cs +++ b/Assets/GameMain/Scripts/Presentation/Main/Context/GoodsItemContext.cs @@ -1,3 +1,4 @@ +using Cysharp.Threading.Tasks; using SepCore.CustomUtility; using SepCore.DataTable; using SepCore.Definition; @@ -24,31 +25,37 @@ namespace SepCore.UI ItemType = ItemType.None; } - public GoodsItemContext(GoodsItemRawData rawData) + public static async UniTask CreateAsync(GoodsItemRawData rawData) { - Price = rawData.Price; - Rarity = rawData.Rarity; - ItemType = rawData.ItemType; - if (ItemType == ItemType.None) + var context = new GoodsItemContext { - Description = string.Empty; - Icon = null; - Title = string.Empty; + Price = rawData.Price, + Rarity = rawData.Rarity, + 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; - Title = weapon.Title; - Description = ItemDescUtility.CreateWeaponDescription(weapon); - GameEntry.SpriteCache.GetSprite(weapon.IconAssetName, sprite => Icon = sprite); + context.Title = weapon.Title; + context.Description = ItemDescUtility.CreateWeaponDescription(weapon); + context.Icon = await GameEntry.SpriteCache.GetSprite(weapon.IconAssetName); } else { var prop = (DRProp)rawData.DataRow; - Title = prop.Title; - Description = ItemDescUtility.CreatePropDescription(prop.Modifiers); - GameEntry.SpriteCache.GetSprite(prop.IconAssetName, sprite => Icon = sprite); + context.Title = prop.Title; + context.Description = ItemDescUtility.CreatePropDescription(prop.Modifiers); + context.Icon = await GameEntry.SpriteCache.GetSprite(prop.IconAssetName); } + + return context; } } } diff --git a/Assets/GameMain/Scripts/Presentation/Main/DisplayItemInfo/DisplayItemInfoForm.cs b/Assets/GameMain/Scripts/Presentation/Main/DisplayItemInfo/DisplayItemInfoForm.cs index a7f6902..c31454d 100644 --- a/Assets/GameMain/Scripts/Presentation/Main/DisplayItemInfo/DisplayItemInfoForm.cs +++ b/Assets/GameMain/Scripts/Presentation/Main/DisplayItemInfo/DisplayItemInfoForm.cs @@ -1,4 +1,5 @@ using System; +using Cysharp.Threading.Tasks; using SepCore.Event; using TMPro; using UnityEngine; @@ -36,7 +37,7 @@ namespace SepCore.UI private Vector3 _targetPos; - public void RefreshUI(DisplayItemInfoContext context) + public async UniTaskVoid RefreshUI(DisplayItemInfoContext context) { if (context == null) { @@ -64,20 +65,15 @@ namespace SepCore.UI _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; + var sprite = await GameEntry.SpriteCache.GetSprite(iconAssetName); + if (_context != null && _context.IconAssetName == iconAssetName) { - string iconAssetName = _context.IconAssetName; - GameEntry.SpriteCache.GetSprite(iconAssetName, sprite => - { - if (_context != null && _context.IconAssetName == iconAssetName) - { - _iconArea.OnInit(sprite, context.Rarity); - ResizeToFitContent(); - ApplyClampedTargetPos(); - } - }); + _iconArea.OnInit(sprite, context.Rarity); + ResizeToFitContent(); + ApplyClampedTargetPos(); } } diff --git a/Assets/GameMain/Scripts/Presentation/Main/Shop/ShopController.cs b/Assets/GameMain/Scripts/Presentation/Main/Shop/ShopController.cs index e0b5c75..c91307f 100644 --- a/Assets/GameMain/Scripts/Presentation/Main/Shop/ShopController.cs +++ b/Assets/GameMain/Scripts/Presentation/Main/Shop/ShopController.cs @@ -42,7 +42,7 @@ namespace SepCore.UI #region BuildContext - private ShopContext BuildContext(ShopRawData rawData) + private async UniTask BuildContext(ShopRawData rawData) { if (rawData == null) { @@ -55,7 +55,7 @@ namespace SepCore.UI List goodsItems = new List(); foreach (var item in rawData.GoodsItems) { - goodsItems.Add(new GoodsItemContext(item)); + goodsItems.Add(await GoodsItemContext.CreateAsync(item)); } return new ShopContext @@ -214,7 +214,7 @@ namespace SepCore.UI public async UniTask OpenUIAsync(ShopRawData rawData, float timeout = 30f) { - ShopContext context = BuildContext(rawData); + ShopContext context = await BuildContext(rawData); return await OpenFormAsync(context, timeout); } @@ -256,7 +256,7 @@ namespace SepCore.UI #region Service - private void RefreshGoodsItems(ShopRefreshResult result) + private async UniTask RefreshGoodsItems(ShopRefreshResult result) { if (result == null) { @@ -272,8 +272,8 @@ namespace SepCore.UI for (int i = 0; i < result.GoodsItems.Count; i++) { - if (i < Context.GoodsItems.Count) Context.GoodsItems[i] = new GoodsItemContext(result.GoodsItems[i]); - else Context.GoodsItems.Add(new GoodsItemContext(result.GoodsItems[i])); + if (i < Context.GoodsItems.Count) Context.GoodsItems[i] = await GoodsItemContext.CreateAsync(result.GoodsItems[i]); + else Context.GoodsItems.Add(await GoodsItemContext.CreateAsync(result.GoodsItems[i])); } if (Context.GoodsItems.Count != result.GoodsItems.Count) @@ -425,7 +425,7 @@ namespace SepCore.UI #region Event Handlers - private void Refresh(object sender, GameEventArgs e) + private async void Refresh(object sender, GameEventArgs e) { if (sender is not ShopForm) { @@ -443,7 +443,7 @@ namespace SepCore.UI return; } - RefreshGoodsItems(result); + await RefreshGoodsItems(result); } private void ShopPurchase(object sender, GameEventArgs e) diff --git a/Assets/GameMain/Scripts/Presentation/Main/View/DisplayItem.cs b/Assets/GameMain/Scripts/Presentation/Main/View/DisplayItem.cs index 4c32ad3..692358f 100644 --- a/Assets/GameMain/Scripts/Presentation/Main/View/DisplayItem.cs +++ b/Assets/GameMain/Scripts/Presentation/Main/View/DisplayItem.cs @@ -1,3 +1,4 @@ +using Cysharp.Threading.Tasks; using SepCore.Event; using UnityEngine; using UnityEngine.UI; @@ -19,7 +20,7 @@ namespace SepCore.UI _index = index; } - public void OnInit(DisplayItemContext context, int index) + public async UniTaskVoid OnInit(DisplayItemContext context, int index) { if (context == null) return; @@ -28,8 +29,8 @@ namespace SepCore.UI if (_iconArea != null) { - string iconName = _context.IconAssetName; - GameEntry.SpriteCache.GetSprite(iconName, sprite => { _iconArea.OnInit(sprite, context.Rarity); }); + var sprite = await GameEntry.SpriteCache.GetSprite(_context.IconAssetName); + _iconArea.OnInit(sprite, context.Rarity); } } diff --git a/Assets/GameMain/Scripts/Presentation/Main/View/LevelUpRewardItem.cs b/Assets/GameMain/Scripts/Presentation/Main/View/LevelUpRewardItem.cs index d87e9a6..7735b7e 100644 --- a/Assets/GameMain/Scripts/Presentation/Main/View/LevelUpRewardItem.cs +++ b/Assets/GameMain/Scripts/Presentation/Main/View/LevelUpRewardItem.cs @@ -1,3 +1,4 @@ +using Cysharp.Threading.Tasks; using TMPro; using UnityEngine; using UnityEngine.UI; @@ -32,16 +33,17 @@ namespace SepCore.UI if (_descriptionText != null) _descriptionText.text = context.Description; 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 (string.IsNullOrEmpty(iconAssetName)) return; - GameEntry.SpriteCache.GetSprite(iconAssetName, sprite => _iconArea.SetIcon(sprite)); + var sprite = await GameEntry.SpriteCache.GetSprite(iconAssetName); + _iconArea.SetIcon(sprite); } } } \ No newline at end of file diff --git a/Assets/GameMain/Scripts/Runtime/BuiltinComponent/AsyncTask/ResourceAsyncExtension.cs b/Assets/GameMain/Scripts/Runtime/BuiltinComponent/AsyncTask/ResourceAsyncExtension.cs index db0b9d2..b892eac 100644 --- a/Assets/GameMain/Scripts/Runtime/BuiltinComponent/AsyncTask/ResourceAsyncExtension.cs +++ b/Assets/GameMain/Scripts/Runtime/BuiltinComponent/AsyncTask/ResourceAsyncExtension.cs @@ -1,4 +1,6 @@ +using System; using Cysharp.Threading.Tasks; +using GameFramework.Resource; using UnityGameFramework.Runtime; using ResourceApplySuccessEventArgs = UnityGameFramework.Runtime.ResourceApplySuccessEventArgs; using ResourceUpdateAllCompleteEventArgs = UnityGameFramework.Runtime.ResourceUpdateAllCompleteEventArgs; @@ -11,6 +13,24 @@ namespace SepCore.AsyncTask /// public static class ResourceAsyncExtension { + /// + /// 异步加载资源 + /// + /// 资源类型 + /// 资源组件 + /// 资源名称 + /// 加载优先级 + /// 加载完成的资源 + public static UniTask LoadAssetAsync(this ResourceComponent resourceComponent, string assetName, int priority = 0) + { + var tcs = AutoResetUniTaskCompletionSource.Create(); + resourceComponent.LoadAsset(assetName, priority, new LoadAssetCallbacks( + (_, asset, _, _) => tcs.TrySetResult((T)asset), + (_, _, errorMessage, _) => tcs.TrySetException(new Exception(errorMessage)) + )); + return tcs.Task; + } + /// /// 异步等待资源更新完成 /// diff --git a/Assets/GameMain/Scripts/Runtime/CustomComponent/SpriteCache/SpriteCacheComponent.cs b/Assets/GameMain/Scripts/Runtime/CustomComponent/SpriteCache/SpriteCacheComponent.cs index 1e454f9..42c043b 100644 --- a/Assets/GameMain/Scripts/Runtime/CustomComponent/SpriteCache/SpriteCacheComponent.cs +++ b/Assets/GameMain/Scripts/Runtime/CustomComponent/SpriteCache/SpriteCacheComponent.cs @@ -1,8 +1,9 @@ -using System; using System.Collections.Generic; -using SepCore.Definition; +using Cysharp.Threading.Tasks; using GameFramework.Resource; +using SepCore.AsyncTask; using SepCore.CustomUtility; +using SepCore.Definition; using UnityEngine; using UnityGameFramework.Runtime; @@ -22,45 +23,22 @@ namespace SepCore.SpriteCache _resource = GameEntry.Resource; } - public void GetSprite(string assetName, Action callback) + public async UniTask GetSprite(string assetName) { if (_spriteCache.TryGetValue(assetName, out var sprite)) - { - callback?.Invoke(sprite); - return; - } - else - { - _resource.LoadAsset - ( - AssetUtility.GetUITextureIconAsset(assetName), - Constant.AssetPriority.UIFormAsset, - new LoadAssetCallbacks( - (resourcePath, asset, duration, userData) => - { - Log.Debug(resourcePath); - Texture2D texture = asset as Texture2D; - if (texture != null) - { - Sprite newSprite = Sprite.Create( - texture, - new Rect(0, 0, texture.width, texture.height), - _defaultPivot, - _pixelsPerUnit); - _spriteCache.TryAdd(assetName, newSprite); - callback?.Invoke(newSprite); - } - }, - (resourcePath, status, errorMessage, userData) => - { - Log.Error("Can not load icon '{0}' from '{1}' with error message '{2}'.", - assetName, - resourcePath, - errorMessage); - } - ) - ); - } + return sprite; + + var texture = await _resource.LoadAssetAsync( + AssetUtility.GetUITextureIconAsset(assetName), + Constant.AssetPriority.UIFormAsset); + + var newSprite = Sprite.Create( + texture, + new Rect(0, 0, texture.width, texture.height), + _defaultPivot, + _pixelsPerUnit); + _spriteCache.TryAdd(assetName, newSprite); + return newSprite; } private void OnDestroy()