using asap.core; using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using UniRx; using UnityEngine; public abstract class EventButtonResource : MonoBehaviour { // 取消令牌源(用于终止处理) private CancellationTokenSource _cts; ILoadResourceService loadResourceService; bool Checking = false; IDisposable loadResourceIdis; string resourceKey; Animation anim; public void CheckResource(List resourceName, bool ReChecking = false) { if ((Checking && !ReChecking) || resourceName == null || resourceName.Count == 0) { return; } Checking = true; loadResourceService = GContext.container.Resolve(); resourceKey = string.Join(",", resourceName); CheckResource(resourceName); } async Task CheckResource(List resourceName) { // 初始化取消令牌(若未初始化) _cts ??= new CancellationTokenSource(); CancellationToken token = _cts.Token; try { gameObject.SetActive(false); bool isReady = await loadResourceService.CheckResourceLoadQueue(resourceKey, resourceName); // 检查取消状态(避免后续逻辑执行) if (token.IsCancellationRequested) return; if (!isReady) { anim = GetComponent(); DisposeEvent(); loadResourceIdis = GContext.OnEvent().Where(_ => _.key == resourceKey).Subscribe(LoadEventResourceEvent); // 取消时自动释放事件订阅 token.Register(() => DisposeEvent()); } else { anim = null; LoadEventResource(true); } } catch (OperationCanceledException) { // 任务被取消,安全退出 Debug.Log("CheckResource operation was canceled."); } catch (Exception ex) { Debug.LogError($"CheckResource encountered an error: {ex.Message}"); } } void LoadEventResourceEvent(LoadEventResourceEvent loadEvent) { Debug.Log($"LoadEventResourceEvent {loadEvent.key} {loadEvent.isSucceeded} "); DisposeEvent(); LoadEventResource(loadEvent.isSucceeded); Checking = loadEvent.isSucceeded; } void DisposeEvent() { loadResourceIdis?.Dispose(); loadResourceIdis = null; } void LoadEventResource(bool succeeded) { if (gameObject == null) { Debug.Log("下载资源回调gameObject 是空"); return; } if (succeeded) { try { if (anim != null) { anim.Play("btn_download_show"); } OnLoadEventResource(); } catch (System.Exception e) { Debug.LogError($"Load Event Resource Exception! == {gameObject.name} \n {e}"); } } else { Debug.LogError($"Load Event Resource Failed! == {gameObject.name}"); } } protected abstract void OnLoadEventResource(); protected virtual void OnDestroy() { CancelAllCheckTasks(); } // 取消所有排队任务(切换场景/销毁时调用) public void CancelAllCheckTasks() { _cts?.Cancel(); _cts?.Dispose(); _cts = null; // 释放事件订阅 DisposeEvent(); } }