using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
namespace YooAsset
{
internal abstract class ProviderBase
{
public enum EStatus
{
None = 0,
CheckBundle,
Loading,
Checking,
Succeed,
Failed,
}
///
/// 资源提供者唯一标识符
///
public string ProviderGUID { private set; get; }
///
/// 所属资源系统
///
public AssetSystemImpl Impl { private set; get; }
///
/// 资源信息
///
public AssetInfo MainAssetInfo { private set; get; }
///
/// 获取的资源对象
///
public UnityEngine.Object AssetObject { protected set; get; }
///
/// 获取的资源对象集合
///
public UnityEngine.Object[] AllAssetObjects { protected set; get; }
///
/// 获取的场景对象
///
public UnityEngine.SceneManagement.Scene SceneObject { protected set; get; }
///
/// 原生文件路径
///
public string RawFilePath { protected set; get; }
///
/// 当前的加载状态
///
public EStatus Status { protected set; get; } = EStatus.None;
///
/// 最近的错误信息
///
public string LastError { protected set; get; } = string.Empty;
///
/// 加载进度
///
public float Progress { protected set; get; } = 0f;
///
/// 引用计数
///
public int RefCount { private set; get; } = 0;
///
/// 是否已经销毁
///
public bool IsDestroyed { private set; get; } = false;
///
/// 是否完毕(成功或失败)
///
public bool IsDone
{
get
{
return Status == EStatus.Succeed || Status == EStatus.Failed;
}
}
protected BundleLoaderBase OwnerBundle { private set; get; }
protected DependAssetBundleGroup DependBundleGroup { private set; get; }
protected bool IsWaitForAsyncComplete { private set; get; } = false;
private readonly List _handles = new List();
public ProviderBase(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo)
{
Impl = impl;
ProviderGUID = providerGUID;
MainAssetInfo = assetInfo;
// 创建资源包加载器
if (impl != null)
{
OwnerBundle = impl.CreateOwnerAssetBundleLoader(assetInfo);
OwnerBundle.Reference();
OwnerBundle.AddProvider(this);
var dependBundles = impl.CreateDependAssetBundleLoaders(assetInfo);
DependBundleGroup = new DependAssetBundleGroup(dependBundles);
DependBundleGroup.Reference();
}
}
///
/// 轮询更新方法
///
public abstract void Update();
///
/// 销毁资源对象
///
public virtual void Destroy()
{
IsDestroyed = true;
// 释放资源包加载器
if (OwnerBundle != null)
{
OwnerBundle.Release();
OwnerBundle = null;
}
if (DependBundleGroup != null)
{
DependBundleGroup.Release();
DependBundleGroup = null;
}
}
///
/// 是否可以销毁
///
public bool CanDestroy()
{
if (IsDone == false)
return false;
return RefCount <= 0;
}
///
/// 是否为场景提供者
///
public bool IsSceneProvider()
{
if (this is BundledSceneProvider || this is DatabaseSceneProvider)
return true;
else
return false;
}
///
/// 创建操作句柄
///
public T CreateHandle() where T : OperationHandleBase
{
// 引用计数增加
RefCount++;
OperationHandleBase handle;
if (typeof(T) == typeof(AssetOperationHandle))
handle = new AssetOperationHandle(this);
else if (typeof(T) == typeof(SceneOperationHandle))
handle = new SceneOperationHandle(this);
else if (typeof(T) == typeof(SubAssetsOperationHandle))
handle = new SubAssetsOperationHandle(this);
else if (typeof(T) == typeof(RawFileOperationHandle))
handle = new RawFileOperationHandle(this);
else
throw new System.NotImplementedException();
_handles.Add(handle);
return handle as T;
}
///
/// 释放操作句柄
///
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 void WaitForAsyncComplete()
{
IsWaitForAsyncComplete = true;
// 注意:主动轮询更新完成同步加载
Update();
// 验证结果
if (IsDone == false)
{
YooLogger.Warning($"WaitForAsyncComplete failed to loading : {MainAssetInfo.AssetPath}");
}
}
///
/// 异步操作任务
///
public Task Task
{
get
{
if (_taskCompletionSource == null)
{
_taskCompletionSource = new TaskCompletionSource