mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-26 10:40:14 +00:00
435 lines
16 KiB
C#
435 lines
16 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
namespace YooAsset
|
|
{
|
|
internal class FileSystemHost
|
|
{
|
|
public readonly string PackageName;
|
|
public readonly List<IFileSystem> FileSystems = new List<IFileSystem>(10);
|
|
|
|
/// <summary>
|
|
/// 当前激活的清单
|
|
/// </summary>
|
|
public PackageManifest ActiveManifest { set; get; }
|
|
|
|
|
|
public FileSystemHost(string packageName)
|
|
{
|
|
PackageName = packageName;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 异步初始化
|
|
/// </summary>
|
|
public InitializeFileSystemOperation InitializeAsync(FileSystemParameters fileSystemParameter)
|
|
{
|
|
var fileSystemParamList = new List<FileSystemParameters>();
|
|
if (fileSystemParameter != null)
|
|
fileSystemParamList.Add(fileSystemParameter);
|
|
return InitializeAsync(fileSystemParamList);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 异步初始化
|
|
/// </summary>
|
|
public InitializeFileSystemOperation InitializeAsync(FileSystemParameters fileSystemParameterA, FileSystemParameters fileSystemParameterB)
|
|
{
|
|
var fileSystemParamList = new List<FileSystemParameters>();
|
|
if (fileSystemParameterA != null)
|
|
fileSystemParamList.Add(fileSystemParameterA);
|
|
if (fileSystemParameterB != null)
|
|
fileSystemParamList.Add(fileSystemParameterB);
|
|
return InitializeAsync(fileSystemParamList);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 异步初始化
|
|
/// </summary>
|
|
public InitializeFileSystemOperation InitializeAsync(List<FileSystemParameters> fileSystemParameterList)
|
|
{
|
|
var operation = new InitializeFileSystemOperation(this, fileSystemParameterList);
|
|
return operation;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 销毁文件系统
|
|
/// </summary>
|
|
public void Destroy()
|
|
{
|
|
foreach (var fileSystem in FileSystems)
|
|
{
|
|
fileSystem.OnDestroy();
|
|
}
|
|
FileSystems.Clear();
|
|
}
|
|
|
|
#region 资源包相关
|
|
private BundleInfo CreateBundleInfo(PackageBundle packageBundle)
|
|
{
|
|
if (packageBundle == null)
|
|
throw new YooInternalException();
|
|
|
|
var fileSystem = GetBelongFileSystem(packageBundle);
|
|
if (fileSystem != null)
|
|
{
|
|
BundleInfo bundleInfo = new BundleInfo(fileSystem, packageBundle);
|
|
return bundleInfo;
|
|
}
|
|
|
|
throw new YooFileSystemException($"Can not found belong file system : {packageBundle.BundleName}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取主资源包信息
|
|
/// </summary>
|
|
public BundleInfo GetMainBundleInfo(AssetInfo assetInfo)
|
|
{
|
|
if (assetInfo == null || assetInfo.IsInvalid)
|
|
throw new YooInternalException();
|
|
|
|
// 注意:如果清单里未找到资源包会抛出异常!
|
|
var packageBundle = ActiveManifest.GetMainPackageBundle(assetInfo.Asset);
|
|
return CreateBundleInfo(packageBundle);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取主资源包名称
|
|
/// </summary>
|
|
public string GetMainBundleName(int bundleID)
|
|
{
|
|
// 注意:如果清单里未找到资源包会抛出异常!
|
|
var packageBundle = ActiveManifest.GetMainPackageBundle(bundleID);
|
|
return packageBundle.BundleName;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取依赖的资源包信息集合
|
|
/// </summary>
|
|
public List<BundleInfo> GetDependBundleInfos(AssetInfo assetInfo)
|
|
{
|
|
if (assetInfo == null || assetInfo.IsInvalid)
|
|
throw new YooInternalException();
|
|
|
|
// 注意:如果清单里未找到资源包会抛出异常!
|
|
List<PackageBundle> depends;
|
|
if (assetInfo.LoadMethod == AssetInfo.ELoadMethod.LoadAllAssets)
|
|
{
|
|
var mainBundle = ActiveManifest.GetMainPackageBundle(assetInfo.Asset);
|
|
depends = ActiveManifest.GetBundleAllDependencies(mainBundle);
|
|
}
|
|
else
|
|
{
|
|
depends = ActiveManifest.GetAssetAllDependencies(assetInfo.Asset);
|
|
}
|
|
|
|
List<BundleInfo> result = new List<BundleInfo>(depends.Count);
|
|
foreach (var packageBundle in depends)
|
|
{
|
|
BundleInfo bundleInfo = CreateBundleInfo(packageBundle);
|
|
result.Add(bundleInfo);
|
|
}
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
#region 下载器相关
|
|
public ResourceDownloaderOperation CreateResourceDownloader(ResourceDownloaderOptions options)
|
|
{
|
|
List<BundleInfo> downloadList;
|
|
if (options.Tags == null)
|
|
downloadList = GetDownloadListByAll(ActiveManifest);
|
|
else
|
|
downloadList = GetDownloadListByTags(ActiveManifest, options.Tags);
|
|
|
|
var operation = new ResourceDownloaderOperation(PackageName, downloadList, options.MaximumConcurrency, options.FailedTryAgain);
|
|
return operation;
|
|
}
|
|
public ResourceDownloaderOperation CreateResourceDownloader(BundleDownloaderOptions options)
|
|
{
|
|
List<BundleInfo> downloadList;
|
|
if (options.AssetInfos == null)
|
|
downloadList = GetDownloadListByAll(ActiveManifest);
|
|
else
|
|
downloadList = GetDownloadListByAssetInfos(ActiveManifest, options.AssetInfos, options.DownloadBundleDependencies);
|
|
|
|
var operation = new ResourceDownloaderOperation(PackageName, downloadList, options.MaximumConcurrency, options.FailedTryAgain);
|
|
return operation;
|
|
}
|
|
public ResourceUnpackerOperation CreateResourceUnpacker(ResourceUnpackerOptions options)
|
|
{
|
|
List<BundleInfo> unpcakList;
|
|
if (options.Tags == null)
|
|
unpcakList = GetUnpackListByAll(ActiveManifest);
|
|
else
|
|
unpcakList = GetUnpackListByTags(ActiveManifest, options.Tags);
|
|
|
|
var operation = new ResourceUnpackerOperation(PackageName, unpcakList, options.MaximumConcurrency, options.FailedTryAgain);
|
|
return operation;
|
|
}
|
|
public ResourceImporterOperation CreateResourceImporter(BundleImporterOptions options)
|
|
{
|
|
List<BundleInfo> importerList = GetImporterListByBundleInfos(ActiveManifest, options.BundleInfos);
|
|
var operation = new ResourceImporterOperation(PackageName, importerList, options.MaximumConcurrency, options.FailedTryAgain);
|
|
return operation;
|
|
}
|
|
|
|
internal List<BundleInfo> GetDownloadListByAll(PackageManifest manifest)
|
|
{
|
|
if (manifest == null)
|
|
return new List<BundleInfo>();
|
|
|
|
List<BundleInfo> result = new List<BundleInfo>(1000);
|
|
foreach (var packageBundle in manifest.BundleList)
|
|
{
|
|
var fileSystem = GetBelongFileSystem(packageBundle);
|
|
if (fileSystem == null)
|
|
continue;
|
|
|
|
if (fileSystem.NeedDownload(packageBundle))
|
|
{
|
|
var bundleInfo = new BundleInfo(fileSystem, packageBundle);
|
|
result.Add(bundleInfo);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
internal List<BundleInfo> GetDownloadListByTags(PackageManifest manifest, string[] tags)
|
|
{
|
|
if (manifest == null)
|
|
return new List<BundleInfo>();
|
|
|
|
List<BundleInfo> result = new List<BundleInfo>(1000);
|
|
foreach (var packageBundle in manifest.BundleList)
|
|
{
|
|
var fileSystem = GetBelongFileSystem(packageBundle);
|
|
if (fileSystem == null)
|
|
continue;
|
|
|
|
if (fileSystem.NeedDownload(packageBundle))
|
|
{
|
|
// 如果未带任何标记,则统一下载
|
|
if (packageBundle.HasAnyTags() == false)
|
|
{
|
|
var bundleInfo = new BundleInfo(fileSystem, packageBundle);
|
|
result.Add(bundleInfo);
|
|
}
|
|
else
|
|
{
|
|
// 查询DLC资源
|
|
if (packageBundle.HasTag(tags))
|
|
{
|
|
var bundleInfo = new BundleInfo(fileSystem, packageBundle);
|
|
result.Add(bundleInfo);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
internal List<BundleInfo> GetDownloadListByAssetInfos(PackageManifest manifest, AssetInfo[] assetInfos, bool recursiveDownload)
|
|
{
|
|
if (manifest == null)
|
|
return new List<BundleInfo>();
|
|
|
|
// 获取资源对象的资源包和所有依赖资源包
|
|
HashSet<string> checkSet = new HashSet<string>();
|
|
List<PackageBundle> checkList = new List<PackageBundle>(assetInfos.Length);
|
|
foreach (var assetInfo in assetInfos)
|
|
{
|
|
if (assetInfo.IsInvalid)
|
|
{
|
|
YooLogger.Warning(assetInfo.Error);
|
|
continue;
|
|
}
|
|
|
|
// 注意:如果清单里未找到资源包会抛出异常!
|
|
PackageBundle mainBundle = manifest.GetMainPackageBundle(assetInfo.Asset);
|
|
if (checkSet.Contains(mainBundle.BundleGUID) == false)
|
|
{
|
|
checkSet.Add(mainBundle.BundleGUID);
|
|
checkList.Add(mainBundle);
|
|
}
|
|
|
|
// 注意:如果清单里未找到资源包会抛出异常!
|
|
List<PackageBundle> mainDependBundles = manifest.GetAssetAllDependencies(assetInfo.Asset);
|
|
foreach (var dependBundle in mainDependBundles)
|
|
{
|
|
if (checkSet.Contains(dependBundle.BundleGUID) == false)
|
|
{
|
|
checkSet.Add(dependBundle.BundleGUID);
|
|
checkList.Add(dependBundle);
|
|
}
|
|
}
|
|
|
|
// 下载主资源包内所有资源对象依赖的资源包
|
|
if (recursiveDownload)
|
|
{
|
|
foreach (var otherMainAsset in mainBundle.IncludeMainAssets)
|
|
{
|
|
var otherMainBundle = manifest.GetMainPackageBundle(otherMainAsset.BundleID);
|
|
if (checkSet.Contains(otherMainBundle.BundleGUID) == false)
|
|
{
|
|
checkSet.Add(otherMainBundle.BundleGUID);
|
|
checkList.Add(otherMainBundle);
|
|
}
|
|
|
|
List<PackageBundle> otherDependBundles = manifest.GetAssetAllDependencies(otherMainAsset);
|
|
foreach (var dependBundle in otherDependBundles)
|
|
{
|
|
if (checkSet.Contains(dependBundle.BundleGUID) == false)
|
|
{
|
|
checkSet.Add(dependBundle.BundleGUID);
|
|
checkList.Add(dependBundle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
List<BundleInfo> result = new List<BundleInfo>(1000);
|
|
foreach (var packageBundle in checkList)
|
|
{
|
|
var fileSystem = GetBelongFileSystem(packageBundle);
|
|
if (fileSystem == null)
|
|
continue;
|
|
|
|
if (fileSystem.NeedDownload(packageBundle))
|
|
{
|
|
var bundleInfo = new BundleInfo(fileSystem, packageBundle);
|
|
result.Add(bundleInfo);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
internal List<BundleInfo> GetUnpackListByAll(PackageManifest manifest)
|
|
{
|
|
if (manifest == null)
|
|
return new List<BundleInfo>();
|
|
|
|
List<BundleInfo> result = new List<BundleInfo>(1000);
|
|
foreach (var packageBundle in manifest.BundleList)
|
|
{
|
|
var fileSystem = GetBelongFileSystem(packageBundle);
|
|
if (fileSystem == null)
|
|
continue;
|
|
|
|
if (fileSystem.NeedUnpack(packageBundle))
|
|
{
|
|
var bundleInfo = new BundleInfo(fileSystem, packageBundle);
|
|
result.Add(bundleInfo);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
internal List<BundleInfo> GetUnpackListByTags(PackageManifest manifest, string[] tags)
|
|
{
|
|
if (manifest == null)
|
|
return new List<BundleInfo>();
|
|
|
|
List<BundleInfo> result = new List<BundleInfo>(1000);
|
|
foreach (var packageBundle in manifest.BundleList)
|
|
{
|
|
var fileSystem = GetBelongFileSystem(packageBundle);
|
|
if (fileSystem == null)
|
|
continue;
|
|
|
|
if (fileSystem.NeedUnpack(packageBundle))
|
|
{
|
|
if (packageBundle.HasTag(tags))
|
|
{
|
|
var bundleInfo = new BundleInfo(fileSystem, packageBundle);
|
|
result.Add(bundleInfo);
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
internal List<BundleInfo> GetImporterListByBundleInfos(PackageManifest manifest, ImportBundleInfo[] fileInfos)
|
|
{
|
|
if (manifest == null)
|
|
return new List<BundleInfo>();
|
|
|
|
List<BundleInfo> result = new List<BundleInfo>();
|
|
foreach (var fileInfo in fileInfos)
|
|
{
|
|
string filePath = fileInfo.FilePath;
|
|
if (string.IsNullOrEmpty(filePath))
|
|
continue;
|
|
|
|
PackageBundle packageBundle = null;
|
|
if (string.IsNullOrEmpty(fileInfo.BundleName) == false)
|
|
{
|
|
if (manifest.TryGetPackageBundleByBundleName(fileInfo.BundleName, out packageBundle) == false)
|
|
{
|
|
YooLogger.Warning($"Not found package bundle, bundle name : {fileInfo.BundleName}");
|
|
continue;
|
|
}
|
|
}
|
|
else if (string.IsNullOrEmpty(fileInfo.BundleGUID) == false)
|
|
{
|
|
if (manifest.TryGetPackageBundleByBundleGUID(fileInfo.BundleGUID, out packageBundle) == false)
|
|
{
|
|
YooLogger.Warning($"Not found package bundle, bundle guid : {fileInfo.BundleGUID}");
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
string fileName = System.IO.Path.GetFileName(filePath);
|
|
if (manifest.TryGetPackageBundleByFileName(fileName, out packageBundle) == false)
|
|
{
|
|
YooLogger.Warning($"Not found package bundle, file name : {fileName}");
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (packageBundle != null)
|
|
{
|
|
var fileSystem = GetBelongFileSystem(packageBundle);
|
|
if (fileSystem == null)
|
|
continue;
|
|
|
|
if (fileSystem.NeedImport(packageBundle))
|
|
{
|
|
var bundleInfo = new BundleInfo(fileSystem, packageBundle, filePath);
|
|
result.Add(bundleInfo);
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// 获取主文件系统
|
|
/// 说明:文件系统列表里,最后一个属于主文件系统
|
|
/// </summary>
|
|
public IFileSystem GetMainFileSystem()
|
|
{
|
|
int count = FileSystems.Count;
|
|
if (count == 0)
|
|
return null;
|
|
return FileSystems[count - 1];
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取资源包所属文件系统
|
|
/// </summary>
|
|
public IFileSystem GetBelongFileSystem(PackageBundle packageBundle)
|
|
{
|
|
for (int i = 0; i < FileSystems.Count; i++)
|
|
{
|
|
IFileSystem fileSystem = FileSystems[i];
|
|
if (fileSystem.Belong(packageBundle))
|
|
{
|
|
return fileSystem;
|
|
}
|
|
}
|
|
|
|
YooLogger.Error($"Can not found belong file system : {packageBundle.BundleName}");
|
|
return null;
|
|
}
|
|
}
|
|
} |