update asset system

编辑器模拟模式增加虚拟资源包
pull/86/head
hevinci 2023-03-24 18:33:36 +08:00
parent c60cc1e84f
commit de43495af5
14 changed files with 286 additions and 132 deletions

View File

@ -69,7 +69,6 @@ namespace YooAsset
// 更新资源提供者
// 注意:循环更新的时候,可能会扩展列表
// 注意:不能限制场景对象的加载
_isUnloadSafe = false;
for (int i = 0; i < _providerList.Count; i++)
{
@ -123,27 +122,13 @@ namespace YooAsset
}
}
private void UnloadUnusedAssetsInternal()
{
if (_simulationOnEditor)
{
for (int i = _providerList.Count - 1; i >= 0; i--)
{
var provider = _providerList[i];
if (provider.CanDestroy())
{
provider.Destroy();
_providerList.RemoveAt(i);
_providerDic.Remove(provider.ProviderGUID);
}
}
}
else
{
for (int i = _loaderList.Count - 1; i >= 0; i--)
{
BundleLoaderBase loader = _loaderList[i];
loader.TryDestroyAllProviders();
}
for (int i = _loaderList.Count - 1; i >= 0; i--)
{
BundleLoaderBase loader = _loaderList[i];
@ -156,7 +141,6 @@ namespace YooAsset
}
}
}
}
/// <summary>
/// 强制回收所有资源
@ -392,6 +376,12 @@ namespace YooAsset
return loader;
// 新增下载需求
if (_simulationOnEditor)
{
loader = new VirtualBundleFileLoader(this, bundleInfo);
}
else
{
#if UNITY_WEBGL
if (bundleInfo.Bundle.IsRawFile)
loader = new RawBundleWebLoader(this, bundleInfo);
@ -403,6 +393,7 @@ namespace YooAsset
else
loader = new AssetBundleFileLoader(this, bundleInfo);
#endif
}
_loaderList.Add(loader);
_loaderDic.Add(bundleName, loader);
@ -437,13 +428,8 @@ namespace YooAsset
providerInfo.RefCount = provider.RefCount;
providerInfo.Status = provider.Status.ToString();
providerInfo.DependBundleInfos = new List<DebugBundleInfo>();
provider.GetBundleDebugInfos(providerInfo.DependBundleInfos);
result.Add(providerInfo);
if (provider is BundledProvider)
{
BundledProvider temp = provider as BundledProvider;
temp.GetBundleDebugInfos(providerInfo.DependBundleInfos);
}
}
return result;
}

View File

@ -0,0 +1,82 @@

namespace YooAsset
{
internal class VirtualBundleFileLoader : BundleLoaderBase
{
private enum ESteps
{
None,
CheckFile,
Done,
}
private ESteps _steps = ESteps.None;
public VirtualBundleFileLoader(AssetSystemImpl impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
/// <summary>
/// 轮询更新
/// </summary>
public override void Update()
{
if (_steps == ESteps.Done)
return;
if (_steps == ESteps.None)
{
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromEditor)
{
_steps = ESteps.CheckFile;
}
else
{
throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
}
}
// 1. 检测结果
if (_steps == ESteps.CheckFile)
{
// 设置下载进度
DownloadProgress = 1f;
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
_steps = ESteps.Done;
Status = EStatus.Succeed;
}
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public override void WaitForAsyncComplete()
{
int frame = 1000;
while (true)
{
// 保险机制
// 注意:如果需要从远端下载资源,可能会触发保险机制!
frame--;
if (frame == 0)
{
if (IsDone() == false)
{
Status = EStatus.Failed;
LastError = $"WaitForAsyncComplete failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !";
YooLogger.Error(LastError);
}
break;
}
// 驱动流程
Update();
// 完成后退出
if (IsDone())
break;
}
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 4eacb00a7e3873740b599112dfcf0123
guid: 7b9023a940b496549894d9d8872219fb
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -4,7 +4,7 @@ using UnityEngine;
namespace YooAsset
{
internal sealed class BundledAssetProvider : BundledProvider
internal sealed class BundledAssetProvider : ProviderBase
{
private AssetBundleRequest _cacheRequest;

View File

@ -1,69 +0,0 @@
using System.Collections;
using System.Collections.Generic;
namespace YooAsset
{
internal abstract class BundledProvider : ProviderBase
{
protected BundleLoaderBase OwnerBundle { private set; get; }
protected DependAssetBundleGroup DependBundleGroup { private set; get; }
public BundledProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
{
OwnerBundle = impl.CreateOwnerAssetBundleLoader(assetInfo);
OwnerBundle.Reference();
OwnerBundle.AddProvider(this);
var dependBundles = impl.CreateDependAssetBundleLoaders(assetInfo);
DependBundleGroup = new DependAssetBundleGroup(dependBundles);
DependBundleGroup.Reference();
}
public override void Destroy()
{
base.Destroy();
// 释放资源包
if (OwnerBundle != null)
{
OwnerBundle.Release();
OwnerBundle = null;
}
if (DependBundleGroup != null)
{
DependBundleGroup.Release();
DependBundleGroup = null;
}
}
/// <summary>
/// 获取下载报告
/// </summary>
public override DownloadReport GetDownloadReport()
{
DownloadReport result = new DownloadReport();
result.TotalSize = (ulong)OwnerBundle.MainBundleInfo.Bundle.FileSize;
result.DownloadedBytes = OwnerBundle.DownloadedBytes;
foreach (var dependBundle in DependBundleGroup.DependBundles)
{
result.TotalSize += (ulong)dependBundle.MainBundleInfo.Bundle.FileSize;
result.DownloadedBytes += dependBundle.DownloadedBytes;
}
result.Progress = (float)result.DownloadedBytes / result.TotalSize;
return result;
}
/// <summary>
/// 获取资源包的调试信息列表
/// </summary>
internal void GetBundleDebugInfos(List<DebugBundleInfo> output)
{
var bundleInfo = new DebugBundleInfo();
bundleInfo.BundleName = OwnerBundle.MainBundleInfo.Bundle.BundleName;
bundleInfo.RefCount = OwnerBundle.RefCount;
bundleInfo.Status = OwnerBundle.Status.ToString();
output.Add(bundleInfo);
DependBundleGroup.GetBundleDebugInfos(output);
}
}
}

View File

@ -1,7 +1,7 @@

namespace YooAsset
{
internal class BundledRawFileProvider : BundledProvider
internal class BundledRawFileProvider : ProviderBase
{
public BundledRawFileProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
{
@ -18,6 +18,7 @@ namespace YooAsset
Status = EStatus.CheckBundle;
}
// 1. 检测资源包
if (Status == EStatus.CheckBundle)
{
if (IsWaitForAsyncComplete)
@ -39,6 +40,7 @@ namespace YooAsset
Status = EStatus.Checking;
}
// 2. 检测加载结果
if (Status == EStatus.Checking)
{
RawFilePath = OwnerBundle.FileLoadPath;

View File

@ -6,7 +6,7 @@ using UnityEngine.SceneManagement;
namespace YooAsset
{
internal sealed class BundledSceneProvider : BundledProvider
internal sealed class BundledSceneProvider : ProviderBase
{
public readonly LoadSceneMode SceneMode;
private readonly string _sceneName;

View File

@ -4,7 +4,7 @@ using UnityEngine;
namespace YooAsset
{
internal sealed class BundledSubAssetsProvider : BundledProvider
internal sealed class BundledSubAssetsProvider : ProviderBase
{
private AssetBundleRequest _cacheRequest;

View File

@ -28,14 +28,36 @@ namespace YooAsset
return;
}
Status = EStatus.Loading;
Status = EStatus.CheckBundle;
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 1. 加载资源对象
// 1. 检测资源包
if (Status == EStatus.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
Status = EStatus.Failed;
LastError = OwnerBundle.LastError;
InvokeCompletion();
return;
}
Status = EStatus.Loading;
}
// 2. 加载资源对象
if (Status == EStatus.Loading)
{
if (MainAssetInfo.AssetType == null)
@ -45,7 +67,7 @@ namespace YooAsset
Status = EStatus.Checking;
}
// 2. 检测加载结果
// 3. 检测加载结果
if (Status == EStatus.Checking)
{
Status = AssetObject == null ? EStatus.Failed : EStatus.Succeed;

View File

@ -25,13 +25,36 @@ namespace YooAsset
return;
}
Status = EStatus.Checking;
Status = EStatus.CheckBundle;
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 1. 检测资源包
if (Status == EStatus.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
Status = EStatus.Failed;
LastError = OwnerBundle.LastError;
InvokeCompletion();
return;
}
Status = EStatus.Checking;
}
// 2. 检测加载结果
if (Status == EStatus.Checking)
{
RawFilePath = MainAssetInfo.AssetPath;

View File

@ -24,10 +24,32 @@ namespace YooAsset
if (Status == EStatus.None)
{
Status = EStatus.CheckBundle;
}
// 1. 检测资源包
if (Status == EStatus.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
Status = EStatus.Failed;
LastError = OwnerBundle.LastError;
InvokeCompletion();
return;
}
Status = EStatus.Loading;
}
// 1. 加载资源对象
// 2. 加载资源对象
if (Status == EStatus.Loading)
{
LoadSceneParameters loadSceneParameters = new LoadSceneParameters();
@ -49,7 +71,7 @@ namespace YooAsset
}
}
// 2. 检测加载结果
// 3. 检测加载结果
if (Status == EStatus.Checking)
{
Progress = _asyncOp.progress;

View File

@ -28,14 +28,36 @@ namespace YooAsset
return;
}
Status = EStatus.Loading;
Status = EStatus.CheckBundle;
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 1. 加载资源对象
// 1. 检测资源包
if (Status == EStatus.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
Status = EStatus.Failed;
LastError = OwnerBundle.LastError;
InvokeCompletion();
return;
}
Status = EStatus.Loading;
}
// 2. 加载资源对象
if (Status == EStatus.Loading)
{
if (MainAssetInfo.AssetType == null)
@ -56,7 +78,7 @@ namespace YooAsset
Status = EStatus.Checking;
}
// 2. 检测加载结果
// 3. 检测加载结果
if (Status == EStatus.Checking)
{
Status = AllAssetObjects == null ? EStatus.Failed : EStatus.Succeed;

View File

@ -90,6 +90,8 @@ namespace YooAsset
}
protected BundleLoaderBase OwnerBundle { private set; get; }
protected DependAssetBundleGroup DependBundleGroup { private set; get; }
protected bool IsWaitForAsyncComplete { private set; get; } = false;
private readonly List<OperationHandleBase> _handles = new List<OperationHandleBase>();
@ -99,6 +101,15 @@ namespace YooAsset
Impl = impl;
ProviderGUID = providerGUID;
MainAssetInfo = assetInfo;
// 创建资源包加载器
OwnerBundle = impl.CreateOwnerAssetBundleLoader(assetInfo);
OwnerBundle.Reference();
OwnerBundle.AddProvider(this);
var dependBundles = impl.CreateDependAssetBundleLoaders(assetInfo);
DependBundleGroup = new DependAssetBundleGroup(dependBundles);
DependBundleGroup.Reference();
}
/// <summary>
@ -112,14 +123,18 @@ namespace YooAsset
public virtual void Destroy()
{
IsDestroyed = true;
}
/// <summary>
/// 获取下载进度
/// </summary>
public virtual DownloadReport GetDownloadReport()
// 释放资源包加载器
if (OwnerBundle != null)
{
return DownloadReport.CreateDefaultReport();
OwnerBundle.Release();
OwnerBundle = null;
}
if (DependBundleGroup != null)
{
DependBundleGroup.Release();
DependBundleGroup = null;
}
}
/// <summary>
@ -292,6 +307,37 @@ namespace YooAsset
_watch = null;
}
}
/// <summary>
/// 获取下载报告
/// </summary>
internal DownloadReport GetDownloadReport()
{
DownloadReport result = new DownloadReport();
result.TotalSize = (ulong)OwnerBundle.MainBundleInfo.Bundle.FileSize;
result.DownloadedBytes = OwnerBundle.DownloadedBytes;
foreach (var dependBundle in DependBundleGroup.DependBundles)
{
result.TotalSize += (ulong)dependBundle.MainBundleInfo.Bundle.FileSize;
result.DownloadedBytes += dependBundle.DownloadedBytes;
}
result.Progress = (float)result.DownloadedBytes / result.TotalSize;
return result;
}
/// <summary>
/// 获取资源包的调试信息列表
/// </summary>
internal void GetBundleDebugInfos(List<DebugBundleInfo> output)
{
var bundleInfo = new DebugBundleInfo();
bundleInfo.BundleName = OwnerBundle.MainBundleInfo.Bundle.BundleName;
bundleInfo.RefCount = OwnerBundle.RefCount;
bundleInfo.Status = OwnerBundle.Status.ToString();
output.Add(bundleInfo);
DependBundleGroup.GetBundleDebugInfos(output);
}
#endregion
}
}

View File

@ -80,6 +80,14 @@ namespace YooAsset
#endregion
#region IBundleServices接口
private BundleInfo CreateBundleInfo(PackageBundle packageBundle, AssetInfo assetInfo)
{
if (packageBundle == null)
throw new Exception("Should never get here !");
BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromEditor, assetInfo.AssetPath);
return bundleInfo;
}
BundleInfo IBundleServices.GetBundleInfo(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
@ -87,16 +95,26 @@ namespace YooAsset
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromEditor, assetInfo.AssetPath);
return bundleInfo;
return CreateBundleInfo(packageBundle, assetInfo);
}
BundleInfo[] IBundleServices.GetAllDependBundleInfos(AssetInfo assetInfo)
{
throw new NotImplementedException();
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath);
List<BundleInfo> result = new List<BundleInfo>(depends.Length);
foreach (var packageBundle in depends)
{
BundleInfo bundleInfo = CreateBundleInfo(packageBundle, assetInfo);
result.Add(bundleInfo);
}
return result.ToArray();
}
string IBundleServices.GetBundleName(int bundleID)
{
throw new NotImplementedException();
return _activeManifest.GetBundleName(bundleID);
}
bool IBundleServices.IsServicesValid()
{