using XGame.Framework.Asyncs;
using XGame.Framework.Utils;
using UnityEngine;
namespace XGame.Framework.Asset
{
///
/// AssetBundle的加载方式,需要先实现Bundle的Manifest管理
///
internal partial class AssetBundleLoader
{
///
/// 创建从Repository获取Asset的异步
/// Repository没缓存时则返回Null
///
///
///
AssetLoadFromCacheAsync CreateAssetFromCacheAsync(string addressableName)
{
var source = Repository.PopUnusedAsset(addressableName);
if (source != null)
{
var assetAsync = new AssetLoadFromCacheAsync()
{
AddressableName = addressableName,
Source = source,
};
return assetAsync;
}
return null;
}
/////
///// 创建加载Asset的异步
/////
/////
/////
//AssetLoadFromBundleAsync CreateAssetLoadFromBundleAsync(string assetPath)
//{
// var assetAsync = AsyncPool.GetAssetAsync(assetPath) as AssetLoadFromBundleAsync;
// if (assetAsync == null)
// {
// assetAsync = new AssetLoadFromBundleAsync
// {
// Path = assetPath
// };
// //记录当前加载的AssetPath
// LoadingAssets.Add(assetPath);
// assetAsync.On(OnAssetCompleted);
// }
// return assetAsync;
//}
///
/// 创建加载Bundle的异步
///
///
///
IAssetAsync CreateBundleAsync(string bundleName)
{
//var path = FileUtil.GetAssetBundlePath(bundleName);
if (Repository.ContainsBundle(bundleName))
return null;
var assetAsync = AsyncPool.GetAssetAsync(bundleName);
if (assetAsync != null)
return assetAsync;
#if UNITY_EDITOR || !(UNITY_WEBGL || UNITY_WEIXINMINIGAME)
var requestAsync = new AssetBundleCreateRequestAsync
{
Path = FileUtils.GetAssetBundlePath(bundleName),
AddressableName = bundleName,
Offset = GetBundleOffest(bundleName)
};
#else
var requestAsync = new WebRequestAssetBundleAsync
{
Path = FileUtils.GetAssetBundlePath(bundleName),
AddressableName = bundleName,
Offset = GetBundleOffest(bundleName)
};
#endif
requestAsync.On(OnBundleCompleted);
//AsyncPool.AddAsync(requestAsync);
return requestAsync;
}
///
/// AssetBundleCreateRequestAsync的回调监听
///
///
void OnBundleCompleted(IAsync async)
{
if (async is IAssetAsync assetAsync)
{
var bundleName = assetAsync.AddressableName;
var result = assetAsync.GetResult();
var bundleAsset = Repository.GetBundle(bundleName);
if (bundleAsset != null)
{
//bundleAsset.Retain();
AssetsLog.Warn("Bundle load repeated. Name:{0} Last:{1} Next:{2}", bundleName, bundleAsset.Source.GetLongHashCode(), result?.GetLongHashCode());
return;
}
bundleAsset = AssetCreator.Create(bundleName, result) as BundleAsset;
if (bundleAsset != null)
{
Repository.AddBundle(bundleAsset);
}
else
{
AssetsLog.Error("Load bundle failed. Bundle:{0}", bundleName);
}
}
}
///
/// AssetLoadFromBundleAsync的回调监听
///
///
void OnAssetCompleted(IAsync async)
{
if (async is AssetLoadFromBundleAsync assetAsync)
{
int assetHash = assetAsync.AssetHash;
var assetName = assetAsync.AddressableName;
//删除当前加载的AssetPath
//LoadingAssets.Remove(assetPath);
if (assetHash == 0)
{
AssetsLog.Error($"AssetBundle load failed. Asset is null. Name:{assetName}");
return;
}
//记录hash
if (!Repository.RegistAssetHash(assetHash, assetName))
{
//发现重复的Hash记录,不需要再重复记录Bundle的引用计数
//出现重复的原因是异步加载Asset后又使用同步加载了同一个Asset
return;
}
if (TryGetBundleInfo(assetName, out string bundleName, out string[] dependencies))
{
//增加依赖bundle的引用计数
//string bundlePath = FileUtil.GetAssetBundlePath(bundleName);
Repository.RetainBundle(bundleName);
if (dependencies != null)
{
foreach (var dep in dependencies)
{
//var depBundlePath = FileUtil.GetAssetBundlePath(dep);
Repository.RetainBundle(dep);
}
}
}
}
}
///
/// 异步加载scene的回调
///
///
void OnSceneComplete(IAsync async)
{
if (async is SceneLoadAsync sceneAsync)
{
var assetName = sceneAsync.AddressableName;
if (TryGetBundleInfo(assetName, out string bundleName, out string[] dependencies))
{
//sceneBundle在这里添加到Reponsitory
var sceneBundle = Repository.GetBundle(bundleName);
if (sceneBundle != null)
{
AssetsLog.Warn("Bundle load repeated. Name:{0} Last:{1}", bundleName, sceneBundle.Source.GetLongHashCode());
return;
}
//更新引用计数
Repository.RetainBundle(bundleName);
if (dependencies != null)
{
foreach (var dep in dependencies)
{
Repository.RetainBundle(dep);
}
}
}
}
}
AssetBundle GetAssetBundleByName(string bundleName)
{
var bundleAsset = Repository.GetBundle(bundleName);
return bundleAsset?.Source as AssetBundle;
}
}
}