using System.Collections; using System.Collections.Generic; namespace YooAsset { internal abstract class AssetProviderBase { public enum EStatus { None = 0, CheckBundle, Loading, Checking, Success, Fail, } /// /// 资源路径 /// public string AssetPath { private set; get; } /// /// 资源对象的名称 /// public string AssetName { private set; get; } /// /// 资源对象的类型 /// public System.Type AssetType { private set; get; } /// /// 获取的资源对象 /// public UnityEngine.Object AssetObject { protected set; get; } /// /// 获取的资源对象集合 /// public UnityEngine.Object[] AllAssets { protected set; get; } /// /// 获取的场景对象 /// public UnityEngine.SceneManagement.Scene SceneObject { protected set; get; } /// /// 当前的加载状态 /// public EStatus Status { protected set; get; } = EStatus.None; /// /// 引用计数 /// public int RefCount { private set; get; } = 0; /// /// 是否已经销毁 /// public bool IsDestroyed { private set; get; } = false; /// /// 是否完毕(成功或失败) /// public bool IsDone { get { return Status == EStatus.Success || Status == EStatus.Fail; } } /// /// 加载进度 /// public virtual float Progress { get { return 0; } } protected bool IsWaitForAsyncComplete { private set; get; } = false; private readonly List _handles = new List(); public AssetProviderBase(string assetPath, System.Type assetType) { AssetPath = assetPath; AssetName = System.IO.Path.GetFileName(assetPath); AssetType = assetType; } /// /// 轮询更新方法 /// public abstract void Update(); /// /// 销毁资源对象 /// public virtual void Destory() { IsDestroyed = true; } /// /// 是否可以销毁 /// public bool CanDestroy() { if (IsDone == false) return false; return RefCount <= 0; } /// /// 创建操作句柄 /// /// public OperationHandleBase CreateHandle() { // 引用计数增加 RefCount++; OperationHandleBase handle; if (IsSceneProvider()) handle = new SceneOperationHandle(this); else if (IsSubAssetsProvider()) handle = new SubAssetsOperationHandle(this); else handle = new AssetOperationHandle(this); _handles.Add(handle); return handle; } /// /// 释放操作句柄 /// public void ReleaseHandle(OperationHandleBase handle) { if (RefCount <= 0) YooLogger.Warning("Asset provider reference count is already zero. There may be resource leaks !"); if (_handles.Remove(handle) == false) throw new System.Exception("Should never get here !"); // 引用计数减少 RefCount--; } /// /// 是否为场景提供者 /// public bool IsSceneProvider() { if (this is BundledSceneProvider || this is DatabaseSceneProvider) return true; else return false; } /// /// 是否为子资源对象提供者 /// public bool IsSubAssetsProvider() { if (this is BundledSubAssetsProvider || this is DatabaseSubAssetsProvider) return true; else return false; } /// /// 等待异步执行完毕 /// public void WaitForAsyncComplete() { IsWaitForAsyncComplete = true; // 注意:主动轮询更新完成同步加载 Update(); // 验证结果 if (IsDone == false) { YooLogger.Warning($"WaitForAsyncComplete failed to loading : {AssetPath}"); } } /// /// 异步操作任务 /// public System.Threading.Tasks.Task Task { get { var handle = WaitHandle; return System.Threading.Tasks.Task.Factory.StartNew(o => { handle.WaitOne(); return AssetObject as object; }, this); } } // 异步操作相关 private System.Threading.EventWaitHandle _waitHandle; private System.Threading.WaitHandle WaitHandle { get { if (_waitHandle == null) _waitHandle = new System.Threading.EventWaitHandle(false, System.Threading.EventResetMode.ManualReset); _waitHandle.Reset(); return _waitHandle; } } protected void InvokeCompletion() { foreach (var handle in _handles) { handle.InvokeCallback(); } _waitHandle?.Set(); } } }