style : Code text indent format

pull/229/head
hevinci 2023-12-21 19:10:46 +08:00
parent 5c1d316d67
commit 544832c46a
117 changed files with 14101 additions and 14103 deletions

View File

@ -3,34 +3,34 @@ using System.IO;
namespace YooAsset
{
internal class CacheFileInfo
{
private static readonly BufferWriter SharedBuffer = new BufferWriter(1024);
internal class CacheFileInfo
{
private static readonly BufferWriter SharedBuffer = new BufferWriter(1024);
/// <summary>
/// 写入资源包信息
/// </summary>
public static void WriteInfoToFile(string filePath, string dataFileCRC, long dataFileSize)
{
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read))
{
SharedBuffer.Clear();
SharedBuffer.WriteUTF8(dataFileCRC);
SharedBuffer.WriteInt64(dataFileSize);
SharedBuffer.WriteToStream(fs);
fs.Flush();
}
}
/// <summary>
/// 写入资源包信息
/// </summary>
public static void WriteInfoToFile(string filePath, string dataFileCRC, long dataFileSize)
{
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read))
{
SharedBuffer.Clear();
SharedBuffer.WriteUTF8(dataFileCRC);
SharedBuffer.WriteInt64(dataFileSize);
SharedBuffer.WriteToStream(fs);
fs.Flush();
}
}
/// <summary>
/// 读取资源包信息
/// </summary>
public static void ReadInfoFromFile(string filePath, out string dataFileCRC, out long dataFileSize)
{
byte[] binaryData = FileUtility.ReadAllBytes(filePath);
BufferReader buffer = new BufferReader(binaryData);
dataFileCRC = buffer.ReadUTF8();
dataFileSize = buffer.ReadInt64();
}
}
/// <summary>
/// 读取资源包信息
/// </summary>
public static void ReadInfoFromFile(string filePath, out string dataFileCRC, out long dataFileSize)
{
byte[] binaryData = FileUtility.ReadAllBytes(filePath);
BufferReader buffer = new BufferReader(binaryData);
dataFileCRC = buffer.ReadUTF8();
dataFileSize = buffer.ReadInt64();
}
}
}

View File

@ -6,98 +6,98 @@ using System.Diagnostics;
namespace YooAsset
{
internal static class CacheHelper
{
/// <summary>
/// 禁用Unity缓存系统在WebGL平台
/// </summary>
public static bool DisableUnityCacheOnWebGL = false;
internal static class CacheHelper
{
/// <summary>
/// 禁用Unity缓存系统在WebGL平台
/// </summary>
public static bool DisableUnityCacheOnWebGL = false;
/// <summary>
/// 验证缓存文件(子线程内操作)
/// </summary>
public static EVerifyResult VerifyingCacheFile(VerifyCacheFileElement element, EVerifyLevel verifyLevel)
{
try
{
if (verifyLevel == EVerifyLevel.Low)
{
if (File.Exists(element.InfoFilePath) == false)
return EVerifyResult.InfoFileNotExisted;
if (File.Exists(element.DataFilePath) == false)
return EVerifyResult.DataFileNotExisted;
return EVerifyResult.Succeed;
}
else
{
if (File.Exists(element.InfoFilePath) == false)
return EVerifyResult.InfoFileNotExisted;
/// <summary>
/// 验证缓存文件(子线程内操作)
/// </summary>
public static EVerifyResult VerifyingCacheFile(VerifyCacheFileElement element, EVerifyLevel verifyLevel)
{
try
{
if (verifyLevel == EVerifyLevel.Low)
{
if (File.Exists(element.InfoFilePath) == false)
return EVerifyResult.InfoFileNotExisted;
if (File.Exists(element.DataFilePath) == false)
return EVerifyResult.DataFileNotExisted;
return EVerifyResult.Succeed;
}
else
{
if (File.Exists(element.InfoFilePath) == false)
return EVerifyResult.InfoFileNotExisted;
// 解析信息文件获取验证数据
CacheFileInfo.ReadInfoFromFile(element.InfoFilePath, out element.DataFileCRC, out element.DataFileSize);
}
}
catch (Exception)
{
return EVerifyResult.Exception;
}
// 解析信息文件获取验证数据
CacheFileInfo.ReadInfoFromFile(element.InfoFilePath, out element.DataFileCRC, out element.DataFileSize);
}
}
catch (Exception)
{
return EVerifyResult.Exception;
}
return VerifyingInternal(element.DataFilePath, element.DataFileSize, element.DataFileCRC, verifyLevel);
}
return VerifyingInternal(element.DataFilePath, element.DataFileSize, element.DataFileCRC, verifyLevel);
}
/// <summary>
/// 验证下载文件(子线程内操作)
/// </summary>
public static EVerifyResult VerifyingTempFile(VerifyTempFileElement element)
{
return VerifyingInternal(element.TempDataFilePath, element.FileSize, element.FileCRC, EVerifyLevel.High);
}
/// <summary>
/// 验证下载文件(子线程内操作)
/// </summary>
public static EVerifyResult VerifyingTempFile(VerifyTempFileElement element)
{
return VerifyingInternal(element.TempDataFilePath, element.FileSize, element.FileCRC, EVerifyLevel.High);
}
/// <summary>
/// 验证记录文件(主线程内操作)
/// </summary>
public static EVerifyResult VerifyingRecordFile(CacheManager cache, string cacheGUID)
{
var wrapper = cache.TryGetWrapper(cacheGUID);
if (wrapper == null)
return EVerifyResult.CacheNotFound;
/// <summary>
/// 验证记录文件(主线程内操作)
/// </summary>
public static EVerifyResult VerifyingRecordFile(CacheManager cache, string cacheGUID)
{
var wrapper = cache.TryGetWrapper(cacheGUID);
if (wrapper == null)
return EVerifyResult.CacheNotFound;
EVerifyResult result = VerifyingInternal(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EVerifyLevel.High);
return result;
}
EVerifyResult result = VerifyingInternal(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EVerifyLevel.High);
return result;
}
private static EVerifyResult VerifyingInternal(string filePath, long fileSize, string fileCRC, EVerifyLevel verifyLevel)
{
try
{
if (File.Exists(filePath) == false)
return EVerifyResult.DataFileNotExisted;
private static EVerifyResult VerifyingInternal(string filePath, long fileSize, string fileCRC, EVerifyLevel verifyLevel)
{
try
{
if (File.Exists(filePath) == false)
return EVerifyResult.DataFileNotExisted;
// 先验证文件大小
long size = FileUtility.GetFileSize(filePath);
if (size < fileSize)
return EVerifyResult.FileNotComplete;
else if (size > fileSize)
return EVerifyResult.FileOverflow;
// 先验证文件大小
long size = FileUtility.GetFileSize(filePath);
if (size < fileSize)
return EVerifyResult.FileNotComplete;
else if (size > fileSize)
return EVerifyResult.FileOverflow;
// 再验证文件CRC
if (verifyLevel == EVerifyLevel.High)
{
string crc = HashUtility.FileCRC32(filePath);
if (crc == fileCRC)
return EVerifyResult.Succeed;
else
return EVerifyResult.FileCrcError;
}
else
{
return EVerifyResult.Succeed;
}
}
catch (Exception)
{
return EVerifyResult.Exception;
}
}
}
// 再验证文件CRC
if (verifyLevel == EVerifyLevel.High)
{
string crc = HashUtility.FileCRC32(filePath);
if (crc == fileCRC)
return EVerifyResult.Succeed;
else
return EVerifyResult.FileCrcError;
}
else
{
return EVerifyResult.Succeed;
}
}
catch (Exception)
{
return EVerifyResult.Exception;
}
}
}
}

View File

@ -5,132 +5,132 @@ using System.Collections.Generic;
namespace YooAsset
{
internal class CacheManager
{
internal class RecordWrapper
{
public string InfoFilePath { private set; get; }
public string DataFilePath { private set; get; }
public string DataFileCRC { private set; get; }
public long DataFileSize { private set; get; }
internal class CacheManager
{
internal class RecordWrapper
{
public string InfoFilePath { private set; get; }
public string DataFilePath { private set; get; }
public string DataFileCRC { private set; get; }
public long DataFileSize { private set; get; }
public RecordWrapper(string infoFilePath, string dataFilePath, string dataFileCRC, long dataFileSize)
{
InfoFilePath = infoFilePath;
DataFilePath = dataFilePath;
DataFileCRC = dataFileCRC;
DataFileSize = dataFileSize;
}
}
public RecordWrapper(string infoFilePath, string dataFilePath, string dataFileCRC, long dataFileSize)
{
InfoFilePath = infoFilePath;
DataFilePath = dataFilePath;
DataFileCRC = dataFileCRC;
DataFileSize = dataFileSize;
}
}
private readonly Dictionary<string, RecordWrapper> _wrappers = new Dictionary<string, RecordWrapper>();
private readonly Dictionary<string, RecordWrapper> _wrappers = new Dictionary<string, RecordWrapper>();
/// <summary>
/// 所属包裹
/// </summary>
public readonly string PackageName;
/// <summary>
/// 所属包裹
/// </summary>
public readonly string PackageName;
/// <summary>
/// 验证级别
/// </summary>
public readonly EVerifyLevel BootVerifyLevel;
/// <summary>
/// 验证级别
/// </summary>
public readonly EVerifyLevel BootVerifyLevel;
public CacheManager(string packageName, EVerifyLevel bootVerifyLevel)
{
PackageName = packageName;
BootVerifyLevel = bootVerifyLevel;
}
public CacheManager(string packageName, EVerifyLevel bootVerifyLevel)
{
PackageName = packageName;
BootVerifyLevel = bootVerifyLevel;
}
/// <summary>
/// 清空所有数据
/// </summary>
public void ClearAll()
{
_wrappers.Clear();
}
/// <summary>
/// 清空所有数据
/// </summary>
public void ClearAll()
{
_wrappers.Clear();
}
/// <summary>
/// 查询缓存记录
/// </summary>
public bool IsCached(string cacheGUID)
{
return _wrappers.ContainsKey(cacheGUID);
}
/// <summary>
/// 查询缓存记录
/// </summary>
public bool IsCached(string cacheGUID)
{
return _wrappers.ContainsKey(cacheGUID);
}
/// <summary>
/// 记录验证结果
/// </summary>
public void Record(string cacheGUID, RecordWrapper wrapper)
{
if (_wrappers.ContainsKey(cacheGUID) == false)
{
_wrappers.Add(cacheGUID, wrapper);
}
else
{
throw new Exception("Should never get here !");
}
}
/// <summary>
/// 记录验证结果
/// </summary>
public void Record(string cacheGUID, RecordWrapper wrapper)
{
if (_wrappers.ContainsKey(cacheGUID) == false)
{
_wrappers.Add(cacheGUID, wrapper);
}
else
{
throw new Exception("Should never get here !");
}
}
/// <summary>
/// 丢弃验证结果并删除缓存文件
/// </summary>
public void Discard(string cacheGUID)
{
var wrapper = TryGetWrapper(cacheGUID);
if (wrapper != null)
{
try
{
string dataFilePath = wrapper.DataFilePath;
FileInfo fileInfo = new FileInfo(dataFilePath);
if (fileInfo.Exists)
fileInfo.Directory.Delete(true);
}
catch (Exception e)
{
YooLogger.Error($"Failed to delete cache file ! {e.Message}");
}
}
/// <summary>
/// 丢弃验证结果并删除缓存文件
/// </summary>
public void Discard(string cacheGUID)
{
var wrapper = TryGetWrapper(cacheGUID);
if (wrapper != null)
{
try
{
string dataFilePath = wrapper.DataFilePath;
FileInfo fileInfo = new FileInfo(dataFilePath);
if (fileInfo.Exists)
fileInfo.Directory.Delete(true);
}
catch (Exception e)
{
YooLogger.Error($"Failed to delete cache file ! {e.Message}");
}
}
if (_wrappers.ContainsKey(cacheGUID))
{
_wrappers.Remove(cacheGUID);
}
}
if (_wrappers.ContainsKey(cacheGUID))
{
_wrappers.Remove(cacheGUID);
}
}
/// <summary>
/// 获取记录对象
/// </summary>
public RecordWrapper TryGetWrapper(string cacheGUID)
{
if (_wrappers.TryGetValue(cacheGUID, out RecordWrapper value))
return value;
else
return null;
}
/// <summary>
/// 获取记录对象
/// </summary>
public RecordWrapper TryGetWrapper(string cacheGUID)
{
if (_wrappers.TryGetValue(cacheGUID, out RecordWrapper value))
return value;
else
return null;
}
/// <summary>
/// 获取缓存文件总数
/// </summary>
public int GetAllCachedFilesCount()
{
return _wrappers.Count;
}
/// <summary>
/// 获取缓存文件总数
/// </summary>
public int GetAllCachedFilesCount()
{
return _wrappers.Count;
}
/// <summary>
/// 获取缓存GUID集合
/// </summary>
public List<string> GetAllCachedGUIDs()
{
List<string> keys = new List<string>(_wrappers.Keys.Count);
var keyCollection = _wrappers.Keys;
foreach (var key in keyCollection)
{
keys.Add(key);
}
return keys;
}
}
/// <summary>
/// 获取缓存GUID集合
/// </summary>
public List<string> GetAllCachedGUIDs()
{
List<string> keys = new List<string>(_wrappers.Keys.Count);
var keyCollection = _wrappers.Keys;
foreach (var key in keyCollection)
{
keys.Add(key);
}
return keys;
}
}
}

View File

@ -1,24 +1,24 @@

namespace YooAsset
{
/// <summary>
/// 下载文件校验等级
/// </summary>
public enum EVerifyLevel
{
/// <summary>
/// 验证文件存在
/// </summary>
Low,
/// <summary>
/// 下载文件校验等级
/// </summary>
public enum EVerifyLevel
{
/// <summary>
/// 验证文件存在
/// </summary>
Low,
/// <summary>
/// 验证文件大小
/// </summary>
Middle,
/// <summary>
/// 验证文件大小
/// </summary>
Middle,
/// <summary>
/// 验证文件大小和CRC
/// </summary>
High,
}
/// <summary>
/// 验证文件大小和CRC
/// </summary>
High,
}
}

View File

@ -4,68 +4,68 @@ using System.IO;
namespace YooAsset
{
/// <summary>
/// 清理本地包裹所有的缓存文件
/// </summary>
public sealed class ClearAllCacheFilesOperation : AsyncOperationBase
{
private enum ESteps
{
None,
GetAllCacheFiles,
ClearAllCacheFiles,
Done,
}
/// <summary>
/// 清理本地包裹所有的缓存文件
/// </summary>
public sealed class ClearAllCacheFilesOperation : AsyncOperationBase
{
private enum ESteps
{
None,
GetAllCacheFiles,
ClearAllCacheFiles,
Done,
}
private readonly CacheManager _cache;
private List<string> _allCacheGUIDs;
private int _fileTotalCount = 0;
private ESteps _steps = ESteps.None;
private readonly CacheManager _cache;
private List<string> _allCacheGUIDs;
private int _fileTotalCount = 0;
private ESteps _steps = ESteps.None;
internal ClearAllCacheFilesOperation(CacheManager cache)
{
_cache = cache;
}
internal override void InternalOnStart()
{
_steps = ESteps.GetAllCacheFiles;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
internal ClearAllCacheFilesOperation(CacheManager cache)
{
_cache = cache;
}
internal override void InternalOnStart()
{
_steps = ESteps.GetAllCacheFiles;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.GetAllCacheFiles)
{
_allCacheGUIDs = _cache.GetAllCachedGUIDs();
_fileTotalCount = _allCacheGUIDs.Count;
YooLogger.Log($"Found all cache file count : {_fileTotalCount}");
_steps = ESteps.ClearAllCacheFiles;
}
if (_steps == ESteps.GetAllCacheFiles)
{
_allCacheGUIDs = _cache.GetAllCachedGUIDs();
_fileTotalCount = _allCacheGUIDs.Count;
YooLogger.Log($"Found all cache file count : {_fileTotalCount}");
_steps = ESteps.ClearAllCacheFiles;
}
if (_steps == ESteps.ClearAllCacheFiles)
{
for (int i = _allCacheGUIDs.Count - 1; i >= 0; i--)
{
string cacheGUID = _allCacheGUIDs[i];
_cache.Discard(cacheGUID);
_allCacheGUIDs.RemoveAt(i);
if (_steps == ESteps.ClearAllCacheFiles)
{
for (int i = _allCacheGUIDs.Count - 1; i >= 0; i--)
{
string cacheGUID = _allCacheGUIDs[i];
_cache.Discard(cacheGUID);
_allCacheGUIDs.RemoveAt(i);
if (OperationSystem.IsBusy)
break;
}
if (OperationSystem.IsBusy)
break;
}
if (_fileTotalCount == 0)
Progress = 1.0f;
else
Progress = 1.0f - (_allCacheGUIDs.Count / _fileTotalCount);
if (_fileTotalCount == 0)
Progress = 1.0f;
else
Progress = 1.0f - (_allCacheGUIDs.Count / _fileTotalCount);
if (_allCacheGUIDs.Count == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
if (_allCacheGUIDs.Count == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
}

View File

@ -4,84 +4,84 @@ using System.IO;
namespace YooAsset
{
/// <summary>
/// 清理本地包裹未使用的缓存文件
/// </summary>
public sealed class ClearUnusedCacheFilesOperation : AsyncOperationBase
{
private enum ESteps
{
None,
GetUnusedCacheFiles,
ClearUnusedCacheFiles,
Done,
}
/// <summary>
/// 清理本地包裹未使用的缓存文件
/// </summary>
public sealed class ClearUnusedCacheFilesOperation : AsyncOperationBase
{
private enum ESteps
{
None,
GetUnusedCacheFiles,
ClearUnusedCacheFiles,
Done,
}
private readonly ResourcePackage _package;
private readonly CacheManager _cache;
private List<string> _unusedCacheGUIDs;
private int _unusedFileTotalCount = 0;
private ESteps _steps = ESteps.None;
private readonly ResourcePackage _package;
private readonly CacheManager _cache;
private List<string> _unusedCacheGUIDs;
private int _unusedFileTotalCount = 0;
private ESteps _steps = ESteps.None;
internal ClearUnusedCacheFilesOperation(ResourcePackage package, CacheManager cache)
{
_package = package;
_cache = cache;
}
internal override void InternalOnStart()
{
_steps = ESteps.GetUnusedCacheFiles;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
internal ClearUnusedCacheFilesOperation(ResourcePackage package, CacheManager cache)
{
_package = package;
_cache = cache;
}
internal override void InternalOnStart()
{
_steps = ESteps.GetUnusedCacheFiles;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.GetUnusedCacheFiles)
{
_unusedCacheGUIDs = GetUnusedCacheGUIDs();
_unusedFileTotalCount = _unusedCacheGUIDs.Count;
YooLogger.Log($"Found unused cache file count : {_unusedFileTotalCount}");
_steps = ESteps.ClearUnusedCacheFiles;
}
if (_steps == ESteps.GetUnusedCacheFiles)
{
_unusedCacheGUIDs = GetUnusedCacheGUIDs();
_unusedFileTotalCount = _unusedCacheGUIDs.Count;
YooLogger.Log($"Found unused cache file count : {_unusedFileTotalCount}");
_steps = ESteps.ClearUnusedCacheFiles;
}
if (_steps == ESteps.ClearUnusedCacheFiles)
{
for (int i = _unusedCacheGUIDs.Count - 1; i >= 0; i--)
{
string cacheGUID = _unusedCacheGUIDs[i];
_cache.Discard(cacheGUID);
_unusedCacheGUIDs.RemoveAt(i);
if (_steps == ESteps.ClearUnusedCacheFiles)
{
for (int i = _unusedCacheGUIDs.Count - 1; i >= 0; i--)
{
string cacheGUID = _unusedCacheGUIDs[i];
_cache.Discard(cacheGUID);
_unusedCacheGUIDs.RemoveAt(i);
if (OperationSystem.IsBusy)
break;
}
if (OperationSystem.IsBusy)
break;
}
if (_unusedFileTotalCount == 0)
Progress = 1.0f;
else
Progress = 1.0f - (_unusedCacheGUIDs.Count / _unusedFileTotalCount);
if (_unusedFileTotalCount == 0)
Progress = 1.0f;
else
Progress = 1.0f - (_unusedCacheGUIDs.Count / _unusedFileTotalCount);
if (_unusedCacheGUIDs.Count == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
if (_unusedCacheGUIDs.Count == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
private List<string> GetUnusedCacheGUIDs()
{
var allCacheGUIDs = _cache.GetAllCachedGUIDs();
List<string> result = new List<string>(allCacheGUIDs.Count);
foreach (var cacheGUID in allCacheGUIDs)
{
if (_package.IsIncludeBundleFile(cacheGUID) == false)
{
result.Add(cacheGUID);
}
}
return result;
}
}
private List<string> GetUnusedCacheGUIDs()
{
var allCacheGUIDs = _cache.GetAllCachedGUIDs();
List<string> result = new List<string>(allCacheGUIDs.Count);
foreach (var cacheGUID in allCacheGUIDs)
{
if (_package.IsIncludeBundleFile(cacheGUID) == false)
{
result.Add(cacheGUID);
}
}
return result;
}
}
}

View File

@ -5,127 +5,127 @@ using System.Collections.Generic;
namespace YooAsset
{
internal sealed class FindCacheFilesOperation : AsyncOperationBase
{
private enum ESteps
{
None,
Prepare,
UpdateCacheFiles,
Done,
}
internal sealed class FindCacheFilesOperation : AsyncOperationBase
{
private enum ESteps
{
None,
Prepare,
UpdateCacheFiles,
Done,
}
private readonly PersistentManager _persistent;
private readonly CacheManager _cache;
private IEnumerator<DirectoryInfo> _filesEnumerator = null;
private float _verifyStartTime;
private ESteps _steps = ESteps.None;
private readonly PersistentManager _persistent;
private readonly CacheManager _cache;
private IEnumerator<DirectoryInfo> _filesEnumerator = null;
private float _verifyStartTime;
private ESteps _steps = ESteps.None;
/// <summary>
/// 需要验证的元素
/// </summary>
public readonly List<VerifyCacheFileElement> VerifyElements = new List<VerifyCacheFileElement>(5000);
/// <summary>
/// 需要验证的元素
/// </summary>
public readonly List<VerifyCacheFileElement> VerifyElements = new List<VerifyCacheFileElement>(5000);
public FindCacheFilesOperation(PersistentManager persistent, CacheManager cache)
{
_persistent = persistent;
_cache = cache;
}
internal override void InternalOnStart()
{
_steps = ESteps.Prepare;
_verifyStartTime = UnityEngine.Time.realtimeSinceStartup;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public FindCacheFilesOperation(PersistentManager persistent, CacheManager cache)
{
_persistent = persistent;
_cache = cache;
}
internal override void InternalOnStart()
{
_steps = ESteps.Prepare;
_verifyStartTime = UnityEngine.Time.realtimeSinceStartup;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.Prepare)
{
string rootPath = _persistent.SandboxCacheFilesRoot;
DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);
if (rootDirectory.Exists)
{
var directorieInfos = rootDirectory.EnumerateDirectories();
_filesEnumerator = directorieInfos.GetEnumerator();
}
_steps = ESteps.UpdateCacheFiles;
}
if (_steps == ESteps.Prepare)
{
string rootPath = _persistent.SandboxCacheFilesRoot;
DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);
if (rootDirectory.Exists)
{
var directorieInfos = rootDirectory.EnumerateDirectories();
_filesEnumerator = directorieInfos.GetEnumerator();
}
_steps = ESteps.UpdateCacheFiles;
}
if (_steps == ESteps.UpdateCacheFiles)
{
if (UpdateCacheFiles())
return;
if (_steps == ESteps.UpdateCacheFiles)
{
if (UpdateCacheFiles())
return;
// 注意:总是返回成功
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime;
YooLogger.Log($"Find cache files elapsed time {costTime:f1} seconds");
}
}
// 注意:总是返回成功
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime;
YooLogger.Log($"Find cache files elapsed time {costTime:f1} seconds");
}
}
private bool UpdateCacheFiles()
{
if (_filesEnumerator == null)
return false;
private bool UpdateCacheFiles()
{
if (_filesEnumerator == null)
return false;
bool isFindItem;
while (true)
{
isFindItem = _filesEnumerator.MoveNext();
if (isFindItem == false)
break;
bool isFindItem;
while (true)
{
isFindItem = _filesEnumerator.MoveNext();
if (isFindItem == false)
break;
var rootFoder = _filesEnumerator.Current;
var childDirectories = rootFoder.GetDirectories();
foreach (var chidDirectory in childDirectories)
{
string cacheGUID = chidDirectory.Name;
if (_cache.IsCached(cacheGUID))
continue;
var rootFoder = _filesEnumerator.Current;
var childDirectories = rootFoder.GetDirectories();
foreach (var chidDirectory in childDirectories)
{
string cacheGUID = chidDirectory.Name;
if (_cache.IsCached(cacheGUID))
continue;
// 创建验证元素类
string fileRootPath = chidDirectory.FullName;
string dataFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleDataFileName}";
string infoFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleInfoFileName}";
string dataFileExtension = FindDataFileExtension(chidDirectory);
// 创建验证元素类
string fileRootPath = chidDirectory.FullName;
string dataFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleDataFileName}";
string infoFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleInfoFileName}";
string dataFileExtension = FindDataFileExtension(chidDirectory);
// 跳过断点续传的临时文件
if (dataFileExtension == ".temp")
continue;
// 跳过断点续传的临时文件
if (dataFileExtension == ".temp")
continue;
// 注意:根据配置需求数据文件会带文件格式
if (_persistent.AppendFileExtension)
{
if (string.IsNullOrEmpty(dataFileExtension) == false)
dataFilePath += dataFileExtension;
}
// 注意:根据配置需求数据文件会带文件格式
if (_persistent.AppendFileExtension)
{
if (string.IsNullOrEmpty(dataFileExtension) == false)
dataFilePath += dataFileExtension;
}
VerifyCacheFileElement element = new VerifyCacheFileElement(_cache.PackageName, cacheGUID, fileRootPath, dataFilePath, infoFilePath);
VerifyElements.Add(element);
}
VerifyCacheFileElement element = new VerifyCacheFileElement(_cache.PackageName, cacheGUID, fileRootPath, dataFilePath, infoFilePath);
VerifyElements.Add(element);
}
if (OperationSystem.IsBusy)
break;
}
if (OperationSystem.IsBusy)
break;
}
return isFindItem;
}
private string FindDataFileExtension(DirectoryInfo directoryInfo)
{
string dataFileExtension = string.Empty;
var fileInfos = directoryInfo.GetFiles();
foreach (var fileInfo in fileInfos)
{
if (fileInfo.Name.StartsWith(YooAssetSettings.CacheBundleDataFileName))
{
dataFileExtension = fileInfo.Extension;
break;
}
}
return dataFileExtension;
}
}
return isFindItem;
}
private string FindDataFileExtension(DirectoryInfo directoryInfo)
{
string dataFileExtension = string.Empty;
var fileInfos = directoryInfo.GetFiles();
foreach (var fileInfo in fileInfos)
{
if (fileInfo.Name.StartsWith(YooAssetSettings.CacheBundleDataFileName))
{
dataFileExtension = fileInfo.Extension;
break;
}
}
return dataFileExtension;
}
}
}

View File

@ -6,249 +6,249 @@ using System.Threading;
namespace YooAsset
{
internal abstract class VerifyCacheFilesOperation : AsyncOperationBase
{
public static VerifyCacheFilesOperation CreateOperation(CacheManager cache, List<VerifyCacheFileElement> elements)
{
internal abstract class VerifyCacheFilesOperation : AsyncOperationBase
{
public static VerifyCacheFilesOperation CreateOperation(CacheManager cache, List<VerifyCacheFileElement> elements)
{
#if UNITY_WEBGL
var operation = new VerifyCacheFilesWithoutThreadOperation(cache, elements);
#else
var operation = new VerifyCacheFilesWithThreadOperation(cache, elements);
var operation = new VerifyCacheFilesWithThreadOperation(cache, elements);
#endif
return operation;
}
}
return operation;
}
}
/// <summary>
/// 本地缓存文件验证(线程版)
/// </summary>
internal class VerifyCacheFilesWithThreadOperation : VerifyCacheFilesOperation
{
private enum ESteps
{
None,
InitVerify,
UpdateVerify,
Done,
}
/// <summary>
/// 本地缓存文件验证(线程版)
/// </summary>
internal class VerifyCacheFilesWithThreadOperation : VerifyCacheFilesOperation
{
private enum ESteps
{
None,
InitVerify,
UpdateVerify,
Done,
}
private readonly ThreadSyncContext _syncContext = new ThreadSyncContext();
private readonly CacheManager _cache;
private List<VerifyCacheFileElement> _waitingList;
private List<VerifyCacheFileElement> _verifyingList;
private int _verifyMaxNum;
private int _verifyTotalCount;
private float _verifyStartTime;
private int _succeedCount;
private int _failedCount;
private ESteps _steps = ESteps.None;
private readonly ThreadSyncContext _syncContext = new ThreadSyncContext();
private readonly CacheManager _cache;
private List<VerifyCacheFileElement> _waitingList;
private List<VerifyCacheFileElement> _verifyingList;
private int _verifyMaxNum;
private int _verifyTotalCount;
private float _verifyStartTime;
private int _succeedCount;
private int _failedCount;
private ESteps _steps = ESteps.None;
public VerifyCacheFilesWithThreadOperation(CacheManager cache, List<VerifyCacheFileElement> elements)
{
_cache = cache;
_waitingList = elements;
}
internal override void InternalOnStart()
{
_steps = ESteps.InitVerify;
_verifyStartTime = UnityEngine.Time.realtimeSinceStartup;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public VerifyCacheFilesWithThreadOperation(CacheManager cache, List<VerifyCacheFileElement> elements)
{
_cache = cache;
_waitingList = elements;
}
internal override void InternalOnStart()
{
_steps = ESteps.InitVerify;
_verifyStartTime = UnityEngine.Time.realtimeSinceStartup;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.InitVerify)
{
int fileCount = _waitingList.Count;
if (_steps == ESteps.InitVerify)
{
int fileCount = _waitingList.Count;
// 设置同时验证的最大数
ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads);
YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}");
_verifyMaxNum = Math.Min(workerThreads, ioThreads);
_verifyTotalCount = fileCount;
if (_verifyMaxNum < 1)
_verifyMaxNum = 1;
// 设置同时验证的最大数
ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads);
YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}");
_verifyMaxNum = Math.Min(workerThreads, ioThreads);
_verifyTotalCount = fileCount;
if (_verifyMaxNum < 1)
_verifyMaxNum = 1;
_verifyingList = new List<VerifyCacheFileElement>(_verifyMaxNum);
_steps = ESteps.UpdateVerify;
}
_verifyingList = new List<VerifyCacheFileElement>(_verifyMaxNum);
_steps = ESteps.UpdateVerify;
}
if (_steps == ESteps.UpdateVerify)
{
_syncContext.Update();
if (_steps == ESteps.UpdateVerify)
{
_syncContext.Update();
Progress = GetProgress();
if (_waitingList.Count == 0 && _verifyingList.Count == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime;
YooLogger.Log($"Verify cache files elapsed time {costTime:f1} seconds");
}
Progress = GetProgress();
if (_waitingList.Count == 0 && _verifyingList.Count == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime;
YooLogger.Log($"Verify cache files elapsed time {costTime:f1} seconds");
}
for (int i = _waitingList.Count - 1; i >= 0; i--)
{
if (OperationSystem.IsBusy)
break;
for (int i = _waitingList.Count - 1; i >= 0; i--)
{
if (OperationSystem.IsBusy)
break;
if (_verifyingList.Count >= _verifyMaxNum)
break;
if (_verifyingList.Count >= _verifyMaxNum)
break;
var element = _waitingList[i];
if (BeginVerifyFileWithThread(element))
{
_waitingList.RemoveAt(i);
_verifyingList.Add(element);
}
else
{
YooLogger.Warning("The thread pool is failed queued.");
break;
}
}
}
}
var element = _waitingList[i];
if (BeginVerifyFileWithThread(element))
{
_waitingList.RemoveAt(i);
_verifyingList.Add(element);
}
else
{
YooLogger.Warning("The thread pool is failed queued.");
break;
}
}
}
}
private float GetProgress()
{
if (_verifyTotalCount == 0)
return 1f;
return (float)(_succeedCount + _failedCount) / _verifyTotalCount;
}
private bool BeginVerifyFileWithThread(VerifyCacheFileElement element)
{
return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element);
}
private void VerifyInThread(object obj)
{
VerifyCacheFileElement element = (VerifyCacheFileElement)obj;
element.Result = CacheHelper.VerifyingCacheFile(element, _cache.BootVerifyLevel);
_syncContext.Post(VerifyCallback, element);
}
private void VerifyCallback(object obj)
{
VerifyCacheFileElement element = (VerifyCacheFileElement)obj;
_verifyingList.Remove(element);
private float GetProgress()
{
if (_verifyTotalCount == 0)
return 1f;
return (float)(_succeedCount + _failedCount) / _verifyTotalCount;
}
private bool BeginVerifyFileWithThread(VerifyCacheFileElement element)
{
return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element);
}
private void VerifyInThread(object obj)
{
VerifyCacheFileElement element = (VerifyCacheFileElement)obj;
element.Result = CacheHelper.VerifyingCacheFile(element, _cache.BootVerifyLevel);
_syncContext.Post(VerifyCallback, element);
}
private void VerifyCallback(object obj)
{
VerifyCacheFileElement element = (VerifyCacheFileElement)obj;
_verifyingList.Remove(element);
if (element.Result == EVerifyResult.Succeed)
{
_succeedCount++;
var wrapper = new CacheManager.RecordWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize);
_cache.Record(element.CacheGUID, wrapper);
}
else
{
_failedCount++;
if (element.Result == EVerifyResult.Succeed)
{
_succeedCount++;
var wrapper = new CacheManager.RecordWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize);
_cache.Record(element.CacheGUID, wrapper);
}
else
{
_failedCount++;
YooLogger.Warning($"Failed verify file and delete files : {element.FileRootPath}");
element.DeleteFiles();
}
}
}
YooLogger.Warning($"Failed verify file and delete files : {element.FileRootPath}");
element.DeleteFiles();
}
}
}
/// <summary>
/// 本地缓存文件验证(非线程版)
/// </summary>
internal class VerifyCacheFilesWithoutThreadOperation : VerifyCacheFilesOperation
{
private enum ESteps
{
None,
InitVerify,
UpdateVerify,
Done,
}
/// <summary>
/// 本地缓存文件验证(非线程版)
/// </summary>
internal class VerifyCacheFilesWithoutThreadOperation : VerifyCacheFilesOperation
{
private enum ESteps
{
None,
InitVerify,
UpdateVerify,
Done,
}
private readonly CacheManager _cache;
private List<VerifyCacheFileElement> _waitingList;
private List<VerifyCacheFileElement> _verifyingList;
private int _verifyMaxNum;
private int _verifyTotalCount;
private float _verifyStartTime;
private int _succeedCount;
private int _failedCount;
private ESteps _steps = ESteps.None;
private readonly CacheManager _cache;
private List<VerifyCacheFileElement> _waitingList;
private List<VerifyCacheFileElement> _verifyingList;
private int _verifyMaxNum;
private int _verifyTotalCount;
private float _verifyStartTime;
private int _succeedCount;
private int _failedCount;
private ESteps _steps = ESteps.None;
public VerifyCacheFilesWithoutThreadOperation(CacheManager cache, List<VerifyCacheFileElement> elements)
{
_cache = cache;
_waitingList = elements;
}
internal override void InternalOnStart()
{
_steps = ESteps.InitVerify;
_verifyStartTime = UnityEngine.Time.realtimeSinceStartup;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public VerifyCacheFilesWithoutThreadOperation(CacheManager cache, List<VerifyCacheFileElement> elements)
{
_cache = cache;
_waitingList = elements;
}
internal override void InternalOnStart()
{
_steps = ESteps.InitVerify;
_verifyStartTime = UnityEngine.Time.realtimeSinceStartup;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.InitVerify)
{
int fileCount = _waitingList.Count;
if (_steps == ESteps.InitVerify)
{
int fileCount = _waitingList.Count;
// 设置同时验证的最大数
_verifyMaxNum = fileCount;
_verifyTotalCount = fileCount;
// 设置同时验证的最大数
_verifyMaxNum = fileCount;
_verifyTotalCount = fileCount;
_verifyingList = new List<VerifyCacheFileElement>(_verifyMaxNum);
_steps = ESteps.UpdateVerify;
}
_verifyingList = new List<VerifyCacheFileElement>(_verifyMaxNum);
_steps = ESteps.UpdateVerify;
}
if (_steps == ESteps.UpdateVerify)
{
Progress = GetProgress();
if (_waitingList.Count == 0 && _verifyingList.Count == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime;
YooLogger.Log($"Package verify elapsed time {costTime:f1} seconds");
}
if (_steps == ESteps.UpdateVerify)
{
Progress = GetProgress();
if (_waitingList.Count == 0 && _verifyingList.Count == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime;
YooLogger.Log($"Package verify elapsed time {costTime:f1} seconds");
}
for (int i = _waitingList.Count - 1; i >= 0; i--)
{
if (OperationSystem.IsBusy)
break;
for (int i = _waitingList.Count - 1; i >= 0; i--)
{
if (OperationSystem.IsBusy)
break;
if (_verifyingList.Count >= _verifyMaxNum)
break;
if (_verifyingList.Count >= _verifyMaxNum)
break;
var element = _waitingList[i];
BeginVerifyFileWithoutThread(element);
_waitingList.RemoveAt(i);
_verifyingList.Add(element);
}
var element = _waitingList[i];
BeginVerifyFileWithoutThread(element);
_waitingList.RemoveAt(i);
_verifyingList.Add(element);
}
// 主线程内验证,可以清空列表
_verifyingList.Clear();
}
}
// 主线程内验证,可以清空列表
_verifyingList.Clear();
}
}
private float GetProgress()
{
if (_verifyTotalCount == 0)
return 1f;
return (float)(_succeedCount + _failedCount) / _verifyTotalCount;
}
private void BeginVerifyFileWithoutThread(VerifyCacheFileElement element)
{
element.Result = CacheHelper.VerifyingCacheFile(element, _cache.BootVerifyLevel);
if (element.Result == EVerifyResult.Succeed)
{
_succeedCount++;
var wrapper = new CacheManager.RecordWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize);
_cache.Record(element.CacheGUID, wrapper);
}
else
{
_failedCount++;
private float GetProgress()
{
if (_verifyTotalCount == 0)
return 1f;
return (float)(_succeedCount + _failedCount) / _verifyTotalCount;
}
private void BeginVerifyFileWithoutThread(VerifyCacheFileElement element)
{
element.Result = CacheHelper.VerifyingCacheFile(element, _cache.BootVerifyLevel);
if (element.Result == EVerifyResult.Succeed)
{
_succeedCount++;
var wrapper = new CacheManager.RecordWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize);
_cache.Record(element.CacheGUID, wrapper);
}
else
{
_failedCount++;
YooLogger.Warning($"Failed verify file and delete files : {element.FileRootPath}");
element.DeleteFiles();
}
}
}
YooLogger.Warning($"Failed verify file and delete files : {element.FileRootPath}");
element.DeleteFiles();
}
}
}
}

View File

@ -6,136 +6,136 @@ using System.Threading;
namespace YooAsset
{
internal abstract class VerifyTempFileOperation : AsyncOperationBase
{
public EVerifyResult VerifyResult { protected set; get; }
internal abstract class VerifyTempFileOperation : AsyncOperationBase
{
public EVerifyResult VerifyResult { protected set; get; }
public static VerifyTempFileOperation CreateOperation(VerifyTempFileElement element)
{
public static VerifyTempFileOperation CreateOperation(VerifyTempFileElement element)
{
#if UNITY_WEBGL
var operation = new VerifyTempFileWithoutThreadOperation(element);
#else
var operation = new VerifyTempFileWithThreadOperation(element);
var operation = new VerifyTempFileWithThreadOperation(element);
#endif
return operation;
}
}
return operation;
}
}
/// <summary>
/// 下载文件验证(线程版)
/// </summary>
internal class VerifyTempFileWithThreadOperation : VerifyTempFileOperation
{
private enum ESteps
{
None,
VerifyFile,
Waiting,
Done,
}
/// <summary>
/// 下载文件验证(线程版)
/// </summary>
internal class VerifyTempFileWithThreadOperation : VerifyTempFileOperation
{
private enum ESteps
{
None,
VerifyFile,
Waiting,
Done,
}
private readonly VerifyTempFileElement _element;
private ESteps _steps = ESteps.None;
private readonly VerifyTempFileElement _element;
private ESteps _steps = ESteps.None;
public VerifyTempFileWithThreadOperation(VerifyTempFileElement element)
{
_element = element;
}
internal override void InternalOnStart()
{
_steps = ESteps.VerifyFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public VerifyTempFileWithThreadOperation(VerifyTempFileElement element)
{
_element = element;
}
internal override void InternalOnStart()
{
_steps = ESteps.VerifyFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.VerifyFile)
{
if (BeginVerifyFileWithThread(_element))
{
_steps = ESteps.Waiting;
}
}
if (_steps == ESteps.VerifyFile)
{
if (BeginVerifyFileWithThread(_element))
{
_steps = ESteps.Waiting;
}
}
if (_steps == ESteps.Waiting)
{
int result = _element.Result;
if (result == 0)
return;
if (_steps == ESteps.Waiting)
{
int result = _element.Result;
if (result == 0)
return;
VerifyResult = (EVerifyResult)result;
if (VerifyResult == EVerifyResult.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed verify file : {_element.TempDataFilePath} ! ErrorCode : {VerifyResult}";
}
}
}
VerifyResult = (EVerifyResult)result;
if (VerifyResult == EVerifyResult.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed verify file : {_element.TempDataFilePath} ! ErrorCode : {VerifyResult}";
}
}
}
private bool BeginVerifyFileWithThread(VerifyTempFileElement element)
{
return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element);
}
private void VerifyInThread(object obj)
{
VerifyTempFileElement element = (VerifyTempFileElement)obj;
int result = (int)CacheHelper.VerifyingTempFile(element);
element.Result = result;
}
}
private bool BeginVerifyFileWithThread(VerifyTempFileElement element)
{
return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element);
}
private void VerifyInThread(object obj)
{
VerifyTempFileElement element = (VerifyTempFileElement)obj;
int result = (int)CacheHelper.VerifyingTempFile(element);
element.Result = result;
}
}
/// <summary>
/// 下载文件验证(非线程版)
/// </summary>
internal class VerifyTempFileWithoutThreadOperation : VerifyTempFileOperation
{
private enum ESteps
{
None,
VerifyFile,
Done,
}
/// <summary>
/// 下载文件验证(非线程版)
/// </summary>
internal class VerifyTempFileWithoutThreadOperation : VerifyTempFileOperation
{
private enum ESteps
{
None,
VerifyFile,
Done,
}
private readonly VerifyTempFileElement _element;
private ESteps _steps = ESteps.None;
private readonly VerifyTempFileElement _element;
private ESteps _steps = ESteps.None;
public VerifyTempFileWithoutThreadOperation(VerifyTempFileElement element)
{
_element = element;
}
internal override void InternalOnStart()
{
_steps = ESteps.VerifyFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public VerifyTempFileWithoutThreadOperation(VerifyTempFileElement element)
{
_element = element;
}
internal override void InternalOnStart()
{
_steps = ESteps.VerifyFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.VerifyFile)
{
_element.Result = (int)CacheHelper.VerifyingTempFile(_element);
if (_steps == ESteps.VerifyFile)
{
_element.Result = (int)CacheHelper.VerifyingTempFile(_element);
VerifyResult = (EVerifyResult)_element.Result;
if (VerifyResult == EVerifyResult.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed verify file : {_element.TempDataFilePath} ! ErrorCode : {VerifyResult}";
}
}
}
}
VerifyResult = (EVerifyResult)_element.Result;
if (VerifyResult == EVerifyResult.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed verify file : {_element.TempDataFilePath} ! ErrorCode : {VerifyResult}";
}
}
}
}
}

View File

@ -5,70 +5,70 @@ using System.Collections.Generic;
namespace YooAsset
{
internal class PackageCachingOperation : AsyncOperationBase
{
private enum ESteps
{
None,
FindCacheFiles,
VerifyCacheFiles,
Done,
}
internal class PackageCachingOperation : AsyncOperationBase
{
private enum ESteps
{
None,
FindCacheFiles,
VerifyCacheFiles,
Done,
}
private readonly PersistentManager _persistent;
private readonly CacheManager _cache;
private FindCacheFilesOperation _findCacheFilesOp;
private VerifyCacheFilesOperation _verifyCacheFilesOp;
private ESteps _steps = ESteps.None;
private readonly PersistentManager _persistent;
private readonly CacheManager _cache;
private FindCacheFilesOperation _findCacheFilesOp;
private VerifyCacheFilesOperation _verifyCacheFilesOp;
private ESteps _steps = ESteps.None;
public PackageCachingOperation(PersistentManager persistent, CacheManager cache)
{
_persistent = persistent;
_cache = cache;
}
internal override void InternalOnStart()
{
_steps = ESteps.FindCacheFiles;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public PackageCachingOperation(PersistentManager persistent, CacheManager cache)
{
_persistent = persistent;
_cache = cache;
}
internal override void InternalOnStart()
{
_steps = ESteps.FindCacheFiles;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.FindCacheFiles)
{
if (_findCacheFilesOp == null)
{
_findCacheFilesOp = new FindCacheFilesOperation(_persistent, _cache);
OperationSystem.StartOperation(_cache.PackageName, _findCacheFilesOp);
}
if (_steps == ESteps.FindCacheFiles)
{
if (_findCacheFilesOp == null)
{
_findCacheFilesOp = new FindCacheFilesOperation(_persistent, _cache);
OperationSystem.StartOperation(_cache.PackageName, _findCacheFilesOp);
}
Progress = _findCacheFilesOp.Progress;
if (_findCacheFilesOp.IsDone == false)
return;
Progress = _findCacheFilesOp.Progress;
if (_findCacheFilesOp.IsDone == false)
return;
_steps = ESteps.VerifyCacheFiles;
}
_steps = ESteps.VerifyCacheFiles;
}
if (_steps == ESteps.VerifyCacheFiles)
{
if (_verifyCacheFilesOp == null)
{
_verifyCacheFilesOp = VerifyCacheFilesOperation.CreateOperation(_cache, _findCacheFilesOp.VerifyElements);
OperationSystem.StartOperation(_cache.PackageName, _verifyCacheFilesOp);
}
if (_steps == ESteps.VerifyCacheFiles)
{
if (_verifyCacheFilesOp == null)
{
_verifyCacheFilesOp = VerifyCacheFilesOperation.CreateOperation(_cache, _findCacheFilesOp.VerifyElements);
OperationSystem.StartOperation(_cache.PackageName, _verifyCacheFilesOp);
}
Progress = _verifyCacheFilesOp.Progress;
if (_verifyCacheFilesOp.IsDone == false)
return;
Progress = _verifyCacheFilesOp.Progress;
if (_verifyCacheFilesOp.IsDone == false)
return;
// 注意:总是返回成功
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
// 注意:总是返回成功
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
int totalCount = _cache.GetAllCachedFilesCount();
YooLogger.Log($"Package '{_cache.PackageName}' cached files count : {totalCount}");
}
}
}
int totalCount = _cache.GetAllCachedFilesCount();
YooLogger.Log($"Package '{_cache.PackageName}' cached files count : {totalCount}");
}
}
}
}

View File

@ -1,15 +1,15 @@

namespace YooAsset
{
internal static class PersistentHelper
{
/// <summary>
/// 获取WWW加载本地资源的路径
/// </summary>
public static string ConvertToWWWPath(string path)
{
internal static class PersistentHelper
{
/// <summary>
/// 获取WWW加载本地资源的路径
/// </summary>
public static string ConvertToWWWPath(string path)
{
#if UNITY_EDITOR
return StringUtility.Format("file:///{0}", path);
return StringUtility.Format("file:///{0}", path);
#elif UNITY_WEBGL
return path;
#elif UNITY_IPHONE
@ -23,6 +23,6 @@ namespace YooAsset
#else
return path;
#endif
}
}
}
}
}

View File

@ -5,207 +5,207 @@ using System.Collections.Generic;
namespace YooAsset
{
internal class PersistentManager
{
private readonly Dictionary<string, string> _cachedDataFilePaths = new Dictionary<string, string>(10000);
private readonly Dictionary<string, string> _cachedInfoFilePaths = new Dictionary<string, string>(10000);
private readonly Dictionary<string, string> _tempDataFilePaths = new Dictionary<string, string>(10000);
private readonly Dictionary<string, string> _buildinFilePaths = new Dictionary<string, string>(10000);
internal class PersistentManager
{
private readonly Dictionary<string, string> _cachedDataFilePaths = new Dictionary<string, string>(10000);
private readonly Dictionary<string, string> _cachedInfoFilePaths = new Dictionary<string, string>(10000);
private readonly Dictionary<string, string> _tempDataFilePaths = new Dictionary<string, string>(10000);
private readonly Dictionary<string, string> _buildinFilePaths = new Dictionary<string, string>(10000);
/// <summary>
/// 所属包裹
/// </summary>
public readonly string PackageName;
/// <summary>
/// 所属包裹
/// </summary>
public readonly string PackageName;
public string BuildinRoot { private set; get; }
public string BuildinPackageRoot { private set; get; }
public string BuildinRoot { private set; get; }
public string BuildinPackageRoot { private set; get; }
public string SandboxRoot { private set; get; }
public string SandboxPackageRoot { private set; get; }
public string SandboxCacheFilesRoot { private set; get; }
public string SandboxManifestFilesRoot { private set; get; }
public string SandboxAppFootPrintFilePath { private set; get; }
public string SandboxRoot { private set; get; }
public string SandboxPackageRoot { private set; get; }
public string SandboxCacheFilesRoot { private set; get; }
public string SandboxManifestFilesRoot { private set; get; }
public string SandboxAppFootPrintFilePath { private set; get; }
public bool AppendFileExtension { private set; get; }
public bool AppendFileExtension { private set; get; }
public PersistentManager(string packageName)
{
PackageName = packageName;
}
public PersistentManager(string packageName)
{
PackageName = packageName;
}
/// <summary>
/// 初始化
/// </summary>
public void Initialize(string buildinRoot, string sandboxRoot, bool appendFileExtension)
{
if (string.IsNullOrEmpty(buildinRoot))
BuildinRoot = CreateDefaultBuildinRoot();
else
BuildinRoot = buildinRoot;
/// <summary>
/// 初始化
/// </summary>
public void Initialize(string buildinRoot, string sandboxRoot, bool appendFileExtension)
{
if (string.IsNullOrEmpty(buildinRoot))
BuildinRoot = CreateDefaultBuildinRoot();
else
BuildinRoot = buildinRoot;
if (string.IsNullOrEmpty(sandboxRoot))
SandboxRoot = CreateDefaultSandboxRoot();
else
SandboxRoot = sandboxRoot;
if (string.IsNullOrEmpty(sandboxRoot))
SandboxRoot = CreateDefaultSandboxRoot();
else
SandboxRoot = sandboxRoot;
BuildinPackageRoot = PathUtility.Combine(BuildinRoot, PackageName);
SandboxPackageRoot = PathUtility.Combine(SandboxRoot, PackageName);
SandboxCacheFilesRoot = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.CacheFilesFolderName);
SandboxManifestFilesRoot = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.ManifestFolderName);
SandboxAppFootPrintFilePath = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.AppFootPrintFileName);
AppendFileExtension = appendFileExtension;
}
private static string CreateDefaultBuildinRoot()
{
return PathUtility.Combine(UnityEngine.Application.streamingAssetsPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
}
private static string CreateDefaultSandboxRoot()
{
BuildinPackageRoot = PathUtility.Combine(BuildinRoot, PackageName);
SandboxPackageRoot = PathUtility.Combine(SandboxRoot, PackageName);
SandboxCacheFilesRoot = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.CacheFilesFolderName);
SandboxManifestFilesRoot = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.ManifestFolderName);
SandboxAppFootPrintFilePath = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.AppFootPrintFileName);
AppendFileExtension = appendFileExtension;
}
private static string CreateDefaultBuildinRoot()
{
return PathUtility.Combine(UnityEngine.Application.streamingAssetsPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
}
private static string CreateDefaultSandboxRoot()
{
#if UNITY_EDITOR
// 注意:为了方便调试查看,编辑器下把存储目录放到项目里。
string projectPath = Path.GetDirectoryName(UnityEngine.Application.dataPath);
projectPath = PathUtility.RegularPath(projectPath);
return PathUtility.Combine(projectPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
// 注意:为了方便调试查看,编辑器下把存储目录放到项目里。
string projectPath = Path.GetDirectoryName(UnityEngine.Application.dataPath);
projectPath = PathUtility.RegularPath(projectPath);
return PathUtility.Combine(projectPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
#elif UNITY_STANDALONE
return PathUtility.Combine(UnityEngine.Application.dataPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
#else
return PathUtility.Combine(UnityEngine.Application.persistentDataPath, YooAssetSettingsData.Setting.DefaultYooFolderName);
#endif
}
}
public string GetCachedDataFilePath(PackageBundle bundle)
{
if (_cachedDataFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false)
{
string folderName = bundle.FileHash.Substring(0, 2);
filePath = PathUtility.Combine(SandboxCacheFilesRoot, folderName, bundle.CacheGUID, YooAssetSettings.CacheBundleDataFileName);
if (AppendFileExtension)
filePath += bundle.FileExtension;
_cachedDataFilePaths.Add(bundle.CacheGUID, filePath);
}
return filePath;
}
public string GetCachedInfoFilePath(PackageBundle bundle)
{
if (_cachedInfoFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false)
{
string folderName = bundle.FileHash.Substring(0, 2);
filePath = PathUtility.Combine(SandboxCacheFilesRoot, folderName, bundle.CacheGUID, YooAssetSettings.CacheBundleInfoFileName);
_cachedInfoFilePaths.Add(bundle.CacheGUID, filePath);
}
return filePath;
}
public string GetTempDataFilePath(PackageBundle bundle)
{
if (_tempDataFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false)
{
string cachedDataFilePath = GetCachedDataFilePath(bundle);
filePath = $"{cachedDataFilePath}.temp";
_tempDataFilePaths.Add(bundle.CacheGUID, filePath);
}
return filePath;
}
public string GetBuildinFilePath(PackageBundle bundle)
{
if (_buildinFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false)
{
filePath = PathUtility.Combine(BuildinPackageRoot, bundle.FileName);
_buildinFilePaths.Add(bundle.CacheGUID, filePath);
}
return filePath;
}
public string GetCachedDataFilePath(PackageBundle bundle)
{
if (_cachedDataFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false)
{
string folderName = bundle.FileHash.Substring(0, 2);
filePath = PathUtility.Combine(SandboxCacheFilesRoot, folderName, bundle.CacheGUID, YooAssetSettings.CacheBundleDataFileName);
if (AppendFileExtension)
filePath += bundle.FileExtension;
_cachedDataFilePaths.Add(bundle.CacheGUID, filePath);
}
return filePath;
}
public string GetCachedInfoFilePath(PackageBundle bundle)
{
if (_cachedInfoFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false)
{
string folderName = bundle.FileHash.Substring(0, 2);
filePath = PathUtility.Combine(SandboxCacheFilesRoot, folderName, bundle.CacheGUID, YooAssetSettings.CacheBundleInfoFileName);
_cachedInfoFilePaths.Add(bundle.CacheGUID, filePath);
}
return filePath;
}
public string GetTempDataFilePath(PackageBundle bundle)
{
if (_tempDataFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false)
{
string cachedDataFilePath = GetCachedDataFilePath(bundle);
filePath = $"{cachedDataFilePath}.temp";
_tempDataFilePaths.Add(bundle.CacheGUID, filePath);
}
return filePath;
}
public string GetBuildinFilePath(PackageBundle bundle)
{
if (_buildinFilePaths.TryGetValue(bundle.CacheGUID, out string filePath) == false)
{
filePath = PathUtility.Combine(BuildinPackageRoot, bundle.FileName);
_buildinFilePaths.Add(bundle.CacheGUID, filePath);
}
return filePath;
}
/// <summary>
/// 删除沙盒里的包裹目录
/// </summary>
public void DeleteSandboxPackageFolder()
{
if (Directory.Exists(SandboxPackageRoot))
Directory.Delete(SandboxPackageRoot, true);
}
/// <summary>
/// 删除沙盒里的包裹目录
/// </summary>
public void DeleteSandboxPackageFolder()
{
if (Directory.Exists(SandboxPackageRoot))
Directory.Delete(SandboxPackageRoot, true);
}
/// <summary>
/// 删除沙盒内的缓存文件夹
/// </summary>
public void DeleteSandboxCacheFilesFolder()
{
if (Directory.Exists(SandboxCacheFilesRoot))
Directory.Delete(SandboxCacheFilesRoot, true);
}
/// <summary>
/// 删除沙盒内的缓存文件夹
/// </summary>
public void DeleteSandboxCacheFilesFolder()
{
if (Directory.Exists(SandboxCacheFilesRoot))
Directory.Delete(SandboxCacheFilesRoot, true);
}
/// <summary>
/// 删除沙盒内的清单文件夹
/// </summary>
public void DeleteSandboxManifestFilesFolder()
{
if (Directory.Exists(SandboxManifestFilesRoot))
Directory.Delete(SandboxManifestFilesRoot, true);
}
/// <summary>
/// 删除沙盒内的清单文件夹
/// </summary>
public void DeleteSandboxManifestFilesFolder()
{
if (Directory.Exists(SandboxManifestFilesRoot))
Directory.Delete(SandboxManifestFilesRoot, true);
}
/// <summary>
/// 获取沙盒内包裹的清单文件的路径
/// </summary>
public string GetSandboxPackageManifestFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion);
return PathUtility.Combine(SandboxManifestFilesRoot, fileName);
}
/// <summary>
/// 获取沙盒内包裹的清单文件的路径
/// </summary>
public string GetSandboxPackageManifestFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion);
return PathUtility.Combine(SandboxManifestFilesRoot, fileName);
}
/// <summary>
/// 获取沙盒内包裹的哈希文件的路径
/// </summary>
public string GetSandboxPackageHashFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion);
return PathUtility.Combine(SandboxManifestFilesRoot, fileName);
}
/// <summary>
/// 获取沙盒内包裹的哈希文件的路径
/// </summary>
public string GetSandboxPackageHashFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion);
return PathUtility.Combine(SandboxManifestFilesRoot, fileName);
}
/// <summary>
/// 获取沙盒内包裹的版本文件的路径
/// </summary>
public string GetSandboxPackageVersionFilePath()
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(PackageName);
return PathUtility.Combine(SandboxManifestFilesRoot, fileName);
}
/// <summary>
/// 获取沙盒内包裹的版本文件的路径
/// </summary>
public string GetSandboxPackageVersionFilePath()
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(PackageName);
return PathUtility.Combine(SandboxManifestFilesRoot, fileName);
}
/// <summary>
/// 保存沙盒内默认的包裹版本
/// </summary>
public void SaveSandboxPackageVersionFile(string version)
{
string filePath = GetSandboxPackageVersionFilePath();
FileUtility.WriteAllText(filePath, version);
}
/// <summary>
/// 保存沙盒内默认的包裹版本
/// </summary>
public void SaveSandboxPackageVersionFile(string version)
{
string filePath = GetSandboxPackageVersionFilePath();
FileUtility.WriteAllText(filePath, version);
}
/// <summary>
/// 获取APP内包裹的清单文件的路径
/// </summary>
public string GetBuildinPackageManifestFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion);
return PathUtility.Combine(BuildinPackageRoot, fileName);
}
/// <summary>
/// 获取APP内包裹的清单文件的路径
/// </summary>
public string GetBuildinPackageManifestFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(PackageName, packageVersion);
return PathUtility.Combine(BuildinPackageRoot, fileName);
}
/// <summary>
/// 获取APP内包裹的哈希文件的路径
/// </summary>
public string GetBuildinPackageHashFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion);
return PathUtility.Combine(BuildinPackageRoot, fileName);
}
/// <summary>
/// 获取APP内包裹的哈希文件的路径
/// </summary>
public string GetBuildinPackageHashFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(PackageName, packageVersion);
return PathUtility.Combine(BuildinPackageRoot, fileName);
}
/// <summary>
/// 获取APP内包裹的版本文件的路径
/// </summary>
public string GetBuildinPackageVersionFilePath()
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(PackageName);
return PathUtility.Combine(BuildinPackageRoot, fileName);
}
}
/// <summary>
/// 获取APP内包裹的版本文件的路径
/// </summary>
public string GetBuildinPackageVersionFilePath()
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(PackageName);
return PathUtility.Combine(BuildinPackageRoot, fileName);
}
}
}

View File

@ -2,59 +2,59 @@
namespace YooAsset
{
/// <summary>
/// 缓存文件验证元素
/// </summary>
internal class VerifyCacheFileElement
{
public string PackageName { private set; get; }
public string CacheGUID { private set; get; }
public string FileRootPath { private set; get; }
public string DataFilePath { private set; get; }
public string InfoFilePath { private set; get; }
/// <summary>
/// 缓存文件验证元素
/// </summary>
internal class VerifyCacheFileElement
{
public string PackageName { private set; get; }
public string CacheGUID { private set; get; }
public string FileRootPath { private set; get; }
public string DataFilePath { private set; get; }
public string InfoFilePath { private set; get; }
public EVerifyResult Result;
public string DataFileCRC;
public long DataFileSize;
public EVerifyResult Result;
public string DataFileCRC;
public long DataFileSize;
public VerifyCacheFileElement(string packageName, string cacheGUID, string fileRootPath, string dataFilePath, string infoFilePath)
{
PackageName = packageName;
CacheGUID = cacheGUID;
FileRootPath = fileRootPath;
DataFilePath = dataFilePath;
InfoFilePath = infoFilePath;
}
public VerifyCacheFileElement(string packageName, string cacheGUID, string fileRootPath, string dataFilePath, string infoFilePath)
{
PackageName = packageName;
CacheGUID = cacheGUID;
FileRootPath = fileRootPath;
DataFilePath = dataFilePath;
InfoFilePath = infoFilePath;
}
public void DeleteFiles()
{
try
{
Directory.Delete(FileRootPath, true);
}
catch(System.Exception e)
{
YooLogger.Warning($"Failed delete cache bundle folder : {e}");
}
}
}
public void DeleteFiles()
{
try
{
Directory.Delete(FileRootPath, true);
}
catch (System.Exception e)
{
YooLogger.Warning($"Failed delete cache bundle folder : {e}");
}
}
}
/// <summary>
/// 下载文件验证元素
/// </summary>
internal class VerifyTempFileElement
{
public string TempDataFilePath { private set; get; }
public string FileCRC { private set; get; }
public long FileSize { private set; get; }
/// <summary>
/// 下载文件验证元素
/// </summary>
internal class VerifyTempFileElement
{
public string TempDataFilePath { private set; get; }
public string FileCRC { private set; get; }
public long FileSize { private set; get; }
public int Result = 0; // 注意:原子操作对象
public int Result = 0; // 注意:原子操作对象
public VerifyTempFileElement(string tempDataFilePath, string fileCRC, long fileSize)
{
TempDataFilePath = tempDataFilePath;
FileCRC = fileCRC;
FileSize = fileSize;
}
}
public VerifyTempFileElement(string tempDataFilePath, string fileCRC, long fileSize)
{
TempDataFilePath = tempDataFilePath;
FileCRC = fileCRC;
FileSize = fileSize;
}
}
}

View File

@ -4,36 +4,36 @@ using System.Collections.Generic;
namespace YooAsset
{
[Serializable]
internal class DebugBundleInfo : IComparer<DebugBundleInfo>, IComparable<DebugBundleInfo>
{
/// <summary>
/// 包裹名
/// </summary>
public string PackageName { set; get; }
[Serializable]
internal class DebugBundleInfo : IComparer<DebugBundleInfo>, IComparable<DebugBundleInfo>
{
/// <summary>
/// 包裹名
/// </summary>
public string PackageName { set; get; }
/// <summary>
/// 资源包名称
/// </summary>
public string BundleName;
/// <summary>
/// 资源包名称
/// </summary>
public string BundleName;
/// <summary>
/// 引用计数
/// </summary>
public int RefCount;
/// <summary>
/// 引用计数
/// </summary>
public int RefCount;
/// <summary>
/// 加载状态
/// </summary>
public string Status;
/// <summary>
/// 加载状态
/// </summary>
public string Status;
public int CompareTo(DebugBundleInfo other)
{
return Compare(this, other);
}
public int Compare(DebugBundleInfo a, DebugBundleInfo b)
{
return string.CompareOrdinal(a.BundleName, b.BundleName);
}
}
public int CompareTo(DebugBundleInfo other)
{
return Compare(this, other);
}
public int Compare(DebugBundleInfo a, DebugBundleInfo b)
{
return string.CompareOrdinal(a.BundleName, b.BundleName);
}
}
}

View File

@ -5,17 +5,17 @@ using System.Collections.Generic;
namespace YooAsset
{
[Serializable]
internal class DebugPackageData
{
/// <summary>
/// 包裹名称
/// </summary>
public string PackageName;
[Serializable]
internal class DebugPackageData
{
/// <summary>
/// 包裹名称
/// </summary>
public string PackageName;
/// <summary>
/// 调试数据列表
/// </summary>
public List<DebugProviderInfo> ProviderInfos = new List<DebugProviderInfo>(1000);
}
/// <summary>
/// 调试数据列表
/// </summary>
public List<DebugProviderInfo> ProviderInfos = new List<DebugProviderInfo>(1000);
}
}

View File

@ -4,56 +4,56 @@ using System.Collections.Generic;
namespace YooAsset
{
[Serializable]
internal class DebugProviderInfo : IComparer<DebugProviderInfo>, IComparable<DebugProviderInfo>
{
/// <summary>
/// 包裹名
/// </summary>
public string PackageName { set; get; }
[Serializable]
internal class DebugProviderInfo : IComparer<DebugProviderInfo>, IComparable<DebugProviderInfo>
{
/// <summary>
/// 包裹名
/// </summary>
public string PackageName { set; get; }
/// <summary>
/// 资源对象路径
/// </summary>
public string AssetPath;
/// <summary>
/// 资源对象路径
/// </summary>
public string AssetPath;
/// <summary>
/// 资源出生的场景
/// </summary>
public string SpawnScene;
/// <summary>
/// 资源出生的场景
/// </summary>
public string SpawnScene;
/// <summary>
/// 资源出生的时间
/// </summary>
public string SpawnTime;
/// <summary>
/// 资源出生的时间
/// </summary>
public string SpawnTime;
/// <summary>
/// 加载耗时(单位:毫秒)
/// </summary>
public long LoadingTime;
/// <summary>
/// 加载耗时(单位:毫秒)
/// </summary>
public long LoadingTime;
/// <summary>
/// 引用计数
/// </summary>
public int RefCount;
/// <summary>
/// 引用计数
/// </summary>
public int RefCount;
/// <summary>
/// 加载状态
/// </summary>
public string Status;
/// <summary>
/// 加载状态
/// </summary>
public string Status;
/// <summary>
/// 依赖的资源包列表
/// </summary>
public List<DebugBundleInfo> DependBundleInfos;
/// <summary>
/// 依赖的资源包列表
/// </summary>
public List<DebugBundleInfo> DependBundleInfos;
public int CompareTo(DebugProviderInfo other)
{
return Compare(this, other);
}
public int Compare(DebugProviderInfo a, DebugProviderInfo b)
{
return string.CompareOrdinal(a.AssetPath, b.AssetPath);
}
}
public int CompareTo(DebugProviderInfo other)
{
return Compare(this, other);
}
public int Compare(DebugProviderInfo a, DebugProviderInfo b)
{
return string.CompareOrdinal(a.AssetPath, b.AssetPath);
}
}
}

View File

@ -6,34 +6,34 @@ using UnityEngine;
namespace YooAsset
{
/// <summary>
/// 资源系统调试信息
/// </summary>
[Serializable]
internal class DebugReport
{
/// <summary>
/// 游戏帧
/// </summary>
public int FrameCount;
/// <summary>
/// 资源系统调试信息
/// </summary>
[Serializable]
internal class DebugReport
{
/// <summary>
/// 游戏帧
/// </summary>
public int FrameCount;
/// <summary>
/// 调试的包裹数据列表
/// </summary>
public List<DebugPackageData> PackageDatas = new List<DebugPackageData>(10);
/// <summary>
/// 调试的包裹数据列表
/// </summary>
public List<DebugPackageData> PackageDatas = new List<DebugPackageData>(10);
/// <summary>
/// 序列化
/// </summary>
public static byte[] Serialize(DebugReport debugReport)
/// <summary>
/// 序列化
/// </summary>
public static byte[] Serialize(DebugReport debugReport)
{
return Encoding.UTF8.GetBytes(JsonUtility.ToJson(debugReport));
}
/// <summary>
/// 反序列化
/// </summary>
/// <summary>
/// 反序列化
/// </summary>
public static DebugReport Deserialize(byte[] data)
{
return JsonUtility.FromJson<DebugReport>(Encoding.UTF8.GetString(data));

View File

@ -4,42 +4,42 @@ using UnityEngine;
namespace YooAsset
{
internal enum ERemoteCommand
{
/// <summary>
/// 采样一次
/// </summary>
SampleOnce = 0,
}
internal enum ERemoteCommand
{
/// <summary>
/// 采样一次
/// </summary>
SampleOnce = 0,
}
[Serializable]
internal class RemoteCommand
{
/// <summary>
/// 命令类型
/// </summary>
public int CommandType;
[Serializable]
internal class RemoteCommand
{
/// <summary>
/// 命令类型
/// </summary>
public int CommandType;
/// <summary>
/// 命令附加参数
/// </summary>
public string CommandParam;
/// <summary>
/// 命令附加参数
/// </summary>
public string CommandParam;
/// <summary>
/// 序列化
/// </summary>
public static byte[] Serialize(RemoteCommand command)
{
return Encoding.UTF8.GetBytes(JsonUtility.ToJson(command));
}
/// <summary>
/// 序列化
/// </summary>
public static byte[] Serialize(RemoteCommand command)
{
return Encoding.UTF8.GetBytes(JsonUtility.ToJson(command));
}
/// <summary>
/// 反序列化
/// </summary>
public static RemoteCommand Deserialize(byte[] data)
{
return JsonUtility.FromJson<RemoteCommand>(Encoding.UTF8.GetString(data));
}
}
/// <summary>
/// 反序列化
/// </summary>
public static RemoteCommand Deserialize(byte[] data)
{
return JsonUtility.FromJson<RemoteCommand>(Encoding.UTF8.GetString(data));
}
}
}

View File

@ -1,12 +1,11 @@
using System;
using System.Text;
using UnityEngine;
namespace YooAsset
{
internal class RemoteDebuggerDefine
{
public static readonly Guid kMsgSendPlayerToEditor = new Guid("e34a5702dd353724aa315fb8011f08c3");
public static readonly Guid kMsgSendEditorToPlayer = new Guid("4d1926c9df5b052469a1c63448b7609a");
}
internal class RemoteDebuggerDefine
{
public static readonly Guid kMsgSendPlayerToEditor = new Guid("e34a5702dd353724aa315fb8011f08c3");
public static readonly Guid kMsgSendEditorToPlayer = new Guid("4d1926c9df5b052469a1c63448b7609a");
}
}

View File

@ -5,25 +5,25 @@ using UnityEngine.Networking.PlayerConnection;
namespace YooAsset
{
internal class RemoteDebuggerInRuntime : MonoBehaviour
{
internal class RemoteDebuggerInRuntime : MonoBehaviour
{
#if UNITY_EDITOR
/// <summary>
/// 编辑器下获取报告的回调
/// </summary>
public static Action<int, DebugReport> EditorHandleDebugReportCallback;
/// <summary>
/// 编辑器下获取报告的回调
/// </summary>
public static Action<int, DebugReport> EditorHandleDebugReportCallback;
/// <summary>
/// 编辑器下请求报告数据
/// </summary>
public static void EditorRequestDebugReport()
{
if(UnityEditor.EditorApplication.isPlaying)
{
var report = YooAssets.GetDebugReport();
EditorHandleDebugReportCallback?.Invoke(0, report);
}
}
/// <summary>
/// 编辑器下请求报告数据
/// </summary>
public static void EditorRequestDebugReport()
{
if (UnityEditor.EditorApplication.isPlaying)
{
var report = YooAssets.GetDebugReport();
EditorHandleDebugReportCallback?.Invoke(0, report);
}
}
#else
private void OnEnable()
{
@ -49,5 +49,5 @@ namespace YooAsset
}
}
#endif
}
}
}

View File

@ -7,35 +7,35 @@ using UnityEngine.Networking;
namespace YooAsset
{
/// <summary>
/// 自定义下载器的请求委托
/// </summary>
public delegate UnityWebRequest DownloadRequestDelegate(string url);
/// <summary>
/// 自定义下载器的请求委托
/// </summary>
public delegate UnityWebRequest DownloadRequestDelegate(string url);
internal static class DownloadHelper
{
/// <summary>
/// 下载失败后清理文件的HTTP错误码
/// </summary>
public static List<long> ClearFileResponseCodes { set; get; }
internal static class DownloadHelper
{
/// <summary>
/// 下载失败后清理文件的HTTP错误码
/// </summary>
public static List<long> ClearFileResponseCodes { set; get; }
/// <summary>
/// 自定义下载器的请求委托
/// </summary>
public static DownloadRequestDelegate RequestDelegate = null;
/// <summary>
/// 自定义下载器的请求委托
/// </summary>
public static DownloadRequestDelegate RequestDelegate = null;
/// <summary>
/// 创建一个新的网络请求
/// </summary>
public static UnityWebRequest NewRequest(string requestURL)
{
UnityWebRequest webRequest;
if (RequestDelegate != null)
webRequest = RequestDelegate.Invoke(requestURL);
else
webRequest = new UnityWebRequest(requestURL, UnityWebRequest.kHttpVerbGET);
return webRequest;
}
}
/// <summary>
/// 创建一个新的网络请求
/// </summary>
public static UnityWebRequest NewRequest(string requestURL)
{
UnityWebRequest webRequest;
if (RequestDelegate != null)
webRequest = RequestDelegate.Invoke(requestURL);
else
webRequest = new UnityWebRequest(requestURL, UnityWebRequest.kHttpVerbGET);
return webRequest;
}
}
}

View File

@ -6,99 +6,99 @@ using UnityEngine.Networking;
namespace YooAsset
{
/// <summary>
/// 1. 保证每一时刻资源文件只存在一个下载器
/// 2. 保证下载器下载完成后立刻验证并缓存
/// 3. 保证资源文件不会被重复下载
/// </summary>
internal class DownloadManager
{
private readonly Dictionary<string, DownloaderBase> _downloaders = new Dictionary<string, DownloaderBase>(1000);
private readonly List<string> _removeList = new List<string>(1000);
/// <summary>
/// 1. 保证每一时刻资源文件只存在一个下载器
/// 2. 保证下载器下载完成后立刻验证并缓存
/// 3. 保证资源文件不会被重复下载
/// </summary>
internal class DownloadManager
{
private readonly Dictionary<string, DownloaderBase> _downloaders = new Dictionary<string, DownloaderBase>(1000);
private readonly List<string> _removeList = new List<string>(1000);
private uint _breakpointResumeFileSize;
private uint _breakpointResumeFileSize;
/// <summary>
/// 所属包裹
/// </summary>
public readonly string PackageName;
/// <summary>
/// 所属包裹
/// </summary>
public readonly string PackageName;
public DownloadManager(string packageName)
{
PackageName = packageName;
}
public DownloadManager(string packageName)
{
PackageName = packageName;
}
/// <summary>
/// 初始化
/// </summary>
public void Initialize(uint breakpointResumeFileSize)
{
_breakpointResumeFileSize = breakpointResumeFileSize;
}
/// <summary>
/// 初始化
/// </summary>
public void Initialize(uint breakpointResumeFileSize)
{
_breakpointResumeFileSize = breakpointResumeFileSize;
}
/// <summary>
/// 更新下载器
/// </summary>
public void Update()
{
// 更新下载器
_removeList.Clear();
foreach (var valuePair in _downloaders)
{
var downloader = valuePair.Value;
downloader.Update();
if (downloader.IsDone())
{
_removeList.Add(valuePair.Key);
}
}
/// <summary>
/// 更新下载器
/// </summary>
public void Update()
{
// 更新下载器
_removeList.Clear();
foreach (var valuePair in _downloaders)
{
var downloader = valuePair.Value;
downloader.Update();
if (downloader.IsDone())
{
_removeList.Add(valuePair.Key);
}
}
// 移除下载器
foreach (var key in _removeList)
{
_downloaders.Remove(key);
}
}
// 移除下载器
foreach (var key in _removeList)
{
_downloaders.Remove(key);
}
}
/// <summary>
/// 销毁所有下载器
/// </summary>
public void DestroyAll()
{
foreach (var valuePair in _downloaders)
{
var downloader = valuePair.Value;
downloader.Abort();
}
/// <summary>
/// 销毁所有下载器
/// </summary>
public void DestroyAll()
{
foreach (var valuePair in _downloaders)
{
var downloader = valuePair.Value;
downloader.Abort();
}
_downloaders.Clear();
_removeList.Clear();
}
_downloaders.Clear();
_removeList.Clear();
}
/// <summary>
/// 创建下载器
/// 注意:只有第一次请求的参数才有效
/// </summary>
public DownloaderBase CreateDownload(BundleInfo bundleInfo, int failedTryAgain, int timeout = 60)
{
// 查询存在的下载器
if (_downloaders.TryGetValue(bundleInfo.CachedDataFilePath, out var downloader))
{
downloader.Reference();
return downloader;
}
/// <summary>
/// 创建下载器
/// 注意:只有第一次请求的参数才有效
/// </summary>
public DownloaderBase CreateDownload(BundleInfo bundleInfo, int failedTryAgain, int timeout = 60)
{
// 查询存在的下载器
if (_downloaders.TryGetValue(bundleInfo.CachedDataFilePath, out var downloader))
{
downloader.Reference();
return downloader;
}
// 如果资源已经缓存
if (bundleInfo.IsCached())
{
var completedDownloader = new CompletedDownloader(bundleInfo);
return completedDownloader;
}
// 如果资源已经缓存
if (bundleInfo.IsCached())
{
var completedDownloader = new CompletedDownloader(bundleInfo);
return completedDownloader;
}
// 创建新的下载器
DownloaderBase newDownloader = null;
YooLogger.Log($"Beginning to download bundle : {bundleInfo.Bundle.BundleName} URL : {bundleInfo.RemoteMainURL}");
// 创建新的下载器
DownloaderBase newDownloader = null;
YooLogger.Log($"Beginning to download bundle : {bundleInfo.Bundle.BundleName} URL : {bundleInfo.RemoteMainURL}");
#if UNITY_WEBGL
if (bundleInfo.Bundle.Buildpipeline == EDefaultBuildPipeline.RawFileBuildPipeline.ToString())
{
@ -112,39 +112,39 @@ namespace YooAsset
newDownloader = new WebDownloader(bundleInfo, requesterType, failedTryAgain, timeout);
}
#else
FileUtility.CreateFileDirectory(bundleInfo.CachedDataFilePath);
bool resumeDownload = bundleInfo.Bundle.FileSize >= _breakpointResumeFileSize;
if (resumeDownload)
{
System.Type requesterType = typeof(FileResumeRequest);
newDownloader = new FileDownloader(bundleInfo, requesterType, failedTryAgain, timeout);
}
else
{
System.Type requesterType = typeof(FileGeneralRequest);
newDownloader = new FileDownloader(bundleInfo, requesterType, failedTryAgain, timeout);
}
FileUtility.CreateFileDirectory(bundleInfo.CachedDataFilePath);
bool resumeDownload = bundleInfo.Bundle.FileSize >= _breakpointResumeFileSize;
if (resumeDownload)
{
System.Type requesterType = typeof(FileResumeRequest);
newDownloader = new FileDownloader(bundleInfo, requesterType, failedTryAgain, timeout);
}
else
{
System.Type requesterType = typeof(FileGeneralRequest);
newDownloader = new FileDownloader(bundleInfo, requesterType, failedTryAgain, timeout);
}
#endif
// 返回新创建的下载器
_downloaders.Add(bundleInfo.CachedDataFilePath, newDownloader);
newDownloader.Reference();
return newDownloader;
}
// 返回新创建的下载器
_downloaders.Add(bundleInfo.CachedDataFilePath, newDownloader);
newDownloader.Reference();
return newDownloader;
}
/// <summary>
/// 停止不再使用的下载器
/// </summary>
public void AbortUnusedDownloader()
{
foreach (var valuePair in _downloaders)
{
var downloader = valuePair.Value;
if (downloader.RefCount <= 0)
{
downloader.Abort();
}
}
}
}
/// <summary>
/// 停止不再使用的下载器
/// </summary>
public void AbortUnusedDownloader()
{
foreach (var valuePair in _downloaders)
{
var downloader = valuePair.Value;
if (downloader.RefCount <= 0)
{
downloader.Abort();
}
}
}
}
}

View File

@ -1,36 +1,36 @@

namespace YooAsset
{
public struct DownloadStatus
{
/// <summary>
/// 下载是否完成
/// </summary>
public bool IsDone;
public struct DownloadStatus
{
/// <summary>
/// 下载是否完成
/// </summary>
public bool IsDone;
/// <summary>
/// 下载进度0f~1f
/// </summary>
public float Progress;
/// <summary>
/// 下载进度0f~1f
/// </summary>
public float Progress;
/// <summary>
/// 需要下载的总字节数
/// </summary>
public ulong TotalBytes;
/// <summary>
/// 需要下载的总字节数
/// </summary>
public ulong TotalBytes;
/// <summary>
/// 已经下载的字节数
/// </summary>
public ulong DownloadedBytes;
/// <summary>
/// 已经下载的字节数
/// </summary>
public ulong DownloadedBytes;
public static DownloadStatus CreateDefaultStatus()
{
DownloadStatus status = new DownloadStatus();
status.IsDone = false;
status.Progress = 0f;
status.TotalBytes = 0;
status.DownloadedBytes = 0;
return status;
}
}
public static DownloadStatus CreateDefaultStatus()
{
DownloadStatus status = new DownloadStatus();
status.IsDone = false;
status.Progress = 0f;
status.TotalBytes = 0;
status.DownloadedBytes = 0;
return status;
}
}
}

View File

@ -1,29 +1,28 @@

using UnityEngine;
using UnityEngine;
namespace YooAsset
{
internal sealed class CompletedDownloader : DownloaderBase
{
public CompletedDownloader(BundleInfo bundleInfo) : base(bundleInfo, null, 0, 0)
{
DownloadProgress = 1f;
DownloadedBytes = (ulong)bundleInfo.Bundle.FileSize;
_status = EStatus.Succeed;
}
internal sealed class CompletedDownloader : DownloaderBase
{
public CompletedDownloader(BundleInfo bundleInfo) : base(bundleInfo, null, 0, 0)
{
DownloadProgress = 1f;
DownloadedBytes = (ulong)bundleInfo.Bundle.FileSize;
_status = EStatus.Succeed;
}
public override void SendRequest(params object[] param)
{
}
public override void Update()
{
}
public override void Abort()
{
}
public override AssetBundle GetAssetBundle()
{
throw new System.NotImplementedException();
}
}
public override void SendRequest(params object[] param)
{
}
public override void Update()
{
}
public override void Abort()
{
}
public override AssetBundle GetAssetBundle()
{
throw new System.NotImplementedException();
}
}
}

View File

@ -4,179 +4,179 @@ using UnityEngine.Networking;
namespace YooAsset
{
internal abstract class DownloaderBase
{
public enum EStatus
{
None = 0,
Succeed,
Failed
}
internal abstract class DownloaderBase
{
public enum EStatus
{
None = 0,
Succeed,
Failed
}
protected readonly BundleInfo _bundleInfo;
protected readonly System.Type _requesterType;
protected readonly int _timeout;
protected int _failedTryAgain;
protected readonly BundleInfo _bundleInfo;
protected readonly System.Type _requesterType;
protected readonly int _timeout;
protected int _failedTryAgain;
protected IWebRequester _requester;
protected EStatus _status = EStatus.None;
protected string _lastestNetError = string.Empty;
protected long _lastestHttpCode = 0;
protected IWebRequester _requester;
protected EStatus _status = EStatus.None;
protected string _lastestNetError = string.Empty;
protected long _lastestHttpCode = 0;
// 请求次数
protected int _requestCount = 0;
protected string _requestURL;
// 请求次数
protected int _requestCount = 0;
protected string _requestURL;
// 超时相关
protected bool _isAbort = false;
protected ulong _latestDownloadBytes;
protected float _latestDownloadRealtime;
protected float _tryAgainTimer;
// 超时相关
protected bool _isAbort = false;
protected ulong _latestDownloadBytes;
protected float _latestDownloadRealtime;
protected float _tryAgainTimer;
/// <summary>
/// 是否等待异步结束
/// 警告只能用于解压APP内部资源
/// </summary>
public bool WaitForAsyncComplete = false;
/// <summary>
/// 是否等待异步结束
/// 警告只能用于解压APP内部资源
/// </summary>
public bool WaitForAsyncComplete = false;
/// <summary>
/// 下载进度0f~1f
/// </summary>
public float DownloadProgress { protected set; get; }
/// <summary>
/// 下载进度0f~1f
/// </summary>
public float DownloadProgress { protected set; get; }
/// <summary>
/// 已经下载的总字节数
/// </summary>
public ulong DownloadedBytes { protected set; get; }
/// <summary>
/// 已经下载的总字节数
/// </summary>
public ulong DownloadedBytes { protected set; get; }
/// <summary>
/// 引用计数
/// </summary>
public int RefCount { private set; get; }
/// <summary>
/// 引用计数
/// </summary>
public int RefCount { private set; get; }
public DownloaderBase(BundleInfo bundleInfo, System.Type requesterType, int failedTryAgain, int timeout)
{
_bundleInfo = bundleInfo;
_requesterType = requesterType;
_failedTryAgain = failedTryAgain;
_timeout = timeout;
}
public abstract void SendRequest(params object[] args);
public abstract void Update();
public abstract void Abort();
public abstract AssetBundle GetAssetBundle();
public DownloaderBase(BundleInfo bundleInfo, System.Type requesterType, int failedTryAgain, int timeout)
{
_bundleInfo = bundleInfo;
_requesterType = requesterType;
_failedTryAgain = failedTryAgain;
_timeout = timeout;
}
public abstract void SendRequest(params object[] args);
public abstract void Update();
public abstract void Abort();
public abstract AssetBundle GetAssetBundle();
/// <summary>
/// 引用(引用计数递加)
/// </summary>
public void Reference()
{
RefCount++;
}
/// <summary>
/// 引用(引用计数递加)
/// </summary>
public void Reference()
{
RefCount++;
}
/// <summary>
/// 释放(引用计数递减)
/// </summary>
public void Release()
{
RefCount--;
}
/// <summary>
/// 释放(引用计数递减)
/// </summary>
public void Release()
{
RefCount--;
}
/// <summary>
/// 检测下载器是否已经完成(无论成功或失败)
/// </summary>
public bool IsDone()
{
return _status == EStatus.Succeed || _status == EStatus.Failed;
}
/// <summary>
/// 检测下载器是否已经完成(无论成功或失败)
/// </summary>
public bool IsDone()
{
return _status == EStatus.Succeed || _status == EStatus.Failed;
}
/// <summary>
/// 下载过程是否发生错误
/// </summary>
public bool HasError()
{
return _status == EStatus.Failed;
}
/// <summary>
/// 下载过程是否发生错误
/// </summary>
public bool HasError()
{
return _status == EStatus.Failed;
}
/// <summary>
/// 按照错误级别打印错误
/// </summary>
public void ReportError()
{
YooLogger.Error(GetLastError());
}
/// <summary>
/// 按照错误级别打印错误
/// </summary>
public void ReportError()
{
YooLogger.Error(GetLastError());
}
/// <summary>
/// 按照警告级别打印错误
/// </summary>
public void ReportWarning()
{
YooLogger.Warning(GetLastError());
}
/// <summary>
/// 按照警告级别打印错误
/// </summary>
public void ReportWarning()
{
YooLogger.Warning(GetLastError());
}
/// <summary>
/// 获取最近发生的错误信息
/// </summary>
public string GetLastError()
{
return $"Failed to download : {_requestURL} Error : {_lastestNetError} Code : {_lastestHttpCode}";
}
/// <summary>
/// 获取最近发生的错误信息
/// </summary>
public string GetLastError()
{
return $"Failed to download : {_requestURL} Error : {_lastestNetError} Code : {_lastestHttpCode}";
}
/// <summary>
/// 获取下载文件的大小
/// </summary>
/// <returns></returns>
public long GetDownloadFileSize()
{
return _bundleInfo.Bundle.FileSize;
}
/// <summary>
/// 获取下载文件的大小
/// </summary>
/// <returns></returns>
public long GetDownloadFileSize()
{
return _bundleInfo.Bundle.FileSize;
}
/// <summary>
/// 获取下载的资源包名称
/// </summary>
public string GetDownloadBundleName()
{
return _bundleInfo.Bundle.BundleName;
}
/// <summary>
/// 获取下载的资源包名称
/// </summary>
public string GetDownloadBundleName()
{
return _bundleInfo.Bundle.BundleName;
}
/// <summary>
/// 获取网络请求地址
/// </summary>
protected string GetRequestURL()
{
// 轮流返回请求地址
_requestCount++;
if (_requestCount % 2 == 0)
return _bundleInfo.RemoteFallbackURL;
else
return _bundleInfo.RemoteMainURL;
}
/// <summary>
/// 获取网络请求地址
/// </summary>
protected string GetRequestURL()
{
// 轮流返回请求地址
_requestCount++;
if (_requestCount % 2 == 0)
return _bundleInfo.RemoteFallbackURL;
else
return _bundleInfo.RemoteMainURL;
}
/// <summary>
/// 超时判定方法
/// </summary>
protected void CheckTimeout()
{
// 注意:在连续时间段内无新增下载数据及判定为超时
if (_isAbort == false)
{
if (_latestDownloadBytes != DownloadedBytes)
{
_latestDownloadBytes = DownloadedBytes;
_latestDownloadRealtime = Time.realtimeSinceStartup;
}
/// <summary>
/// 超时判定方法
/// </summary>
protected void CheckTimeout()
{
// 注意:在连续时间段内无新增下载数据及判定为超时
if (_isAbort == false)
{
if (_latestDownloadBytes != DownloadedBytes)
{
_latestDownloadBytes = DownloadedBytes;
_latestDownloadRealtime = Time.realtimeSinceStartup;
}
float offset = Time.realtimeSinceStartup - _latestDownloadRealtime;
if (offset > _timeout)
{
YooLogger.Warning($"Web file request timeout : {_requestURL}");
if(_requester != null)
_requester.Abort();
_isAbort = true;
}
}
}
}
float offset = Time.realtimeSinceStartup - _latestDownloadRealtime;
if (offset > _timeout)
{
YooLogger.Warning($"Web file request timeout : {_requestURL}");
if (_requester != null)
_requester.Abort();
_isAbort = true;
}
}
}
}
}

View File

@ -6,211 +6,211 @@ using UnityEngine;
namespace YooAsset
{
/// <summary>
/// 文件下载器
/// </summary>
internal sealed class FileDownloader : DownloaderBase
{
private enum ESteps
{
None,
PrepareDownload,
CreateDownloader,
CheckDownload,
VerifyTempFile,
WaitingVerifyTempFile,
CachingFile,
TryAgain,
Done,
}
/// <summary>
/// 文件下载器
/// </summary>
internal sealed class FileDownloader : DownloaderBase
{
private enum ESteps
{
None,
PrepareDownload,
CreateDownloader,
CheckDownload,
VerifyTempFile,
WaitingVerifyTempFile,
CachingFile,
TryAgain,
Done,
}
private VerifyTempFileOperation _verifyFileOp = null;
private ESteps _steps = ESteps.None;
private VerifyTempFileOperation _verifyFileOp = null;
private ESteps _steps = ESteps.None;
public FileDownloader(BundleInfo bundleInfo, System.Type requesterType, int failedTryAgain, int timeout) : base(bundleInfo, requesterType, failedTryAgain, timeout)
{
}
public override void SendRequest(params object[] args)
{
if (_steps == ESteps.None)
{
_steps = ESteps.PrepareDownload;
}
}
public override void Update()
{
if (_steps == ESteps.None)
return;
if (IsDone())
return;
public FileDownloader(BundleInfo bundleInfo, System.Type requesterType, int failedTryAgain, int timeout) : base(bundleInfo, requesterType, failedTryAgain, timeout)
{
}
public override void SendRequest(params object[] args)
{
if (_steps == ESteps.None)
{
_steps = ESteps.PrepareDownload;
}
}
public override void Update()
{
if (_steps == ESteps.None)
return;
if (IsDone())
return;
// 准备下载
if (_steps == ESteps.PrepareDownload)
{
// 获取请求地址
_requestURL = GetRequestURL();
// 准备下载
if (_steps == ESteps.PrepareDownload)
{
// 获取请求地址
_requestURL = GetRequestURL();
// 重置变量
DownloadProgress = 0f;
DownloadedBytes = 0;
// 重置变量
DownloadProgress = 0f;
DownloadedBytes = 0;
// 重置变量
_isAbort = false;
_latestDownloadBytes = 0;
_latestDownloadRealtime = Time.realtimeSinceStartup;
// 重置变量
_isAbort = false;
_latestDownloadBytes = 0;
_latestDownloadRealtime = Time.realtimeSinceStartup;
// 重置计时器
if (_tryAgainTimer > 0f)
YooLogger.Warning($"Try again download : {_requestURL}");
_tryAgainTimer = 0f;
// 重置计时器
if (_tryAgainTimer > 0f)
YooLogger.Warning($"Try again download : {_requestURL}");
_tryAgainTimer = 0f;
_steps = ESteps.CreateDownloader;
}
_steps = ESteps.CreateDownloader;
}
// 创建下载器
if (_steps == ESteps.CreateDownloader)
{
_requester = (IWebRequester)Activator.CreateInstance(_requesterType);
_requester.Create(_requestURL, _bundleInfo);
_steps = ESteps.CheckDownload;
}
// 创建下载器
if (_steps == ESteps.CreateDownloader)
{
_requester = (IWebRequester)Activator.CreateInstance(_requesterType);
_requester.Create(_requestURL, _bundleInfo);
_steps = ESteps.CheckDownload;
}
// 检测下载结果
if (_steps == ESteps.CheckDownload)
{
_requester.Update();
DownloadedBytes = _requester.DownloadedBytes;
DownloadProgress = _requester.DownloadProgress;
if (_requester.IsDone() == false)
{
CheckTimeout();
return;
}
// 检测下载结果
if (_steps == ESteps.CheckDownload)
{
_requester.Update();
DownloadedBytes = _requester.DownloadedBytes;
DownloadProgress = _requester.DownloadProgress;
if (_requester.IsDone() == false)
{
CheckTimeout();
return;
}
_lastestNetError = _requester.RequestNetError;
_lastestHttpCode = _requester.RequestHttpCode;
if (_requester.Status != ERequestStatus.Success)
{
_steps = ESteps.TryAgain;
}
else
{
_steps = ESteps.VerifyTempFile;
}
}
_lastestNetError = _requester.RequestNetError;
_lastestHttpCode = _requester.RequestHttpCode;
if (_requester.Status != ERequestStatus.Success)
{
_steps = ESteps.TryAgain;
}
else
{
_steps = ESteps.VerifyTempFile;
}
}
// 验证下载文件
if (_steps == ESteps.VerifyTempFile)
{
VerifyTempFileElement element = new VerifyTempFileElement(_bundleInfo.TempDataFilePath, _bundleInfo.Bundle.FileCRC, _bundleInfo.Bundle.FileSize);
_verifyFileOp = VerifyTempFileOperation.CreateOperation(element);
OperationSystem.StartOperation(_bundleInfo.Bundle.PackageName, _verifyFileOp);
_steps = ESteps.WaitingVerifyTempFile;
}
// 验证下载文件
if (_steps == ESteps.VerifyTempFile)
{
VerifyTempFileElement element = new VerifyTempFileElement(_bundleInfo.TempDataFilePath, _bundleInfo.Bundle.FileCRC, _bundleInfo.Bundle.FileSize);
_verifyFileOp = VerifyTempFileOperation.CreateOperation(element);
OperationSystem.StartOperation(_bundleInfo.Bundle.PackageName, _verifyFileOp);
_steps = ESteps.WaitingVerifyTempFile;
}
// 等待验证完成
if (_steps == ESteps.WaitingVerifyTempFile)
{
if (WaitForAsyncComplete)
_verifyFileOp.InternalOnUpdate();
// 等待验证完成
if (_steps == ESteps.WaitingVerifyTempFile)
{
if (WaitForAsyncComplete)
_verifyFileOp.InternalOnUpdate();
if (_verifyFileOp.IsDone == false)
return;
if (_verifyFileOp.IsDone == false)
return;
if (_verifyFileOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.CachingFile;
}
else
{
string tempFilePath = _bundleInfo.TempDataFilePath;
if (File.Exists(tempFilePath))
File.Delete(tempFilePath);
if (_verifyFileOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.CachingFile;
}
else
{
string tempFilePath = _bundleInfo.TempDataFilePath;
if (File.Exists(tempFilePath))
File.Delete(tempFilePath);
_lastestNetError = _verifyFileOp.Error;
_steps = ESteps.TryAgain;
}
}
_lastestNetError = _verifyFileOp.Error;
_steps = ESteps.TryAgain;
}
}
// 缓存下载文件
if (_steps == ESteps.CachingFile)
{
try
{
CachingFile();
_status = EStatus.Succeed;
_steps = ESteps.Done;
}
catch (Exception e)
{
_lastestNetError = e.Message;
_steps = ESteps.TryAgain;
}
}
// 缓存下载文件
if (_steps == ESteps.CachingFile)
{
try
{
CachingFile();
_status = EStatus.Succeed;
_steps = ESteps.Done;
}
catch (Exception e)
{
_lastestNetError = e.Message;
_steps = ESteps.TryAgain;
}
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
if (_failedTryAgain <= 0)
{
ReportError();
_status = EStatus.Failed;
_steps = ESteps.Done;
return;
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
if (_failedTryAgain <= 0)
{
ReportError();
_status = EStatus.Failed;
_steps = ESteps.Done;
return;
}
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
_failedTryAgain--;
_steps = ESteps.PrepareDownload;
ReportWarning();
}
}
}
public override void Abort()
{
if (_requester != null)
_requester.Abort();
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
_failedTryAgain--;
_steps = ESteps.PrepareDownload;
ReportWarning();
}
}
}
public override void Abort()
{
if (_requester != null)
_requester.Abort();
if (IsDone() == false)
{
_status = EStatus.Failed;
_steps = ESteps.Done;
_lastestNetError = "user abort";
_lastestHttpCode = 0;
}
}
public override AssetBundle GetAssetBundle()
{
throw new NotImplementedException();
}
if (IsDone() == false)
{
_status = EStatus.Failed;
_steps = ESteps.Done;
_lastestNetError = "user abort";
_lastestHttpCode = 0;
}
}
public override AssetBundle GetAssetBundle()
{
throw new NotImplementedException();
}
/// <summary>
/// 缓存下载文件
/// </summary>
private void CachingFile()
{
string tempFilePath = _bundleInfo.TempDataFilePath;
string infoFilePath = _bundleInfo.CachedInfoFilePath;
string dataFilePath = _bundleInfo.CachedDataFilePath;
string dataFileCRC = _bundleInfo.Bundle.FileCRC;
long dataFileSize = _bundleInfo.Bundle.FileSize;
/// <summary>
/// 缓存下载文件
/// </summary>
private void CachingFile()
{
string tempFilePath = _bundleInfo.TempDataFilePath;
string infoFilePath = _bundleInfo.CachedInfoFilePath;
string dataFilePath = _bundleInfo.CachedDataFilePath;
string dataFileCRC = _bundleInfo.Bundle.FileCRC;
long dataFileSize = _bundleInfo.Bundle.FileSize;
if (File.Exists(infoFilePath))
File.Delete(infoFilePath);
if (File.Exists(dataFilePath))
File.Delete(dataFilePath);
if (File.Exists(infoFilePath))
File.Delete(infoFilePath);
if (File.Exists(dataFilePath))
File.Delete(dataFilePath);
// 移动临时文件路径
FileInfo fileInfo = new FileInfo(tempFilePath);
fileInfo.MoveTo(dataFilePath);
// 移动临时文件路径
FileInfo fileInfo = new FileInfo(tempFilePath);
fileInfo.MoveTo(dataFilePath);
// 写入信息文件记录验证数据
CacheFileInfo.WriteInfoToFile(infoFilePath, dataFileCRC, dataFileSize);
// 写入信息文件记录验证数据
CacheFileInfo.WriteInfoToFile(infoFilePath, dataFileCRC, dataFileSize);
// 记录缓存文件
_bundleInfo.CacheRecord();
}
}
// 记录缓存文件
_bundleInfo.CacheRecord();
}
}
}

View File

@ -6,135 +6,135 @@ using UnityEngine;
namespace YooAsset
{
internal sealed class WebDownloader : DownloaderBase
{
private enum ESteps
{
None,
PrepareDownload,
CreateDownloader,
CheckDownload,
TryAgain,
Done,
}
internal sealed class WebDownloader : DownloaderBase
{
private enum ESteps
{
None,
PrepareDownload,
CreateDownloader,
CheckDownload,
TryAgain,
Done,
}
private ESteps _steps = ESteps.None;
private bool _getAssetBundle = false;
private ESteps _steps = ESteps.None;
private bool _getAssetBundle = false;
public WebDownloader(BundleInfo bundleInfo, System.Type requesterType, int failedTryAgain, int timeout) : base(bundleInfo, requesterType, failedTryAgain, timeout)
{
}
public override void SendRequest(params object[] args)
{
if (_steps == ESteps.None)
{
if (args.Length > 0)
{
_getAssetBundle = (bool)args[0];
}
_steps = ESteps.PrepareDownload;
}
}
public override void Update()
{
if (_steps == ESteps.None)
return;
if (IsDone())
return;
public WebDownloader(BundleInfo bundleInfo, System.Type requesterType, int failedTryAgain, int timeout) : base(bundleInfo, requesterType, failedTryAgain, timeout)
{
}
public override void SendRequest(params object[] args)
{
if (_steps == ESteps.None)
{
if (args.Length > 0)
{
_getAssetBundle = (bool)args[0];
}
_steps = ESteps.PrepareDownload;
}
}
public override void Update()
{
if (_steps == ESteps.None)
return;
if (IsDone())
return;
// 创建下载器
if (_steps == ESteps.PrepareDownload)
{
// 获取请求地址
_requestURL = GetRequestURL();
// 创建下载器
if (_steps == ESteps.PrepareDownload)
{
// 获取请求地址
_requestURL = GetRequestURL();
// 重置变量
DownloadProgress = 0f;
DownloadedBytes = 0;
// 重置变量
DownloadProgress = 0f;
DownloadedBytes = 0;
// 重置变量
_isAbort = false;
_latestDownloadBytes = 0;
_latestDownloadRealtime = Time.realtimeSinceStartup;
// 重置变量
_isAbort = false;
_latestDownloadBytes = 0;
_latestDownloadRealtime = Time.realtimeSinceStartup;
// 重置计时器
if (_tryAgainTimer > 0f)
YooLogger.Warning($"Try again download : {_requestURL}");
_tryAgainTimer = 0f;
// 重置计时器
if (_tryAgainTimer > 0f)
YooLogger.Warning($"Try again download : {_requestURL}");
_tryAgainTimer = 0f;
_steps = ESteps.CreateDownloader;
}
_steps = ESteps.CreateDownloader;
}
// 创建下载器
if (_steps == ESteps.CreateDownloader)
{
_requester = (IWebRequester)Activator.CreateInstance(_requesterType);
_requester.Create(_requestURL, _bundleInfo, _getAssetBundle);
_steps = ESteps.CheckDownload;
}
// 创建下载器
if (_steps == ESteps.CreateDownloader)
{
_requester = (IWebRequester)Activator.CreateInstance(_requesterType);
_requester.Create(_requestURL, _bundleInfo, _getAssetBundle);
_steps = ESteps.CheckDownload;
}
// 检测下载结果
if (_steps == ESteps.CheckDownload)
{
_requester.Update();
DownloadedBytes = _requester.DownloadedBytes;
DownloadProgress = _requester.DownloadProgress;
if (_requester.IsDone() == false)
{
CheckTimeout();
return;
}
// 检测下载结果
if (_steps == ESteps.CheckDownload)
{
_requester.Update();
DownloadedBytes = _requester.DownloadedBytes;
DownloadProgress = _requester.DownloadProgress;
if (_requester.IsDone() == false)
{
CheckTimeout();
return;
}
_lastestNetError = _requester.RequestNetError;
_lastestHttpCode = _requester.RequestHttpCode;
if (_requester.Status != ERequestStatus.Success)
{
_steps = ESteps.TryAgain;
}
else
{
_status = EStatus.Succeed;
_steps = ESteps.Done;
}
}
_lastestNetError = _requester.RequestNetError;
_lastestHttpCode = _requester.RequestHttpCode;
if (_requester.Status != ERequestStatus.Success)
{
_steps = ESteps.TryAgain;
}
else
{
_status = EStatus.Succeed;
_steps = ESteps.Done;
}
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
if (_failedTryAgain <= 0)
{
ReportError();
_status = EStatus.Failed;
_steps = ESteps.Done;
return;
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
if (_failedTryAgain <= 0)
{
ReportError();
_status = EStatus.Failed;
_steps = ESteps.Done;
return;
}
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
_failedTryAgain--;
_steps = ESteps.PrepareDownload;
ReportWarning();
YooLogger.Warning($"Try again download : {_requestURL}");
}
}
}
public override void Abort()
{
if (_requester != null)
_requester.Abort();
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
_failedTryAgain--;
_steps = ESteps.PrepareDownload;
ReportWarning();
YooLogger.Warning($"Try again download : {_requestURL}");
}
}
}
public override void Abort()
{
if (_requester != null)
_requester.Abort();
if (IsDone() == false)
{
_status = EStatus.Failed;
_steps = ESteps.Done;
_lastestNetError = "user abort";
_lastestHttpCode = 0;
}
}
public override AssetBundle GetAssetBundle()
{
return (AssetBundle)_requester.GetRequestObject();
}
}
if (IsDone() == false)
{
_status = EStatus.Failed;
_steps = ESteps.Done;
_lastestNetError = "user abort";
_lastestHttpCode = 0;
}
}
public override AssetBundle GetAssetBundle()
{
return (AssetBundle)_requester.GetRequestObject();
}
}
}

View File

@ -4,33 +4,33 @@ using System.Collections.Generic;
namespace YooAsset
{
public class RequestHelper
{
/// <summary>
/// 记录网络请求失败事件的次数
/// </summary>
private static readonly Dictionary<string, int> _requestFailedRecorder = new Dictionary<string, int>(1000);
public class RequestHelper
{
/// <summary>
/// 记录网络请求失败事件的次数
/// </summary>
private static readonly Dictionary<string, int> _requestFailedRecorder = new Dictionary<string, int>(1000);
/// <summary>
/// 记录请求失败事件
/// </summary>
public static void RecordRequestFailed(string packageName, string eventName)
{
string key = $"{packageName}_{eventName}";
if (_requestFailedRecorder.ContainsKey(key) == false)
_requestFailedRecorder.Add(key, 0);
_requestFailedRecorder[key]++;
}
/// <summary>
/// 记录请求失败事件
/// </summary>
public static void RecordRequestFailed(string packageName, string eventName)
{
string key = $"{packageName}_{eventName}";
if (_requestFailedRecorder.ContainsKey(key) == false)
_requestFailedRecorder.Add(key, 0);
_requestFailedRecorder[key]++;
}
/// <summary>
/// 获取请求失败的次数
/// </summary>
public static int GetRequestFailedCount(string packageName, string eventName)
{
string key = $"{packageName}_{eventName}";
if (_requestFailedRecorder.ContainsKey(key) == false)
_requestFailedRecorder.Add(key, 0);
return _requestFailedRecorder[key];
}
}
/// <summary>
/// 获取请求失败的次数
/// </summary>
public static int GetRequestFailedCount(string packageName, string eventName)
{
string key = $"{packageName}_{eventName}";
if (_requestFailedRecorder.ContainsKey(key) == false)
_requestFailedRecorder.Add(key, 0);
return _requestFailedRecorder[key];
}
}
}

View File

@ -4,76 +4,76 @@ using UnityEngine.Networking;
namespace YooAsset
{
internal class AssetBundleWebRequest : IWebRequester
{
private UnityWebRequest _webRequest;
private DownloadHandlerAssetBundle _downloadhandler;
private AssetBundle _cacheAssetBundle;
private bool _getAssetBundle = false;
internal class AssetBundleWebRequest : IWebRequester
{
private UnityWebRequest _webRequest;
private DownloadHandlerAssetBundle _downloadhandler;
private AssetBundle _cacheAssetBundle;
private bool _getAssetBundle = false;
public ERequestStatus Status { private set; get; } = ERequestStatus.None;
public float DownloadProgress { private set; get; }
public ulong DownloadedBytes { private set; get; }
public string RequestNetError { private set; get; }
public long RequestHttpCode { private set; get; }
public ERequestStatus Status { private set; get; } = ERequestStatus.None;
public float DownloadProgress { private set; get; }
public ulong DownloadedBytes { private set; get; }
public string RequestNetError { private set; get; }
public long RequestHttpCode { private set; get; }
public AssetBundleWebRequest() { }
public void Create(string requestURL, BundleInfo bundleInfo, params object[] args)
{
if (Status != ERequestStatus.None)
throw new System.Exception("Should never get here !");
public AssetBundleWebRequest() { }
public void Create(string requestURL, BundleInfo bundleInfo, params object[] args)
{
if (Status != ERequestStatus.None)
throw new System.Exception("Should never get here !");
if (args.Length == 0)
throw new System.Exception("Not found param value");
if (args.Length == 0)
throw new System.Exception("Not found param value");
// 解析附加参数
_getAssetBundle = (bool)args[0];
// 解析附加参数
_getAssetBundle = (bool)args[0];
// 创建下载器
_webRequest = DownloadHelper.NewRequest(requestURL);
if (CacheHelper.DisableUnityCacheOnWebGL)
{
uint crc = bundleInfo.Bundle.UnityCRC;
_downloadhandler = new DownloadHandlerAssetBundle(requestURL, crc);
}
else
{
uint crc = bundleInfo.Bundle.UnityCRC;
var hash = Hash128.Parse(bundleInfo.Bundle.FileHash);
_downloadhandler = new DownloadHandlerAssetBundle(requestURL, hash, crc);
}
// 创建下载器
_webRequest = DownloadHelper.NewRequest(requestURL);
if (CacheHelper.DisableUnityCacheOnWebGL)
{
uint crc = bundleInfo.Bundle.UnityCRC;
_downloadhandler = new DownloadHandlerAssetBundle(requestURL, crc);
}
else
{
uint crc = bundleInfo.Bundle.UnityCRC;
var hash = Hash128.Parse(bundleInfo.Bundle.FileHash);
_downloadhandler = new DownloadHandlerAssetBundle(requestURL, hash, crc);
}
#if UNITY_2020_3_OR_NEWER
_downloadhandler.autoLoadAssetBundle = false;
_downloadhandler.autoLoadAssetBundle = false;
#endif
_webRequest.downloadHandler = _downloadhandler;
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
Status = ERequestStatus.InProgress;
}
public void Update()
{
if (Status == ERequestStatus.None)
return;
if (IsDone())
return;
_webRequest.downloadHandler = _downloadhandler;
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
Status = ERequestStatus.InProgress;
}
public void Update()
{
if (Status == ERequestStatus.None)
return;
if (IsDone())
return;
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = _webRequest.downloadedBytes;
if (_webRequest.isDone == false)
return;
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = _webRequest.downloadedBytes;
if (_webRequest.isDone == false)
return;
// 检查网络错误
// 检查网络错误
#if UNITY_2020_3_OR_NEWER
RequestHttpCode = _webRequest.responseCode;
if (_webRequest.result != UnityWebRequest.Result.Success)
{
RequestNetError = _webRequest.error;
Status = ERequestStatus.Error;
}
else
{
Status = ERequestStatus.Success;
}
RequestHttpCode = _webRequest.responseCode;
if (_webRequest.result != UnityWebRequest.Result.Success)
{
RequestNetError = _webRequest.error;
Status = ERequestStatus.Error;
}
else
{
Status = ERequestStatus.Success;
}
#else
RequestHttpCode = _webRequest.responseCode;
if (_webRequest.isNetworkError || _webRequest.isHttpError)
@ -87,59 +87,59 @@ namespace YooAsset
}
#endif
// 缓存加载的AssetBundle对象
if (Status == ERequestStatus.Success)
{
if (_getAssetBundle)
{
_cacheAssetBundle = _downloadhandler.assetBundle;
if (_cacheAssetBundle == null)
{
RequestNetError = "assetBundle is null";
Status = ERequestStatus.Error;
}
}
}
// 缓存加载的AssetBundle对象
if (Status == ERequestStatus.Success)
{
if (_getAssetBundle)
{
_cacheAssetBundle = _downloadhandler.assetBundle;
if (_cacheAssetBundle == null)
{
RequestNetError = "assetBundle is null";
Status = ERequestStatus.Error;
}
}
}
// 最终释放下载器
DisposeWebRequest();
}
public void Abort()
{
// 如果下载任务还未开始
if (Status == ERequestStatus.None)
{
RequestNetError = "user cancel";
Status = ERequestStatus.Error;
}
else
{
// 注意:为了防止同一个文件强制停止之后立马创建新的请求,应该让进行中的请求自然终止。
if (_webRequest != null)
{
if (_webRequest.isDone == false)
_webRequest.Abort(); // If in progress, halts the UnityWebRequest as soon as possible.
}
}
}
public bool IsDone()
{
if (Status == ERequestStatus.Success || Status == ERequestStatus.Error)
return true;
else
return false;
}
public object GetRequestObject()
{
return _cacheAssetBundle;
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
_webRequest.Dispose();
_webRequest = null;
}
}
}
// 最终释放下载器
DisposeWebRequest();
}
public void Abort()
{
// 如果下载任务还未开始
if (Status == ERequestStatus.None)
{
RequestNetError = "user cancel";
Status = ERequestStatus.Error;
}
else
{
// 注意:为了防止同一个文件强制停止之后立马创建新的请求,应该让进行中的请求自然终止。
if (_webRequest != null)
{
if (_webRequest.isDone == false)
_webRequest.Abort(); // If in progress, halts the UnityWebRequest as soon as possible.
}
}
}
public bool IsDone()
{
if (Status == ERequestStatus.Success || Status == ERequestStatus.Error)
return true;
else
return false;
}
public object GetRequestObject()
{
return _cacheAssetBundle;
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
_webRequest.Dispose();
_webRequest = null;
}
}
}
}

View File

@ -5,83 +5,83 @@ using UnityEngine.Networking;
namespace YooAsset
{
/// <summary>
/// 支持Unity2018版本的断点续传下载器
/// </summary>
internal class DownloadHandlerFileRange : DownloadHandlerScript
{
private string _fileSavePath;
private long _fileTotalSize;
private UnityWebRequest _webRequest;
private FileStream _fileStream;
/// <summary>
/// 支持Unity2018版本的断点续传下载器
/// </summary>
internal class DownloadHandlerFileRange : DownloadHandlerScript
{
private string _fileSavePath;
private long _fileTotalSize;
private UnityWebRequest _webRequest;
private FileStream _fileStream;
private long _localFileSize = 0;
private long _curFileSize = 0;
private long _localFileSize = 0;
private long _curFileSize = 0;
public DownloadHandlerFileRange(string fileSavePath, long fileTotalSize, UnityWebRequest webRequest) : base(new byte[1024 * 1024])
{
_fileSavePath = fileSavePath;
_fileTotalSize = fileTotalSize;
_webRequest = webRequest;
public DownloadHandlerFileRange(string fileSavePath, long fileTotalSize, UnityWebRequest webRequest) : base(new byte[1024 * 1024])
{
_fileSavePath = fileSavePath;
_fileTotalSize = fileTotalSize;
_webRequest = webRequest;
if (File.Exists(fileSavePath))
{
FileInfo fileInfo = new FileInfo(fileSavePath);
_localFileSize = fileInfo.Length;
}
if (File.Exists(fileSavePath))
{
FileInfo fileInfo = new FileInfo(fileSavePath);
_localFileSize = fileInfo.Length;
}
_fileStream = new FileStream(_fileSavePath, FileMode.Append, FileAccess.Write);
_curFileSize = _localFileSize;
}
protected override bool ReceiveData(byte[] data, int dataLength)
{
if (data == null || dataLength == 0 || _webRequest.responseCode >= 400)
return false;
_fileStream = new FileStream(_fileSavePath, FileMode.Append, FileAccess.Write);
_curFileSize = _localFileSize;
}
protected override bool ReceiveData(byte[] data, int dataLength)
{
if (data == null || dataLength == 0 || _webRequest.responseCode >= 400)
return false;
if (_fileStream == null)
return false;
if (_fileStream == null)
return false;
_fileStream.Write(data, 0, dataLength);
_curFileSize += dataLength;
return true;
}
_fileStream.Write(data, 0, dataLength);
_curFileSize += dataLength;
return true;
}
/// <summary>
/// UnityWebRequest.downloadHandler.data
/// </summary>
protected override byte[] GetData()
{
return null;
}
/// <summary>
/// UnityWebRequest.downloadHandler.data
/// </summary>
protected override byte[] GetData()
{
return null;
}
/// <summary>
/// UnityWebRequest.downloadHandler.text
/// </summary>
protected override string GetText()
{
return null;
}
/// <summary>
/// UnityWebRequest.downloadHandler.text
/// </summary>
protected override string GetText()
{
return null;
}
/// <summary>
/// UnityWebRequest.downloadProgress
/// </summary>
protected override float GetProgress()
{
return _fileTotalSize == 0 ? 0 : ((float)_curFileSize) / _fileTotalSize;
}
/// <summary>
/// UnityWebRequest.downloadProgress
/// </summary>
protected override float GetProgress()
{
return _fileTotalSize == 0 ? 0 : ((float)_curFileSize) / _fileTotalSize;
}
/// <summary>
/// 释放下载句柄
/// </summary>
public void Cleanup()
{
if (_fileStream != null)
{
_fileStream.Flush();
_fileStream.Dispose();
_fileStream = null;
}
}
}
/// <summary>
/// 释放下载句柄
/// </summary>
public void Cleanup()
{
if (_fileStream != null)
{
_fileStream.Flush();
_fileStream.Dispose();
_fileStream = null;
}
}
}
}

View File

@ -3,61 +3,61 @@ using UnityEngine.Networking;
namespace YooAsset
{
internal class FileGeneralRequest : IWebRequester
{
private UnityWebRequest _webRequest;
internal class FileGeneralRequest : IWebRequester
{
private UnityWebRequest _webRequest;
public ERequestStatus Status { private set; get; } = ERequestStatus.None;
public float DownloadProgress { private set; get; }
public ulong DownloadedBytes { private set; get; }
public string RequestNetError { private set; get; }
public long RequestHttpCode { private set; get; }
public ERequestStatus Status { private set; get; } = ERequestStatus.None;
public float DownloadProgress { private set; get; }
public ulong DownloadedBytes { private set; get; }
public string RequestNetError { private set; get; }
public long RequestHttpCode { private set; get; }
public FileGeneralRequest() { }
public void Create(string requestURL, BundleInfo bundleInfo, params object[] args)
{
if (Status != ERequestStatus.None)
throw new System.Exception("Should never get here !");
public FileGeneralRequest() { }
public void Create(string requestURL, BundleInfo bundleInfo, params object[] args)
{
if (Status != ERequestStatus.None)
throw new System.Exception("Should never get here !");
string tempFilePath = bundleInfo.TempDataFilePath;
string tempFilePath = bundleInfo.TempDataFilePath;
// 删除临时文件
if (File.Exists(tempFilePath))
File.Delete(tempFilePath);
// 删除临时文件
if (File.Exists(tempFilePath))
File.Delete(tempFilePath);
// 创建下载器
_webRequest = DownloadHelper.NewRequest(requestURL);
DownloadHandlerFile handler = new DownloadHandlerFile(tempFilePath);
handler.removeFileOnAbort = true;
_webRequest.downloadHandler = handler;
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
Status = ERequestStatus.InProgress;
}
public void Update()
{
if (Status == ERequestStatus.None)
return;
if (IsDone())
return;
// 创建下载器
_webRequest = DownloadHelper.NewRequest(requestURL);
DownloadHandlerFile handler = new DownloadHandlerFile(tempFilePath);
handler.removeFileOnAbort = true;
_webRequest.downloadHandler = handler;
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
Status = ERequestStatus.InProgress;
}
public void Update()
{
if (Status == ERequestStatus.None)
return;
if (IsDone())
return;
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = _webRequest.downloadedBytes;
if (_webRequest.isDone == false)
return;
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = _webRequest.downloadedBytes;
if (_webRequest.isDone == false)
return;
// 检查网络错误
// 检查网络错误
#if UNITY_2020_3_OR_NEWER
RequestHttpCode = _webRequest.responseCode;
if (_webRequest.result != UnityWebRequest.Result.Success)
{
RequestNetError = _webRequest.error;
Status = ERequestStatus.Error;
}
else
{
Status = ERequestStatus.Success;
}
RequestHttpCode = _webRequest.responseCode;
if (_webRequest.result != UnityWebRequest.Result.Success)
{
RequestNetError = _webRequest.error;
Status = ERequestStatus.Error;
}
else
{
Status = ERequestStatus.Success;
}
#else
RequestHttpCode = _webRequest.responseCode;
if (_webRequest.isNetworkError || _webRequest.isHttpError)
@ -71,37 +71,37 @@ namespace YooAsset
}
#endif
// 最终释放下载器
DisposeWebRequest();
}
public void Abort()
{
DisposeWebRequest();
if (IsDone() == false)
{
RequestNetError = "user abort";
RequestHttpCode = 0;
Status = ERequestStatus.Error;
}
}
public bool IsDone()
{
if (Status == ERequestStatus.Success || Status == ERequestStatus.Error)
return true;
else
return false;
}
public object GetRequestObject()
{
throw new System.NotImplementedException();
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
_webRequest.Dispose(); //注意引擎底层会自动调用Abort方法
_webRequest = null;
}
}
}
// 最终释放下载器
DisposeWebRequest();
}
public void Abort()
{
DisposeWebRequest();
if (IsDone() == false)
{
RequestNetError = "user abort";
RequestHttpCode = 0;
Status = ERequestStatus.Error;
}
}
public bool IsDone()
{
if (Status == ERequestStatus.Success || Status == ERequestStatus.Error)
return true;
else
return false;
}
public object GetRequestObject()
{
throw new System.NotImplementedException();
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
_webRequest.Dispose(); //注意引擎底层会自动调用Abort方法
_webRequest = null;
}
}
}
}

View File

@ -3,85 +3,85 @@ using UnityEngine.Networking;
namespace YooAsset
{
internal class FileResumeRequest : IWebRequester
{
private string _tempFilePath;
private UnityWebRequest _webRequest;
private DownloadHandlerFileRange _downloadHandle;
private ulong _fileOriginLength = 0;
internal class FileResumeRequest : IWebRequester
{
private string _tempFilePath;
private UnityWebRequest _webRequest;
private DownloadHandlerFileRange _downloadHandle;
private ulong _fileOriginLength = 0;
public ERequestStatus Status { private set; get; } = ERequestStatus.None;
public float DownloadProgress { private set; get; }
public ulong DownloadedBytes { private set; get; }
public string RequestNetError { private set; get; }
public long RequestHttpCode { private set; get; }
public ERequestStatus Status { private set; get; } = ERequestStatus.None;
public float DownloadProgress { private set; get; }
public ulong DownloadedBytes { private set; get; }
public string RequestNetError { private set; get; }
public long RequestHttpCode { private set; get; }
public FileResumeRequest() { }
public void Create(string requestURL, BundleInfo bundleInfo, params object[] args)
{
if (Status != ERequestStatus.None)
throw new System.Exception("Should never get here !");
public FileResumeRequest() { }
public void Create(string requestURL, BundleInfo bundleInfo, params object[] args)
{
if (Status != ERequestStatus.None)
throw new System.Exception("Should never get here !");
_tempFilePath = bundleInfo.TempDataFilePath;
long fileBytes = bundleInfo.Bundle.FileSize;
_tempFilePath = bundleInfo.TempDataFilePath;
long fileBytes = bundleInfo.Bundle.FileSize;
// 获取下载的起始位置
long fileLength = -1;
if (File.Exists(_tempFilePath))
{
FileInfo fileInfo = new FileInfo(_tempFilePath);
fileLength = fileInfo.Length;
_fileOriginLength = (ulong)fileLength;
DownloadedBytes = _fileOriginLength;
}
// 获取下载的起始位置
long fileLength = -1;
if (File.Exists(_tempFilePath))
{
FileInfo fileInfo = new FileInfo(_tempFilePath);
fileLength = fileInfo.Length;
_fileOriginLength = (ulong)fileLength;
DownloadedBytes = _fileOriginLength;
}
// 检测下载起始位置是否有效
if (fileLength >= fileBytes)
{
if (File.Exists(_tempFilePath))
File.Delete(_tempFilePath);
}
// 检测下载起始位置是否有效
if (fileLength >= fileBytes)
{
if (File.Exists(_tempFilePath))
File.Delete(_tempFilePath);
}
// 创建下载器
_webRequest = DownloadHelper.NewRequest(requestURL);
// 创建下载器
_webRequest = DownloadHelper.NewRequest(requestURL);
#if UNITY_2019_4_OR_NEWER
var handler = new DownloadHandlerFile(_tempFilePath, true);
handler.removeFileOnAbort = false;
var handler = new DownloadHandlerFile(_tempFilePath, true);
handler.removeFileOnAbort = false;
#else
var handler = new DownloadHandlerFileRange(tempFilePath, _bundleInfo.Bundle.FileSize, _webRequest);
_downloadHandle = handler;
#endif
_webRequest.downloadHandler = handler;
_webRequest.disposeDownloadHandlerOnDispose = true;
if (fileLength > 0)
_webRequest.SetRequestHeader("Range", $"bytes={fileLength}-");
_webRequest.SendWebRequest();
Status = ERequestStatus.InProgress;
}
public void Update()
{
if (Status == ERequestStatus.None)
return;
if (IsDone())
return;
_webRequest.downloadHandler = handler;
_webRequest.disposeDownloadHandlerOnDispose = true;
if (fileLength > 0)
_webRequest.SetRequestHeader("Range", $"bytes={fileLength}-");
_webRequest.SendWebRequest();
Status = ERequestStatus.InProgress;
}
public void Update()
{
if (Status == ERequestStatus.None)
return;
if (IsDone())
return;
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = _fileOriginLength + _webRequest.downloadedBytes;
if (_webRequest.isDone == false)
return;
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = _fileOriginLength + _webRequest.downloadedBytes;
if (_webRequest.isDone == false)
return;
// 检查网络错误
// 检查网络错误
#if UNITY_2020_3_OR_NEWER
RequestHttpCode = _webRequest.responseCode;
if (_webRequest.result != UnityWebRequest.Result.Success)
{
RequestNetError = _webRequest.error;
Status = ERequestStatus.Error;
}
else
{
Status = ERequestStatus.Success;
}
RequestHttpCode = _webRequest.responseCode;
if (_webRequest.result != UnityWebRequest.Result.Success)
{
RequestNetError = _webRequest.error;
Status = ERequestStatus.Error;
}
else
{
Status = ERequestStatus.Success;
}
#else
RequestHttpCode = _webRequest.responseCode;
if (_webRequest.isNetworkError || _webRequest.isHttpError)
@ -95,56 +95,56 @@ namespace YooAsset
}
#endif
// 注意:下载断点续传文件发生特殊错误码之后删除文件
if (Status == ERequestStatus.Error)
{
if (DownloadHelper.ClearFileResponseCodes != null)
{
if (DownloadHelper.ClearFileResponseCodes.Contains(RequestHttpCode))
{
if (File.Exists(_tempFilePath))
File.Delete(_tempFilePath);
}
}
}
// 注意:下载断点续传文件发生特殊错误码之后删除文件
if (Status == ERequestStatus.Error)
{
if (DownloadHelper.ClearFileResponseCodes != null)
{
if (DownloadHelper.ClearFileResponseCodes.Contains(RequestHttpCode))
{
if (File.Exists(_tempFilePath))
File.Delete(_tempFilePath);
}
}
}
// 最终释放下载器
DisposeWebRequest();
}
public void Abort()
{
DisposeWebRequest();
if (IsDone() == false)
{
RequestNetError = "user abort";
RequestHttpCode = 0;
Status = ERequestStatus.Error;
}
}
public bool IsDone()
{
if (Status == ERequestStatus.Success || Status == ERequestStatus.Error)
return true;
else
return false;
}
public object GetRequestObject()
{
throw new System.NotImplementedException();
}
private void DisposeWebRequest()
{
if (_downloadHandle != null)
{
_downloadHandle.Cleanup();
_downloadHandle = null;
}
// 最终释放下载器
DisposeWebRequest();
}
public void Abort()
{
DisposeWebRequest();
if (IsDone() == false)
{
RequestNetError = "user abort";
RequestHttpCode = 0;
Status = ERequestStatus.Error;
}
}
public bool IsDone()
{
if (Status == ERequestStatus.Success || Status == ERequestStatus.Error)
return true;
else
return false;
}
public object GetRequestObject()
{
throw new System.NotImplementedException();
}
private void DisposeWebRequest()
{
if (_downloadHandle != null)
{
_downloadHandle.Cleanup();
_downloadHandle = null;
}
if (_webRequest != null)
{
_webRequest.Dispose();
_webRequest = null;
}
}
}
if (_webRequest != null)
{
_webRequest.Dispose();
_webRequest = null;
}
}
}
}

View File

@ -1,65 +1,65 @@

namespace YooAsset
{
internal enum ERequestStatus
{
None,
InProgress,
Error,
Success,
}
internal enum ERequestStatus
{
None,
InProgress,
Error,
Success,
}
internal interface IWebRequester
{
/// <summary>
/// 任务状态
/// </summary>
public ERequestStatus Status { get; }
internal interface IWebRequester
{
/// <summary>
/// 任务状态
/// </summary>
public ERequestStatus Status { get; }
/// <summary>
/// 下载进度0f~1f
/// </summary>
public float DownloadProgress { get; }
/// <summary>
/// 下载进度0f~1f
/// </summary>
public float DownloadProgress { get; }
/// <summary>
/// 已经下载的总字节数
/// </summary>
public ulong DownloadedBytes { get; }
/// <summary>
/// 已经下载的总字节数
/// </summary>
public ulong DownloadedBytes { get; }
/// <summary>
/// 返回的网络错误
/// </summary>
public string RequestNetError { get; }
/// <summary>
/// 返回的网络错误
/// </summary>
public string RequestNetError { get; }
/// <summary>
/// 返回的HTTP CODE
/// </summary>
public long RequestHttpCode { get; }
/// <summary>
/// 返回的HTTP CODE
/// </summary>
public long RequestHttpCode { get; }
/// <summary>
/// 创建任务
/// </summary>
public void Create(string url, BundleInfo bundleInfo, params object[] args);
/// <summary>
/// 创建任务
/// </summary>
public void Create(string url, BundleInfo bundleInfo, params object[] args);
/// <summary>
/// 更新任务
/// </summary>
public void Update();
/// <summary>
/// 更新任务
/// </summary>
public void Update();
/// <summary>
/// 终止任务
/// </summary>
public void Abort();
/// <summary>
/// 终止任务
/// </summary>
public void Abort();
/// <summary>
/// 是否已经完成(无论成功或失败)
/// </summary>
public bool IsDone();
/// <summary>
/// 是否已经完成(无论成功或失败)
/// </summary>
public bool IsDone();
/// <summary>
/// 获取请求的对象
/// </summary>
public object GetRequestObject();
}
/// <summary>
/// 获取请求的对象
/// </summary>
public object GetRequestObject();
}
}

View File

@ -5,34 +5,34 @@ using System.Threading;
namespace YooAsset
{
/// <summary>
/// 同步其它线程里的回调到主线程里
/// 注意Unity3D中需要设置Scripting Runtime Version为.NET4.6
/// </summary>
internal sealed class ThreadSyncContext : SynchronizationContext
{
private readonly ConcurrentQueue<Action> _safeQueue = new ConcurrentQueue<Action>();
/// <summary>
/// 同步其它线程里的回调到主线程里
/// 注意Unity3D中需要设置Scripting Runtime Version为.NET4.6
/// </summary>
internal sealed class ThreadSyncContext : SynchronizationContext
{
private readonly ConcurrentQueue<Action> _safeQueue = new ConcurrentQueue<Action>();
/// <summary>
/// 更新同步队列
/// </summary>
public void Update()
{
while (true)
{
if (_safeQueue.TryDequeue(out Action action) == false)
return;
action.Invoke();
}
}
/// <summary>
/// 更新同步队列
/// </summary>
public void Update()
{
while (true)
{
if (_safeQueue.TryDequeue(out Action action) == false)
return;
action.Invoke();
}
}
/// <summary>
/// 向同步队列里投递一个回调方法
/// </summary>
public override void Post(SendOrPostCallback callback, object state)
{
Action action = new Action(() => { callback(state); });
_safeQueue.Enqueue(action);
}
}
/// <summary>
/// 向同步队列里投递一个回调方法
/// </summary>
public override void Post(SendOrPostCallback callback, object state)
{
Action action = new Action(() => { callback(state); });
_safeQueue.Enqueue(action);
}
}
}

View File

@ -6,46 +6,46 @@ using UnityEngine;
namespace YooAsset
{
internal class UnityWebDataRequester : UnityWebRequesterBase
{
/// <summary>
/// 发送GET请求
/// </summary>
public void SendRequest(string url, int timeout = 60)
{
if (_webRequest == null)
{
URL = url;
ResetTimeout(timeout);
internal class UnityWebDataRequester : UnityWebRequesterBase
{
/// <summary>
/// 发送GET请求
/// </summary>
public void SendRequest(string url, int timeout = 60)
{
if (_webRequest == null)
{
URL = url;
ResetTimeout(timeout);
_webRequest = DownloadHelper.NewRequest(URL);
DownloadHandlerBuffer handler = new DownloadHandlerBuffer();
_webRequest.downloadHandler = handler;
_webRequest.disposeDownloadHandlerOnDispose = true;
_operationHandle = _webRequest.SendWebRequest();
}
}
_webRequest = DownloadHelper.NewRequest(URL);
DownloadHandlerBuffer handler = new DownloadHandlerBuffer();
_webRequest.downloadHandler = handler;
_webRequest.disposeDownloadHandlerOnDispose = true;
_operationHandle = _webRequest.SendWebRequest();
}
}
/// <summary>
/// 获取下载的字节数据
/// </summary>
public byte[] GetData()
{
if (_webRequest != null && IsDone())
return _webRequest.downloadHandler.data;
else
return null;
}
/// <summary>
/// 获取下载的字节数据
/// </summary>
public byte[] GetData()
{
if (_webRequest != null && IsDone())
return _webRequest.downloadHandler.data;
else
return null;
}
/// <summary>
/// 获取下载的文本数据
/// </summary>
public string GetText()
{
if (_webRequest != null && IsDone())
return _webRequest.downloadHandler.text;
else
return null;
}
}
/// <summary>
/// 获取下载的文本数据
/// </summary>
public string GetText()
{
if (_webRequest != null && IsDone())
return _webRequest.downloadHandler.text;
else
return null;
}
}
}

View File

@ -6,25 +6,25 @@ using UnityEngine;
namespace YooAsset
{
internal class UnityWebFileRequester : UnityWebRequesterBase
{
/// <summary>
/// 发送GET请求
/// </summary>
public void SendRequest(string url, string fileSavePath, int timeout = 60)
{
if (_webRequest == null)
{
URL = url;
ResetTimeout(timeout);
internal class UnityWebFileRequester : UnityWebRequesterBase
{
/// <summary>
/// 发送GET请求
/// </summary>
public void SendRequest(string url, string fileSavePath, int timeout = 60)
{
if (_webRequest == null)
{
URL = url;
ResetTimeout(timeout);
_webRequest = DownloadHelper.NewRequest(URL);
DownloadHandlerFile handler = new DownloadHandlerFile(fileSavePath);
handler.removeFileOnAbort = true;
_webRequest.downloadHandler = handler;
_webRequest.disposeDownloadHandlerOnDispose = true;
_operationHandle = _webRequest.SendWebRequest();
}
}
}
_webRequest = DownloadHelper.NewRequest(URL);
DownloadHandlerFile handler = new DownloadHandlerFile(fileSavePath);
handler.removeFileOnAbort = true;
_webRequest.downloadHandler = handler;
_webRequest.disposeDownloadHandlerOnDispose = true;
_operationHandle = _webRequest.SendWebRequest();
}
}
}
}

View File

@ -6,111 +6,111 @@ using UnityEngine;
namespace YooAsset
{
internal abstract class UnityWebRequesterBase
{
protected UnityWebRequest _webRequest;
protected UnityWebRequestAsyncOperation _operationHandle;
internal abstract class UnityWebRequesterBase
{
protected UnityWebRequest _webRequest;
protected UnityWebRequestAsyncOperation _operationHandle;
// 超时相关
private float _timeout;
private bool _isAbort = false;
private ulong _latestDownloadBytes;
private float _latestDownloadRealtime;
// 超时相关
private float _timeout;
private bool _isAbort = false;
private ulong _latestDownloadBytes;
private float _latestDownloadRealtime;
/// <summary>
/// 请求URL地址
/// </summary>
public string URL { protected set; get; }
/// <summary>
/// 请求URL地址
/// </summary>
public string URL { protected set; get; }
protected void ResetTimeout(float timeout)
{
_timeout = timeout;
_latestDownloadBytes = 0;
_latestDownloadRealtime = Time.realtimeSinceStartup;
}
protected void ResetTimeout(float timeout)
{
_timeout = timeout;
_latestDownloadBytes = 0;
_latestDownloadRealtime = Time.realtimeSinceStartup;
}
/// <summary>
/// 释放下载器
/// </summary>
public void Dispose()
{
if (_webRequest != null)
{
_webRequest.Dispose();
_webRequest = null;
_operationHandle = null;
}
}
/// <summary>
/// 释放下载器
/// </summary>
public void Dispose()
{
if (_webRequest != null)
{
_webRequest.Dispose();
_webRequest = null;
_operationHandle = null;
}
}
/// <summary>
/// 是否完毕(无论成功失败)
/// </summary>
public bool IsDone()
{
if (_operationHandle == null)
return false;
return _operationHandle.isDone;
}
/// <summary>
/// 是否完毕(无论成功失败)
/// </summary>
public bool IsDone()
{
if (_operationHandle == null)
return false;
return _operationHandle.isDone;
}
/// <summary>
/// 下载进度
/// </summary>
public float Progress()
{
if (_operationHandle == null)
return 0;
return _operationHandle.progress;
}
/// <summary>
/// 下载进度
/// </summary>
public float Progress()
{
if (_operationHandle == null)
return 0;
return _operationHandle.progress;
}
/// <summary>
/// 下载是否发生错误
/// </summary>
public bool HasError()
{
/// <summary>
/// 下载是否发生错误
/// </summary>
public bool HasError()
{
#if UNITY_2020_3_OR_NEWER
return _webRequest.result != UnityWebRequest.Result.Success;
return _webRequest.result != UnityWebRequest.Result.Success;
#else
if (_webRequest.isNetworkError || _webRequest.isHttpError)
return true;
else
return false;
#endif
}
}
/// <summary>
/// 获取错误信息
/// </summary>
public string GetError()
{
if (_webRequest != null)
{
return $"URL : {URL} Error : {_webRequest.error}";
}
return string.Empty;
}
/// <summary>
/// 获取错误信息
/// </summary>
public string GetError()
{
if (_webRequest != null)
{
return $"URL : {URL} Error : {_webRequest.error}";
}
return string.Empty;
}
/// <summary>
/// 检测超时
/// </summary>
public void CheckTimeout()
{
// 注意:在连续时间段内无新增下载数据及判定为超时
if (_isAbort == false)
{
if (_latestDownloadBytes != _webRequest.downloadedBytes)
{
_latestDownloadBytes = _webRequest.downloadedBytes;
_latestDownloadRealtime = Time.realtimeSinceStartup;
}
/// <summary>
/// 检测超时
/// </summary>
public void CheckTimeout()
{
// 注意:在连续时间段内无新增下载数据及判定为超时
if (_isAbort == false)
{
if (_latestDownloadBytes != _webRequest.downloadedBytes)
{
_latestDownloadBytes = _webRequest.downloadedBytes;
_latestDownloadRealtime = Time.realtimeSinceStartup;
}
float offset = Time.realtimeSinceStartup - _latestDownloadRealtime;
if (offset > _timeout)
{
_webRequest.Abort();
_isAbort = true;
}
}
}
}
float offset = Time.realtimeSinceStartup - _latestDownloadRealtime;
if (offset > _timeout)
{
_webRequest.Abort();
_isAbort = true;
}
}
}
}
}

View File

@ -1,154 +1,154 @@

namespace YooAsset
{
/// <summary>
/// 默认的构建管线
/// </summary>
public enum EDefaultBuildPipeline
{
/// <summary>
/// 内置构建管线
/// </summary>
BuiltinBuildPipeline,
/// <summary>
/// 默认的构建管线
/// </summary>
public enum EDefaultBuildPipeline
{
/// <summary>
/// 内置构建管线
/// </summary>
BuiltinBuildPipeline,
/// <summary>
/// 可编程构建管线
/// </summary>
ScriptableBuildPipeline,
/// <summary>
/// 可编程构建管线
/// </summary>
ScriptableBuildPipeline,
/// <summary>
/// 原生文件构建管线
/// </summary>
RawFileBuildPipeline,
}
/// <summary>
/// 原生文件构建管线
/// </summary>
RawFileBuildPipeline,
}
/// <summary>
/// 运行模式
/// </summary>
public enum EPlayMode
{
/// <summary>
/// 编辑器下的模拟模式
/// </summary>
EditorSimulateMode,
/// <summary>
/// 运行模式
/// </summary>
public enum EPlayMode
{
/// <summary>
/// 编辑器下的模拟模式
/// </summary>
EditorSimulateMode,
/// <summary>
/// 离线运行模式
/// </summary>
OfflinePlayMode,
/// <summary>
/// 离线运行模式
/// </summary>
OfflinePlayMode,
/// <summary>
/// 联机运行模式
/// </summary>
HostPlayMode,
/// <summary>
/// 联机运行模式
/// </summary>
HostPlayMode,
/// <summary>
/// WebGL运行模式
/// </summary>
WebPlayMode,
}
/// <summary>
/// WebGL运行模式
/// </summary>
WebPlayMode,
}
/// <summary>
/// 初始化参数
/// </summary>
public abstract class InitializeParameters
{
/// <summary>
/// 内置文件的根路径
/// 注意:当参数为空的时候会使用默认的根目录。
/// </summary>
public string BuildinRootDirectory = string.Empty;
/// <summary>
/// 初始化参数
/// </summary>
public abstract class InitializeParameters
{
/// <summary>
/// 内置文件的根路径
/// 注意:当参数为空的时候会使用默认的根目录。
/// </summary>
public string BuildinRootDirectory = string.Empty;
/// <summary>
/// 沙盒文件的根路径
/// 注意:当参数为空的时候会使用默认的根目录。
/// </summary>
public string SandboxRootDirectory = string.Empty;
/// <summary>
/// 沙盒文件的根路径
/// 注意:当参数为空的时候会使用默认的根目录。
/// </summary>
public string SandboxRootDirectory = string.Empty;
/// <summary>
/// 缓存文件追加原始后缀格式
/// </summary>
public bool CacheFileAppendExtension = false;
/// <summary>
/// 缓存文件追加原始后缀格式
/// </summary>
public bool CacheFileAppendExtension = false;
/// <summary>
/// 缓存系统启动时的验证级别
/// </summary>
public EVerifyLevel CacheBootVerifyLevel = EVerifyLevel.Middle;
/// <summary>
/// 缓存系统启动时的验证级别
/// </summary>
public EVerifyLevel CacheBootVerifyLevel = EVerifyLevel.Middle;
/// <summary>
/// 自动销毁不再使用的资源提供者
/// </summary>
public bool AutoDestroyAssetProvider = false;
/// <summary>
/// 自动销毁不再使用的资源提供者
/// </summary>
public bool AutoDestroyAssetProvider = false;
/// <summary>
/// 启用断点续传参数
/// 说明:当文件的大小大于设置的字节数时启用断点续传下载器
/// </summary>
public uint BreakpointResumeFileSize = int.MaxValue;
/// <summary>
/// 启用断点续传参数
/// 说明:当文件的大小大于设置的字节数时启用断点续传下载器
/// </summary>
public uint BreakpointResumeFileSize = int.MaxValue;
/// <summary>
/// 文件解密服务接口
/// </summary>
public IDecryptionServices DecryptionServices = null;
}
/// <summary>
/// 文件解密服务接口
/// </summary>
public IDecryptionServices DecryptionServices = null;
}
/// <summary>
/// 编辑器下模拟运行模式的初始化参数
/// </summary>
public class EditorSimulateModeParameters : InitializeParameters
{
/// <summary>
/// 用于模拟运行的资源清单路径
/// </summary>
public string SimulateManifestFilePath = string.Empty;
}
/// <summary>
/// 编辑器下模拟运行模式的初始化参数
/// </summary>
public class EditorSimulateModeParameters : InitializeParameters
{
/// <summary>
/// 用于模拟运行的资源清单路径
/// </summary>
public string SimulateManifestFilePath = string.Empty;
}
/// <summary>
/// 离线运行模式的初始化参数
/// </summary>
public class OfflinePlayModeParameters : InitializeParameters
{
}
/// <summary>
/// 离线运行模式的初始化参数
/// </summary>
public class OfflinePlayModeParameters : InitializeParameters
{
}
/// <summary>
/// 联机运行模式的初始化参数
/// </summary>
public class HostPlayModeParameters : InitializeParameters
{
/// <summary>
/// 远端资源地址查询服务类
/// </summary>
public IRemoteServices RemoteServices = null;
/// <summary>
/// 联机运行模式的初始化参数
/// </summary>
public class HostPlayModeParameters : InitializeParameters
{
/// <summary>
/// 远端资源地址查询服务类
/// </summary>
public IRemoteServices RemoteServices = null;
/// <summary>
/// 内置资源查询服务接口
/// </summary>
public IBuildinQueryServices BuildinQueryServices = null;
/// <summary>
/// 内置资源查询服务接口
/// </summary>
public IBuildinQueryServices BuildinQueryServices = null;
/// <summary>
/// 分发资源查询服务接口
/// </summary>
public IDeliveryQueryServices DeliveryQueryServices = null;
/// <summary>
/// 分发资源查询服务接口
/// </summary>
public IDeliveryQueryServices DeliveryQueryServices = null;
/// <summary>
/// 分发资源加载服务接口
/// </summary>
public IDeliveryLoadServices DeliveryLoadServices = null;
}
/// <summary>
/// 分发资源加载服务接口
/// </summary>
public IDeliveryLoadServices DeliveryLoadServices = null;
}
/// <summary>
/// WebGL运行模式的初始化参数
/// </summary>
public class WebPlayModeParameters : InitializeParameters
{
/// <summary>
/// 远端资源地址查询服务类
/// </summary>
public IRemoteServices RemoteServices = null;
/// <summary>
/// WebGL运行模式的初始化参数
/// </summary>
public class WebPlayModeParameters : InitializeParameters
{
/// <summary>
/// 远端资源地址查询服务类
/// </summary>
public IRemoteServices RemoteServices = null;
/// <summary>
/// 内置资源查询服务接口
/// </summary>
public IBuildinQueryServices BuildinQueryServices = null;
}
/// <summary>
/// 内置资源查询服务接口
/// </summary>
public IBuildinQueryServices BuildinQueryServices = null;
}
}

View File

@ -5,148 +5,148 @@ using System.Threading.Tasks;
namespace YooAsset
{
public abstract class AsyncOperationBase : IEnumerator, IComparable<AsyncOperationBase>
{
// 用户请求的回调
private Action<AsyncOperationBase> _callback;
public abstract class AsyncOperationBase : IEnumerator, IComparable<AsyncOperationBase>
{
// 用户请求的回调
private Action<AsyncOperationBase> _callback;
// 是否已经完成
internal bool IsFinish = false;
// 是否已经完成
internal bool IsFinish = false;
/// <summary>
/// 所属包裹
/// </summary>
public string PackageName { private set; get; }
/// <summary>
/// 所属包裹
/// </summary>
public string PackageName { private set; get; }
/// <summary>
/// 优先级
/// </summary>
public uint Priority { set; get; } = 0;
/// <summary>
/// 优先级
/// </summary>
public uint Priority { set; get; } = 0;
/// <summary>
/// 状态
/// </summary>
public EOperationStatus Status { get; protected set; } = EOperationStatus.None;
/// <summary>
/// 状态
/// </summary>
public EOperationStatus Status { get; protected set; } = EOperationStatus.None;
/// <summary>
/// 错误信息
/// </summary>
public string Error { get; protected set; }
/// <summary>
/// 错误信息
/// </summary>
public string Error { get; protected set; }
/// <summary>
/// 处理进度
/// </summary>
public float Progress { get; protected set; }
/// <summary>
/// 处理进度
/// </summary>
public float Progress { get; protected set; }
/// <summary>
/// 是否已经完成
/// </summary>
public bool IsDone
{
get
{
return Status == EOperationStatus.Failed || Status == EOperationStatus.Succeed;
}
}
/// <summary>
/// 是否已经完成
/// </summary>
public bool IsDone
{
get
{
return Status == EOperationStatus.Failed || Status == EOperationStatus.Succeed;
}
}
/// <summary>
/// 完成事件
/// </summary>
public event Action<AsyncOperationBase> Completed
{
add
{
if (IsDone)
value.Invoke(this);
else
_callback += value;
}
remove
{
_callback -= value;
}
}
/// <summary>
/// 完成事件
/// </summary>
public event Action<AsyncOperationBase> Completed
{
add
{
if (IsDone)
value.Invoke(this);
else
_callback += value;
}
remove
{
_callback -= value;
}
}
/// <summary>
/// 异步操作任务
/// </summary>
public Task Task
{
get
{
if (_taskCompletionSource == null)
{
_taskCompletionSource = new TaskCompletionSource<object>();
if (IsDone)
_taskCompletionSource.SetResult(null);
}
return _taskCompletionSource.Task;
}
}
/// <summary>
/// 异步操作任务
/// </summary>
public Task Task
{
get
{
if (_taskCompletionSource == null)
{
_taskCompletionSource = new TaskCompletionSource<object>();
if (IsDone)
_taskCompletionSource.SetResult(null);
}
return _taskCompletionSource.Task;
}
}
internal abstract void InternalOnStart();
internal abstract void InternalOnUpdate();
internal virtual void InternalOnAbort() { }
internal abstract void InternalOnStart();
internal abstract void InternalOnUpdate();
internal virtual void InternalOnAbort() { }
internal void Init(string packageName)
{
PackageName = packageName;
}
internal void SetStart()
{
Status = EOperationStatus.Processing;
InternalOnStart();
}
internal void SetFinish()
{
IsFinish = true;
internal void Init(string packageName)
{
PackageName = packageName;
}
internal void SetStart()
{
Status = EOperationStatus.Processing;
InternalOnStart();
}
internal void SetFinish()
{
IsFinish = true;
// 进度百分百完成
Progress = 1f;
// 进度百分百完成
Progress = 1f;
//注意如果完成回调内发生异常会导致Task无限期等待
_callback?.Invoke(this);
//注意如果完成回调内发生异常会导致Task无限期等待
_callback?.Invoke(this);
if (_taskCompletionSource != null)
_taskCompletionSource.TrySetResult(null);
}
internal void SetAbort()
{
if (IsDone == false)
{
Status = EOperationStatus.Failed;
Error = "user abort";
YooLogger.Warning($"Async operaiton has been abort : {this.GetType().Name}");
InternalOnAbort();
}
}
if (_taskCompletionSource != null)
_taskCompletionSource.TrySetResult(null);
}
internal void SetAbort()
{
if (IsDone == false)
{
Status = EOperationStatus.Failed;
Error = "user abort";
YooLogger.Warning($"Async operaiton has been abort : {this.GetType().Name}");
InternalOnAbort();
}
}
/// <summary>
/// 清空完成回调
/// </summary>
protected void ClearCompletedCallback()
{
_callback = null;
}
/// <summary>
/// 清空完成回调
/// </summary>
protected void ClearCompletedCallback()
{
_callback = null;
}
#region 排序接口实现
public int CompareTo(AsyncOperationBase other)
{
return other.Priority.CompareTo(this.Priority);
}
#endregion
#region 排序接口实现
public int CompareTo(AsyncOperationBase other)
{
return other.Priority.CompareTo(this.Priority);
}
#endregion
#region 异步编程相关
bool IEnumerator.MoveNext()
{
return !IsDone;
}
void IEnumerator.Reset()
{
}
object IEnumerator.Current => null;
#region 异步编程相关
bool IEnumerator.MoveNext()
{
return !IsDone;
}
void IEnumerator.Reset()
{
}
object IEnumerator.Current => null;
private TaskCompletionSource<object> _taskCompletionSource;
#endregion
}
private TaskCompletionSource<object> _taskCompletionSource;
#endregion
}
}

View File

@ -1,11 +1,11 @@

namespace YooAsset
{
public enum EOperationStatus
{
None,
Processing,
Succeed,
Failed
}
public enum EOperationStatus
{
None,
Processing,
Succeed,
Failed
}
}

View File

@ -1,42 +1,42 @@

namespace YooAsset
{
public abstract class GameAsyncOperation : AsyncOperationBase
{
internal override void InternalOnStart()
{
OnStart();
}
internal override void InternalOnUpdate()
{
OnUpdate();
}
internal override void InternalOnAbort()
{
OnAbort();
}
public abstract class GameAsyncOperation : AsyncOperationBase
{
internal override void InternalOnStart()
{
OnStart();
}
internal override void InternalOnUpdate()
{
OnUpdate();
}
internal override void InternalOnAbort()
{
OnAbort();
}
/// <summary>
/// 异步操作开始
/// </summary>
protected abstract void OnStart();
/// <summary>
/// 异步操作开始
/// </summary>
protected abstract void OnStart();
/// <summary>
/// 异步操作更新
/// </summary>
protected abstract void OnUpdate();
/// <summary>
/// 异步操作更新
/// </summary>
protected abstract void OnUpdate();
/// <summary>
/// 异步操作终止
/// </summary>
protected abstract void OnAbort();
/// <summary>
/// 异步操作终止
/// </summary>
protected abstract void OnAbort();
/// <summary>
/// 异步操作系统是否繁忙
/// </summary>
protected bool IsBusy()
{
return OperationSystem.IsBusy;
}
}
/// <summary>
/// 异步操作系统是否繁忙
/// </summary>
protected bool IsBusy()
{
return OperationSystem.IsBusy;
}
}
}

View File

@ -4,138 +4,138 @@ using System.Diagnostics;
namespace YooAsset
{
internal class OperationSystem
{
private static readonly List<AsyncOperationBase> _operations = new List<AsyncOperationBase>(1000);
private static readonly List<AsyncOperationBase> _newList = new List<AsyncOperationBase>(1000);
internal class OperationSystem
{
private static readonly List<AsyncOperationBase> _operations = new List<AsyncOperationBase>(1000);
private static readonly List<AsyncOperationBase> _newList = new List<AsyncOperationBase>(1000);
// 计时器相关
private static Stopwatch _watch;
private static long _frameTime;
// 计时器相关
private static Stopwatch _watch;
private static long _frameTime;
/// <summary>
/// 异步操作的最小时间片段
/// </summary>
public static long MaxTimeSlice { set; get; } = long.MaxValue;
/// <summary>
/// 异步操作的最小时间片段
/// </summary>
public static long MaxTimeSlice { set; get; } = long.MaxValue;
/// <summary>
/// 处理器是否繁忙
/// </summary>
public static bool IsBusy
{
get
{
return _watch.ElapsedMilliseconds - _frameTime >= MaxTimeSlice;
}
}
/// <summary>
/// 处理器是否繁忙
/// </summary>
public static bool IsBusy
{
get
{
return _watch.ElapsedMilliseconds - _frameTime >= MaxTimeSlice;
}
}
/// <summary>
/// 初始化异步操作系统
/// </summary>
public static void Initialize()
{
_watch = Stopwatch.StartNew();
}
/// <summary>
/// 初始化异步操作系统
/// </summary>
public static void Initialize()
{
_watch = Stopwatch.StartNew();
}
/// <summary>
/// 更新异步操作系统
/// </summary>
public static void Update()
{
_frameTime = _watch.ElapsedMilliseconds;
/// <summary>
/// 更新异步操作系统
/// </summary>
public static void Update()
{
_frameTime = _watch.ElapsedMilliseconds;
// 添加新增的异步操作
if (_newList.Count > 0)
{
bool sorting = false;
foreach (var operation in _newList)
{
if (operation.Priority > 0)
{
sorting = true;
break;
}
}
// 添加新增的异步操作
if (_newList.Count > 0)
{
bool sorting = false;
foreach (var operation in _newList)
{
if (operation.Priority > 0)
{
sorting = true;
break;
}
}
_operations.AddRange(_newList);
_newList.Clear();
_operations.AddRange(_newList);
_newList.Clear();
// 重新排序优先级
if (sorting)
_operations.Sort();
}
// 重新排序优先级
if (sorting)
_operations.Sort();
}
// 更新进行中的异步操作
for (int i = 0; i < _operations.Count; i++)
{
if (IsBusy)
break;
// 更新进行中的异步操作
for (int i = 0; i < _operations.Count; i++)
{
if (IsBusy)
break;
var operation = _operations[i];
if (operation.IsFinish)
continue;
var operation = _operations[i];
if (operation.IsFinish)
continue;
if (operation.IsDone == false)
operation.InternalOnUpdate();
if (operation.IsDone == false)
operation.InternalOnUpdate();
if (operation.IsDone)
operation.SetFinish();
}
if (operation.IsDone)
operation.SetFinish();
}
// 移除已经完成的异步操作
for (int i = _operations.Count - 1; i >= 0; i--)
{
var operation = _operations[i];
if (operation.IsFinish)
_operations.RemoveAt(i);
}
}
// 移除已经完成的异步操作
for (int i = _operations.Count - 1; i >= 0; i--)
{
var operation = _operations[i];
if (operation.IsFinish)
_operations.RemoveAt(i);
}
}
/// <summary>
/// 销毁异步操作系统
/// </summary>
public static void DestroyAll()
{
_operations.Clear();
_newList.Clear();
_watch = null;
_frameTime = 0;
MaxTimeSlice = long.MaxValue;
}
/// <summary>
/// 销毁异步操作系统
/// </summary>
public static void DestroyAll()
{
_operations.Clear();
_newList.Clear();
_watch = null;
_frameTime = 0;
MaxTimeSlice = long.MaxValue;
}
/// <summary>
/// 销毁包裹的所有任务
/// </summary>
public static void ClearPackageOperation(string packageName)
{
// 终止临时队列里的任务
foreach (var operation in _newList)
{
if (operation.PackageName == packageName)
{
operation.SetAbort();
}
}
/// <summary>
/// 销毁包裹的所有任务
/// </summary>
public static void ClearPackageOperation(string packageName)
{
// 终止临时队列里的任务
foreach (var operation in _newList)
{
if (operation.PackageName == packageName)
{
operation.SetAbort();
}
}
// 终止正在进行的任务
foreach (var operation in _operations)
{
if (operation.PackageName == packageName)
{
operation.SetAbort();
}
}
}
// 终止正在进行的任务
foreach (var operation in _operations)
{
if (operation.PackageName == packageName)
{
operation.SetAbort();
}
}
}
/// <summary>
/// 开始处理异步操作类
/// </summary>
public static void StartOperation(string packageName, AsyncOperationBase operation)
{
_newList.Add(operation);
operation.Init(packageName);
operation.SetStart();
}
}
/// <summary>
/// 开始处理异步操作类
/// </summary>
public static void StartOperation(string packageName, AsyncOperationBase operation)
{
_newList.Add(operation);
operation.Init(packageName);
operation.SetStart();
}
}
}

View File

@ -3,78 +3,78 @@ using System.Collections.Generic;
namespace YooAsset
{
public sealed class AllAssetsHandle : HandleBase, IDisposable
{
private System.Action<AllAssetsHandle> _callback;
public sealed class AllAssetsHandle : HandleBase, IDisposable
{
private System.Action<AllAssetsHandle> _callback;
internal AllAssetsHandle(ProviderBase provider) : base(provider)
{
}
internal override void InvokeCallback()
{
_callback?.Invoke(this);
}
internal AllAssetsHandle(ProviderBase provider) : base(provider)
{
}
internal override void InvokeCallback()
{
_callback?.Invoke(this);
}
/// <summary>
/// 完成委托
/// </summary>
public event System.Action<AllAssetsHandle> Completed
{
add
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(AllAssetsHandle)} is invalid");
if (Provider.IsDone)
value.Invoke(this);
else
_callback += value;
}
remove
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(AllAssetsHandle)} is invalid");
_callback -= value;
}
}
/// <summary>
/// 完成委托
/// </summary>
public event System.Action<AllAssetsHandle> Completed
{
add
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(AllAssetsHandle)} is invalid");
if (Provider.IsDone)
value.Invoke(this);
else
_callback += value;
}
remove
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(AllAssetsHandle)} is invalid");
_callback -= value;
}
}
/// <summary>
/// 等待异步执行完毕
/// </summary>
public void WaitForAsyncComplete()
{
if (IsValidWithWarning == false)
return;
Provider.WaitForAsyncComplete();
}
/// <summary>
/// 等待异步执行完毕
/// </summary>
public void WaitForAsyncComplete()
{
if (IsValidWithWarning == false)
return;
Provider.WaitForAsyncComplete();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Release()
{
this.ReleaseInternal();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Release()
{
this.ReleaseInternal();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Dispose()
{
this.ReleaseInternal();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Dispose()
{
this.ReleaseInternal();
}
/// <summary>
/// 子资源对象集合
/// </summary>
public UnityEngine.Object[] AllAssetObjects
{
get
{
if (IsValidWithWarning == false)
return null;
return Provider.AllAssetObjects;
}
}
}
/// <summary>
/// 子资源对象集合
/// </summary>
public UnityEngine.Object[] AllAssetObjects
{
get
{
if (IsValidWithWarning == false)
return null;
return Provider.AllAssetObjects;
}
}
}
}

View File

@ -4,154 +4,154 @@ using UnityEngine;
namespace YooAsset
{
public sealed class AssetHandle : HandleBase, IDisposable
{
private System.Action<AssetHandle> _callback;
public sealed class AssetHandle : HandleBase, IDisposable
{
private System.Action<AssetHandle> _callback;
internal AssetHandle(ProviderBase provider) : base(provider)
{
}
internal override void InvokeCallback()
{
_callback?.Invoke(this);
}
internal AssetHandle(ProviderBase provider) : base(provider)
{
}
internal override void InvokeCallback()
{
_callback?.Invoke(this);
}
/// <summary>
/// 完成委托
/// </summary>
public event System.Action<AssetHandle> Completed
{
add
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(AssetHandle)} is invalid");
if (Provider.IsDone)
value.Invoke(this);
else
_callback += value;
}
remove
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(AssetHandle)} is invalid");
_callback -= value;
}
}
/// <summary>
/// 完成委托
/// </summary>
public event System.Action<AssetHandle> Completed
{
add
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(AssetHandle)} is invalid");
if (Provider.IsDone)
value.Invoke(this);
else
_callback += value;
}
remove
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(AssetHandle)} is invalid");
_callback -= value;
}
}
/// <summary>
/// 等待异步执行完毕
/// </summary>
public void WaitForAsyncComplete()
{
if (IsValidWithWarning == false)
return;
Provider.WaitForAsyncComplete();
}
/// <summary>
/// 等待异步执行完毕
/// </summary>
public void WaitForAsyncComplete()
{
if (IsValidWithWarning == false)
return;
Provider.WaitForAsyncComplete();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Release()
{
this.ReleaseInternal();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Release()
{
this.ReleaseInternal();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Dispose()
{
this.ReleaseInternal();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Dispose()
{
this.ReleaseInternal();
}
/// <summary>
/// 资源对象
/// </summary>
public UnityEngine.Object AssetObject
{
get
{
if (IsValidWithWarning == false)
return null;
return Provider.AssetObject;
}
}
/// <summary>
/// 资源对象
/// </summary>
public UnityEngine.Object AssetObject
{
get
{
if (IsValidWithWarning == false)
return null;
return Provider.AssetObject;
}
}
/// <summary>
/// 获取资源对象
/// </summary>
/// <typeparam name="TAsset">资源类型</typeparam>
public TAsset GetAssetObject<TAsset>() where TAsset : UnityEngine.Object
{
if (IsValidWithWarning == false)
return null;
return Provider.AssetObject as TAsset;
}
/// <summary>
/// 获取资源对象
/// </summary>
/// <typeparam name="TAsset">资源类型</typeparam>
public TAsset GetAssetObject<TAsset>() where TAsset : UnityEngine.Object
{
if (IsValidWithWarning == false)
return null;
return Provider.AssetObject as TAsset;
}
/// <summary>
/// 同步初始化游戏对象
/// </summary>
public GameObject InstantiateSync()
{
return InstantiateSyncInternal(false, Vector3.zero, Quaternion.identity, null, false);
}
public GameObject InstantiateSync(Transform parent)
{
return InstantiateSyncInternal(false, Vector3.zero, Quaternion.identity, parent, false);
}
public GameObject InstantiateSync(Transform parent, bool worldPositionStays)
{
return InstantiateSyncInternal(false, Vector3.zero, Quaternion.identity, parent, worldPositionStays);
}
public GameObject InstantiateSync(Vector3 position, Quaternion rotation)
{
return InstantiateSyncInternal(true, position, rotation, null, false);
}
public GameObject InstantiateSync(Vector3 position, Quaternion rotation, Transform parent)
{
return InstantiateSyncInternal(true, position, rotation, parent, false);
}
/// <summary>
/// 同步初始化游戏对象
/// </summary>
public GameObject InstantiateSync()
{
return InstantiateSyncInternal(false, Vector3.zero, Quaternion.identity, null, false);
}
public GameObject InstantiateSync(Transform parent)
{
return InstantiateSyncInternal(false, Vector3.zero, Quaternion.identity, parent, false);
}
public GameObject InstantiateSync(Transform parent, bool worldPositionStays)
{
return InstantiateSyncInternal(false, Vector3.zero, Quaternion.identity, parent, worldPositionStays);
}
public GameObject InstantiateSync(Vector3 position, Quaternion rotation)
{
return InstantiateSyncInternal(true, position, rotation, null, false);
}
public GameObject InstantiateSync(Vector3 position, Quaternion rotation, Transform parent)
{
return InstantiateSyncInternal(true, position, rotation, parent, false);
}
/// <summary>
/// 异步初始化游戏对象
/// </summary>
public InstantiateOperation InstantiateAsync()
{
return InstantiateAsyncInternal(false, Vector3.zero, Quaternion.identity, null, false);
}
public InstantiateOperation InstantiateAsync(Transform parent)
{
return InstantiateAsyncInternal(false, Vector3.zero, Quaternion.identity, parent, false);
}
public InstantiateOperation InstantiateAsync(Transform parent, bool worldPositionStays)
{
return InstantiateAsyncInternal(false, Vector3.zero, Quaternion.identity, parent, worldPositionStays);
}
public InstantiateOperation InstantiateAsync(Vector3 position, Quaternion rotation)
{
return InstantiateAsyncInternal(true, position, rotation, null, false);
}
public InstantiateOperation InstantiateAsync(Vector3 position, Quaternion rotation, Transform parent)
{
return InstantiateAsyncInternal(true, position, rotation, parent, false);
}
/// <summary>
/// 异步初始化游戏对象
/// </summary>
public InstantiateOperation InstantiateAsync()
{
return InstantiateAsyncInternal(false, Vector3.zero, Quaternion.identity, null, false);
}
public InstantiateOperation InstantiateAsync(Transform parent)
{
return InstantiateAsyncInternal(false, Vector3.zero, Quaternion.identity, parent, false);
}
public InstantiateOperation InstantiateAsync(Transform parent, bool worldPositionStays)
{
return InstantiateAsyncInternal(false, Vector3.zero, Quaternion.identity, parent, worldPositionStays);
}
public InstantiateOperation InstantiateAsync(Vector3 position, Quaternion rotation)
{
return InstantiateAsyncInternal(true, position, rotation, null, false);
}
public InstantiateOperation InstantiateAsync(Vector3 position, Quaternion rotation, Transform parent)
{
return InstantiateAsyncInternal(true, position, rotation, parent, false);
}
private GameObject InstantiateSyncInternal(bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays)
{
if (IsValidWithWarning == false)
return null;
if (Provider.AssetObject == null)
return null;
private GameObject InstantiateSyncInternal(bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays)
{
if (IsValidWithWarning == false)
return null;
if (Provider.AssetObject == null)
return null;
return InstantiateOperation.InstantiateInternal(Provider.AssetObject, setPositionAndRotation, position, rotation, parent, worldPositionStays);
}
private InstantiateOperation InstantiateAsyncInternal(bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays)
{
string packageName = GetAssetInfo().PackageName;
InstantiateOperation operation = new InstantiateOperation(this, setPositionAndRotation, position, rotation, parent, worldPositionStays);
OperationSystem.StartOperation(packageName, operation);
return operation;
}
}
return InstantiateOperation.InstantiateInternal(Provider.AssetObject, setPositionAndRotation, position, rotation, parent, worldPositionStays);
}
private InstantiateOperation InstantiateAsyncInternal(bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays)
{
string packageName = GetAssetInfo().PackageName;
InstantiateOperation operation = new InstantiateOperation(this, setPositionAndRotation, position, rotation, parent, worldPositionStays);
OperationSystem.StartOperation(packageName, operation);
return operation;
}
}
}

View File

@ -3,159 +3,159 @@ using System.Collections;
namespace YooAsset
{
public abstract class HandleBase : IEnumerator
{
private readonly AssetInfo _assetInfo;
internal ProviderBase Provider { private set; get; }
public abstract class HandleBase : IEnumerator
{
private readonly AssetInfo _assetInfo;
internal ProviderBase Provider { private set; get; }
internal HandleBase(ProviderBase provider)
{
Provider = provider;
_assetInfo = provider.MainAssetInfo;
}
internal abstract void InvokeCallback();
internal HandleBase(ProviderBase provider)
{
Provider = provider;
_assetInfo = provider.MainAssetInfo;
}
internal abstract void InvokeCallback();
/// <summary>
/// 获取资源信息
/// </summary>
public AssetInfo GetAssetInfo()
{
return _assetInfo;
}
/// <summary>
/// 获取资源信息
/// </summary>
public AssetInfo GetAssetInfo()
{
return _assetInfo;
}
/// <summary>
/// 获取下载报告
/// </summary>
public DownloadStatus GetDownloadStatus()
{
if (IsValidWithWarning == false)
{
return DownloadStatus.CreateDefaultStatus();
}
return Provider.GetDownloadStatus();
}
/// <summary>
/// 获取下载报告
/// </summary>
public DownloadStatus GetDownloadStatus()
{
if (IsValidWithWarning == false)
{
return DownloadStatus.CreateDefaultStatus();
}
return Provider.GetDownloadStatus();
}
/// <summary>
/// 当前状态
/// </summary>
public EOperationStatus Status
{
get
{
if (IsValidWithWarning == false)
return EOperationStatus.None;
/// <summary>
/// 当前状态
/// </summary>
public EOperationStatus Status
{
get
{
if (IsValidWithWarning == false)
return EOperationStatus.None;
return Provider.Status;
}
}
return Provider.Status;
}
}
/// <summary>
/// 最近的错误信息
/// </summary>
public string LastError
{
get
{
if (IsValidWithWarning == false)
return string.Empty;
return Provider.Error;
}
}
/// <summary>
/// 最近的错误信息
/// </summary>
public string LastError
{
get
{
if (IsValidWithWarning == false)
return string.Empty;
return Provider.Error;
}
}
/// <summary>
/// 加载进度
/// </summary>
public float Progress
{
get
{
if (IsValidWithWarning == false)
return 0;
return Provider.Progress;
}
}
/// <summary>
/// 加载进度
/// </summary>
public float Progress
{
get
{
if (IsValidWithWarning == false)
return 0;
return Provider.Progress;
}
}
/// <summary>
/// 是否加载完毕
/// </summary>
public bool IsDone
{
get
{
if (IsValidWithWarning == false)
return false;
return Provider.IsDone;
}
}
/// <summary>
/// 是否加载完毕
/// </summary>
public bool IsDone
{
get
{
if (IsValidWithWarning == false)
return false;
return Provider.IsDone;
}
}
/// <summary>
/// 句柄是否有效
/// </summary>
public bool IsValid
{
get
{
if (Provider != null && Provider.IsDestroyed == false)
return true;
else
return false;
}
}
/// <summary>
/// 句柄是否有效
/// </summary>
public bool IsValid
{
get
{
if (Provider != null && Provider.IsDestroyed == false)
return true;
else
return false;
}
}
/// <summary>
/// 句柄是否有效
/// </summary>
internal bool IsValidWithWarning
{
get
{
if (Provider != null && Provider.IsDestroyed == false)
{
return true;
}
else
{
if (Provider == null)
YooLogger.Warning($"Operation handle is released : {_assetInfo.AssetPath}");
else if (Provider.IsDestroyed)
YooLogger.Warning($"Provider is destroyed : {_assetInfo.AssetPath}");
return false;
}
}
}
/// <summary>
/// 句柄是否有效
/// </summary>
internal bool IsValidWithWarning
{
get
{
if (Provider != null && Provider.IsDestroyed == false)
{
return true;
}
else
{
if (Provider == null)
YooLogger.Warning($"Operation handle is released : {_assetInfo.AssetPath}");
else if (Provider.IsDestroyed)
YooLogger.Warning($"Provider is destroyed : {_assetInfo.AssetPath}");
return false;
}
}
}
/// <summary>
/// 释放句柄
/// </summary>
internal void ReleaseInternal()
{
if (IsValidWithWarning == false)
return;
Provider.ReleaseHandle(this);
Provider = null;
}
/// <summary>
/// 释放句柄
/// </summary>
internal void ReleaseInternal()
{
if (IsValidWithWarning == false)
return;
Provider.ReleaseHandle(this);
Provider = null;
}
#region 异步操作相关
/// <summary>
/// 异步操作任务
/// </summary>
public System.Threading.Tasks.Task Task
{
get { return Provider.Task; }
}
#region 异步操作相关
/// <summary>
/// 异步操作任务
/// </summary>
public System.Threading.Tasks.Task Task
{
get { return Provider.Task; }
}
// 协程相关
bool IEnumerator.MoveNext()
{
return !IsDone;
}
void IEnumerator.Reset()
{
}
object IEnumerator.Current
{
get { return Provider; }
}
#endregion
}
// 协程相关
bool IEnumerator.MoveNext()
{
return !IsDone;
}
void IEnumerator.Reset()
{
}
object IEnumerator.Current
{
get { return Provider; }
}
#endregion
}
}

View File

@ -4,97 +4,97 @@ using System.Text;
namespace YooAsset
{
public class RawFileHandle : HandleBase, IDisposable
{
private System.Action<RawFileHandle> _callback;
public class RawFileHandle : HandleBase, IDisposable
{
private System.Action<RawFileHandle> _callback;
internal RawFileHandle(ProviderBase provider) : base(provider)
{
}
internal override void InvokeCallback()
{
_callback?.Invoke(this);
}
internal RawFileHandle(ProviderBase provider) : base(provider)
{
}
internal override void InvokeCallback()
{
_callback?.Invoke(this);
}
/// <summary>
/// 完成委托
/// </summary>
public event System.Action<RawFileHandle> Completed
{
add
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(RawFileHandle)} is invalid");
if (Provider.IsDone)
value.Invoke(this);
else
_callback += value;
}
remove
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(RawFileHandle)} is invalid");
_callback -= value;
}
}
/// <summary>
/// 完成委托
/// </summary>
public event System.Action<RawFileHandle> Completed
{
add
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(RawFileHandle)} is invalid");
if (Provider.IsDone)
value.Invoke(this);
else
_callback += value;
}
remove
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(RawFileHandle)} is invalid");
_callback -= value;
}
}
/// <summary>
/// 等待异步执行完毕
/// </summary>
public void WaitForAsyncComplete()
{
if (IsValidWithWarning == false)
return;
Provider.WaitForAsyncComplete();
}
/// <summary>
/// 等待异步执行完毕
/// </summary>
public void WaitForAsyncComplete()
{
if (IsValidWithWarning == false)
return;
Provider.WaitForAsyncComplete();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Release()
{
this.ReleaseInternal();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Release()
{
this.ReleaseInternal();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Dispose()
{
this.ReleaseInternal();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Dispose()
{
this.ReleaseInternal();
}
/// <summary>
/// 获取原生文件的二进制数据
/// </summary>
public byte[] GetRawFileData()
{
if (IsValidWithWarning == false)
return null;
string filePath = Provider.RawFilePath;
return FileUtility.ReadAllBytes(filePath);
}
/// <summary>
/// 获取原生文件的二进制数据
/// </summary>
public byte[] GetRawFileData()
{
if (IsValidWithWarning == false)
return null;
string filePath = Provider.RawFilePath;
return FileUtility.ReadAllBytes(filePath);
}
/// <summary>
/// 获取原生文件的文本数据
/// </summary>
public string GetRawFileText()
{
if (IsValidWithWarning == false)
return null;
string filePath = Provider.RawFilePath;
return FileUtility.ReadAllText(filePath);
}
/// <summary>
/// 获取原生文件的文本数据
/// </summary>
public string GetRawFileText()
{
if (IsValidWithWarning == false)
return null;
string filePath = Provider.RawFilePath;
return FileUtility.ReadAllText(filePath);
}
/// <summary>
/// 获取原生文件的路径
/// </summary>
public string GetRawFilePath()
{
if (IsValidWithWarning == false)
return string.Empty;
return Provider.RawFilePath;
}
}
/// <summary>
/// 获取原生文件的路径
/// </summary>
public string GetRawFilePath()
{
if (IsValidWithWarning == false)
return string.Empty;
return Provider.RawFilePath;
}
}
}

View File

@ -2,174 +2,174 @@
namespace YooAsset
{
public class SceneHandle : HandleBase
{
private System.Action<SceneHandle> _callback;
internal string PackageName { set; get; }
public class SceneHandle : HandleBase
{
private System.Action<SceneHandle> _callback;
internal string PackageName { set; get; }
internal SceneHandle(ProviderBase provider) : base(provider)
{
}
internal override void InvokeCallback()
{
_callback?.Invoke(this);
}
internal SceneHandle(ProviderBase provider) : base(provider)
{
}
internal override void InvokeCallback()
{
_callback?.Invoke(this);
}
/// <summary>
/// 完成委托
/// </summary>
public event System.Action<SceneHandle> Completed
{
add
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(SceneHandle)} is invalid");
if (Provider.IsDone)
value.Invoke(this);
else
_callback += value;
}
remove
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(SceneHandle)} is invalid");
_callback -= value;
}
}
/// <summary>
/// 完成委托
/// </summary>
public event System.Action<SceneHandle> Completed
{
add
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(SceneHandle)} is invalid");
if (Provider.IsDone)
value.Invoke(this);
else
_callback += value;
}
remove
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(SceneHandle)} is invalid");
_callback -= value;
}
}
/// <summary>
/// 场景名称
/// </summary>
public string SceneName
{
get
{
if (IsValidWithWarning == false)
return string.Empty;
return Provider.SceneName;
}
}
/// <summary>
/// 场景名称
/// </summary>
public string SceneName
{
get
{
if (IsValidWithWarning == false)
return string.Empty;
return Provider.SceneName;
}
}
/// <summary>
/// 场景对象
/// </summary>
public Scene SceneObject
{
get
{
if (IsValidWithWarning == false)
return new Scene();
return Provider.SceneObject;
}
}
/// <summary>
/// 场景对象
/// </summary>
public Scene SceneObject
{
get
{
if (IsValidWithWarning == false)
return new Scene();
return Provider.SceneObject;
}
}
/// <summary>
/// 激活场景(当同时存在多个场景时用于切换激活场景)
/// </summary>
public bool ActivateScene()
{
if (IsValidWithWarning == false)
return false;
/// <summary>
/// 激活场景(当同时存在多个场景时用于切换激活场景)
/// </summary>
public bool ActivateScene()
{
if (IsValidWithWarning == false)
return false;
if (SceneObject.IsValid() && SceneObject.isLoaded)
{
return SceneManager.SetActiveScene(SceneObject);
}
else
{
YooLogger.Warning($"Scene is invalid or not loaded : {SceneObject.name}");
return false;
}
}
if (SceneObject.IsValid() && SceneObject.isLoaded)
{
return SceneManager.SetActiveScene(SceneObject);
}
else
{
YooLogger.Warning($"Scene is invalid or not loaded : {SceneObject.name}");
return false;
}
}
/// <summary>
/// 解除场景加载挂起操作
/// </summary>
public bool UnSuspend()
{
if (IsValidWithWarning == false)
return false;
/// <summary>
/// 解除场景加载挂起操作
/// </summary>
public bool UnSuspend()
{
if (IsValidWithWarning == false)
return false;
if (SceneObject.IsValid())
{
if (Provider is DatabaseSceneProvider)
{
var temp = Provider as DatabaseSceneProvider;
return temp.UnSuspendLoad();
}
else if (Provider is BundledSceneProvider)
{
var temp = Provider as BundledSceneProvider;
return temp.UnSuspendLoad();
}
else
{
throw new System.NotImplementedException();
}
}
else
{
YooLogger.Warning($"Scene is invalid : {SceneObject.name}");
return false;
}
}
if (SceneObject.IsValid())
{
if (Provider is DatabaseSceneProvider)
{
var temp = Provider as DatabaseSceneProvider;
return temp.UnSuspendLoad();
}
else if (Provider is BundledSceneProvider)
{
var temp = Provider as BundledSceneProvider;
return temp.UnSuspendLoad();
}
else
{
throw new System.NotImplementedException();
}
}
else
{
YooLogger.Warning($"Scene is invalid : {SceneObject.name}");
return false;
}
}
/// <summary>
/// 是否为主场景
/// </summary>
public bool IsMainScene()
{
if (IsValidWithWarning == false)
return false;
/// <summary>
/// 是否为主场景
/// </summary>
public bool IsMainScene()
{
if (IsValidWithWarning == false)
return false;
if (Provider is DatabaseSceneProvider)
{
var temp = Provider as DatabaseSceneProvider;
return temp.SceneMode == LoadSceneMode.Single;
}
else if (Provider is BundledSceneProvider)
{
var temp = Provider as BundledSceneProvider;
return temp.SceneMode == LoadSceneMode.Single;
}
else
{
throw new System.NotImplementedException();
}
}
if (Provider is DatabaseSceneProvider)
{
var temp = Provider as DatabaseSceneProvider;
return temp.SceneMode == LoadSceneMode.Single;
}
else if (Provider is BundledSceneProvider)
{
var temp = Provider as BundledSceneProvider;
return temp.SceneMode == LoadSceneMode.Single;
}
else
{
throw new System.NotImplementedException();
}
}
/// <summary>
/// 异步卸载子场景
/// </summary>
public UnloadSceneOperation UnloadAsync()
{
string packageName = GetAssetInfo().PackageName;
/// <summary>
/// 异步卸载子场景
/// </summary>
public UnloadSceneOperation UnloadAsync()
{
string packageName = GetAssetInfo().PackageName;
// 如果句柄无效
if (IsValidWithWarning == false)
{
string error = $"{nameof(SceneHandle)} is invalid.";
var operation = new UnloadSceneOperation(error);
OperationSystem.StartOperation(packageName, operation);
return operation;
}
// 如果句柄无效
if (IsValidWithWarning == false)
{
string error = $"{nameof(SceneHandle)} is invalid.";
var operation = new UnloadSceneOperation(error);
OperationSystem.StartOperation(packageName, operation);
return operation;
}
// 如果是主场景
if (IsMainScene())
{
string error = $"Cannot unload main scene. Use {nameof(YooAssets.LoadSceneAsync)} method to change the main scene !";
YooLogger.Error(error);
var operation = new UnloadSceneOperation(error);
OperationSystem.StartOperation(packageName, operation);
return operation;
}
// 如果是主场景
if (IsMainScene())
{
string error = $"Cannot unload main scene. Use {nameof(YooAssets.LoadSceneAsync)} method to change the main scene !";
YooLogger.Error(error);
var operation = new UnloadSceneOperation(error);
OperationSystem.StartOperation(packageName, operation);
return operation;
}
// 卸载子场景
{
var operation = new UnloadSceneOperation(Provider);
OperationSystem.StartOperation(packageName, operation);
return operation;
}
}
}
// 卸载子场景
{
var operation = new UnloadSceneOperation(Provider);
OperationSystem.StartOperation(packageName, operation);
return operation;
}
}
}
}

View File

@ -3,117 +3,117 @@ using System.Collections.Generic;
namespace YooAsset
{
public sealed class SubAssetsHandle : HandleBase, IDisposable
{
private System.Action<SubAssetsHandle> _callback;
public sealed class SubAssetsHandle : HandleBase, IDisposable
{
private System.Action<SubAssetsHandle> _callback;
internal SubAssetsHandle(ProviderBase provider) : base(provider)
{
}
internal override void InvokeCallback()
{
_callback?.Invoke(this);
}
internal SubAssetsHandle(ProviderBase provider) : base(provider)
{
}
internal override void InvokeCallback()
{
_callback?.Invoke(this);
}
/// <summary>
/// 完成委托
/// </summary>
public event System.Action<SubAssetsHandle> Completed
{
add
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(SubAssetsHandle)} is invalid");
if (Provider.IsDone)
value.Invoke(this);
else
_callback += value;
}
remove
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(SubAssetsHandle)} is invalid");
_callback -= value;
}
}
/// <summary>
/// 完成委托
/// </summary>
public event System.Action<SubAssetsHandle> Completed
{
add
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(SubAssetsHandle)} is invalid");
if (Provider.IsDone)
value.Invoke(this);
else
_callback += value;
}
remove
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(SubAssetsHandle)} is invalid");
_callback -= value;
}
}
/// <summary>
/// 等待异步执行完毕
/// </summary>
public void WaitForAsyncComplete()
{
if (IsValidWithWarning == false)
return;
Provider.WaitForAsyncComplete();
}
/// <summary>
/// 等待异步执行完毕
/// </summary>
public void WaitForAsyncComplete()
{
if (IsValidWithWarning == false)
return;
Provider.WaitForAsyncComplete();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Release()
{
this.ReleaseInternal();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Release()
{
this.ReleaseInternal();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Dispose()
{
this.ReleaseInternal();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Dispose()
{
this.ReleaseInternal();
}
/// <summary>
/// 子资源对象集合
/// </summary>
public UnityEngine.Object[] AllAssetObjects
{
get
{
if (IsValidWithWarning == false)
return null;
return Provider.AllAssetObjects;
}
}
/// <summary>
/// 子资源对象集合
/// </summary>
public UnityEngine.Object[] AllAssetObjects
{
get
{
if (IsValidWithWarning == false)
return null;
return Provider.AllAssetObjects;
}
}
/// <summary>
/// 获取子资源对象
/// </summary>
/// <typeparam name="TObject">子资源对象类型</typeparam>
/// <param name="assetName">子资源对象名称</param>
public TObject GetSubAssetObject<TObject>(string assetName) where TObject : UnityEngine.Object
{
if (IsValidWithWarning == false)
return null;
/// <summary>
/// 获取子资源对象
/// </summary>
/// <typeparam name="TObject">子资源对象类型</typeparam>
/// <param name="assetName">子资源对象名称</param>
public TObject GetSubAssetObject<TObject>(string assetName) where TObject : UnityEngine.Object
{
if (IsValidWithWarning == false)
return null;
foreach (var assetObject in Provider.AllAssetObjects)
{
if (assetObject.name == assetName)
return assetObject as TObject;
}
foreach (var assetObject in Provider.AllAssetObjects)
{
if (assetObject.name == assetName)
return assetObject as TObject;
}
YooLogger.Warning($"Not found sub asset object : {assetName}");
return null;
}
YooLogger.Warning($"Not found sub asset object : {assetName}");
return null;
}
/// <summary>
/// 获取所有的子资源对象集合
/// </summary>
/// <typeparam name="TObject">子资源对象类型</typeparam>
public TObject[] GetSubAssetObjects<TObject>() where TObject : UnityEngine.Object
{
if (IsValidWithWarning == false)
return null;
/// <summary>
/// 获取所有的子资源对象集合
/// </summary>
/// <typeparam name="TObject">子资源对象类型</typeparam>
public TObject[] GetSubAssetObjects<TObject>() where TObject : UnityEngine.Object
{
if (IsValidWithWarning == false)
return null;
List<TObject> ret = new List<TObject>(Provider.AllAssetObjects.Length);
foreach (var assetObject in Provider.AllAssetObjects)
{
var retObject = assetObject as TObject;
if (retObject != null)
ret.Add(retObject);
}
return ret.ToArray();
}
}
List<TObject> ret = new List<TObject>(Provider.AllAssetObjects.Length);
foreach (var assetObject in Provider.AllAssetObjects)
{
var retObject = assetObject as TObject;
if (retObject != null)
ret.Add(retObject);
}
return ret.ToArray();
}
}
}

View File

@ -6,289 +6,289 @@ using UnityEngine;
namespace YooAsset
{
internal sealed class AssetBundleFileLoader : BundleLoaderBase
{
private enum ESteps
{
None = 0,
Download,
CheckDownload,
Unpack,
CheckUnpack,
LoadBundleFile,
LoadDeliveryFile,
CheckLoadFile,
Done,
}
internal sealed class AssetBundleFileLoader : BundleLoaderBase
{
private enum ESteps
{
None = 0,
Download,
CheckDownload,
Unpack,
CheckUnpack,
LoadBundleFile,
LoadDeliveryFile,
CheckLoadFile,
Done,
}
private ESteps _steps = ESteps.None;
private bool _isWaitForAsyncComplete = false;
private bool _isShowWaitForAsyncError = false;
private DownloaderBase _unpacker;
private DownloaderBase _downloader;
private AssetBundleCreateRequest _createRequest;
private Stream _managedStream;
private ESteps _steps = ESteps.None;
private bool _isWaitForAsyncComplete = false;
private bool _isShowWaitForAsyncError = false;
private DownloaderBase _unpacker;
private DownloaderBase _downloader;
private AssetBundleCreateRequest _createRequest;
private Stream _managedStream;
public AssetBundleFileLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
public AssetBundleFileLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
/// <summary>
/// 轮询更新
/// </summary>
public override void Update()
{
if (_steps == ESteps.Done)
return;
/// <summary>
/// 轮询更新
/// </summary>
public override void Update()
{
if (_steps == ESteps.Done)
return;
if (_steps == ESteps.None)
{
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.Download;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
if (_steps == ESteps.None)
{
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.Download;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
#if UNITY_ANDROID
if (MainBundleInfo.Bundle.Encrypted)
{
_steps = ESteps.Unpack;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else
{
_steps = ESteps.LoadBundleFile;
FileLoadPath = MainBundleInfo.BuildinFilePath;
}
if (MainBundleInfo.Bundle.Encrypted)
{
_steps = ESteps.Unpack;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else
{
_steps = ESteps.LoadBundleFile;
FileLoadPath = MainBundleInfo.BuildinFilePath;
}
#else
_steps = ESteps.LoadBundleFile;
FileLoadPath = MainBundleInfo.BuildinFilePath;
#endif
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
_steps = ESteps.LoadBundleFile;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromDelivery)
{
_steps = ESteps.LoadDeliveryFile;
FileLoadPath = MainBundleInfo.DeliveryFilePath;
}
else
{
throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
}
}
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
_steps = ESteps.LoadBundleFile;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromDelivery)
{
_steps = ESteps.LoadDeliveryFile;
FileLoadPath = MainBundleInfo.DeliveryFilePath;
}
else
{
throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
}
}
// 1. 从服务器下载
if (_steps == ESteps.Download)
{
_downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
_downloader.SendRequest();
_steps = ESteps.CheckDownload;
}
// 1. 从服务器下载
if (_steps == ESteps.Download)
{
_downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
_downloader.SendRequest();
_steps = ESteps.CheckDownload;
}
// 2. 检测服务器下载结果
if (_steps == ESteps.CheckDownload)
{
DownloadProgress = _downloader.DownloadProgress;
DownloadedBytes = _downloader.DownloadedBytes;
if (_downloader.IsDone() == false)
return;
// 2. 检测服务器下载结果
if (_steps == ESteps.CheckDownload)
{
DownloadProgress = _downloader.DownloadProgress;
DownloadedBytes = _downloader.DownloadedBytes;
if (_downloader.IsDone() == false)
return;
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _downloader.GetLastError();
}
else
{
_steps = ESteps.LoadBundleFile;
return; //下载完毕等待一帧再去加载!
}
}
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _downloader.GetLastError();
}
else
{
_steps = ESteps.LoadBundleFile;
return; //下载完毕等待一帧再去加载!
}
}
// 3. 内置文件解压
if (_steps == ESteps.Unpack)
{
int failedTryAgain = 1;
_unpacker = MainBundleInfo.CreateUnpacker(failedTryAgain);
_unpacker.SendRequest();
_steps = ESteps.CheckUnpack;
}
// 3. 内置文件解压
if (_steps == ESteps.Unpack)
{
int failedTryAgain = 1;
_unpacker = MainBundleInfo.CreateUnpacker(failedTryAgain);
_unpacker.SendRequest();
_steps = ESteps.CheckUnpack;
}
// 4.检测内置文件解压结果
if (_steps == ESteps.CheckUnpack)
{
DownloadProgress = _unpacker.DownloadProgress;
DownloadedBytes = _unpacker.DownloadedBytes;
if (_unpacker.IsDone() == false)
return;
// 4.检测内置文件解压结果
if (_steps == ESteps.CheckUnpack)
{
DownloadProgress = _unpacker.DownloadProgress;
DownloadedBytes = _unpacker.DownloadedBytes;
if (_unpacker.IsDone() == false)
return;
if (_unpacker.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _unpacker.GetLastError();
}
else
{
_steps = ESteps.LoadBundleFile;
}
}
if (_unpacker.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _unpacker.GetLastError();
}
else
{
_steps = ESteps.LoadBundleFile;
}
}
// 5. 加载AssetBundle
if (_steps == ESteps.LoadBundleFile)
{
// 5. 加载AssetBundle
if (_steps == ESteps.LoadBundleFile)
{
#if UNITY_EDITOR
// 注意Unity2017.4编辑器模式下如果AssetBundle文件不存在会导致编辑器崩溃这里做了预判。
if (System.IO.File.Exists(FileLoadPath) == false)
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"Not found assetBundle file : {FileLoadPath}";
YooLogger.Error(LastError);
return;
}
// 注意Unity2017.4编辑器模式下如果AssetBundle文件不存在会导致编辑器崩溃这里做了预判。
if (System.IO.File.Exists(FileLoadPath) == false)
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"Not found assetBundle file : {FileLoadPath}";
YooLogger.Error(LastError);
return;
}
#endif
// 设置下载进度
DownloadProgress = 1f;
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
// 设置下载进度
DownloadProgress = 1f;
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
// 加载AssetBundle资源对象
// 注意:解密服务类可能会返回空的对象。
if (_isWaitForAsyncComplete)
CacheBundle = MainBundleInfo.LoadAssetBundle(FileLoadPath, out _managedStream);
else
_createRequest = MainBundleInfo.LoadAssetBundleAsync(FileLoadPath, out _managedStream);
// 加载AssetBundle资源对象
// 注意:解密服务类可能会返回空的对象。
if (_isWaitForAsyncComplete)
CacheBundle = MainBundleInfo.LoadAssetBundle(FileLoadPath, out _managedStream);
else
_createRequest = MainBundleInfo.LoadAssetBundleAsync(FileLoadPath, out _managedStream);
_steps = ESteps.CheckLoadFile;
}
_steps = ESteps.CheckLoadFile;
}
// 6. 加载AssetBundle
if (_steps == ESteps.LoadDeliveryFile)
{
// 设置下载进度
DownloadProgress = 1f;
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
// 6. 加载AssetBundle
if (_steps == ESteps.LoadDeliveryFile)
{
// 设置下载进度
DownloadProgress = 1f;
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
// Load assetBundle file
if (_isWaitForAsyncComplete)
CacheBundle = MainBundleInfo.LoadDeliveryAssetBundle(FileLoadPath);
else
_createRequest = MainBundleInfo.LoadDeliveryAssetBundleAsync(FileLoadPath);
// Load assetBundle file
if (_isWaitForAsyncComplete)
CacheBundle = MainBundleInfo.LoadDeliveryAssetBundle(FileLoadPath);
else
_createRequest = MainBundleInfo.LoadDeliveryAssetBundleAsync(FileLoadPath);
_steps = ESteps.CheckLoadFile;
}
_steps = ESteps.CheckLoadFile;
}
// 7. 检测AssetBundle加载结果
if (_steps == ESteps.CheckLoadFile)
{
if (_createRequest != null)
{
if (_isWaitForAsyncComplete || IsForceDestroyComplete)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity bundle.");
CacheBundle = _createRequest.assetBundle;
}
else
{
if (_createRequest.isDone == false)
return;
CacheBundle = _createRequest.assetBundle;
}
}
// 7. 检测AssetBundle加载结果
if (_steps == ESteps.CheckLoadFile)
{
if (_createRequest != null)
{
if (_isWaitForAsyncComplete || IsForceDestroyComplete)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity bundle.");
CacheBundle = _createRequest.assetBundle;
}
else
{
if (_createRequest.isDone == false)
return;
CacheBundle = _createRequest.assetBundle;
}
}
// Check error
if (CacheBundle == null)
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"Failed to load assetBundle : {MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
// Check error
if (CacheBundle == null)
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"Failed to load assetBundle : {MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
// 注意当缓存文件的校验等级为Low的时候并不能保证缓存文件的完整性。
// 在AssetBundle文件加载失败的情况下我们需要重新验证文件的完整性
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
var result = MainBundleInfo.VerifySelf();
if (result != EVerifyResult.Succeed)
{
YooLogger.Error($"Found possibly corrupt file ! {MainBundleInfo.Bundle.CacheGUID} Verify result : {result}");
MainBundleInfo.CacheDiscard();
}
}
}
else
{
_steps = ESteps.Done;
Status = EStatus.Succeed;
}
}
}
// 注意当缓存文件的校验等级为Low的时候并不能保证缓存文件的完整性。
// 在AssetBundle文件加载失败的情况下我们需要重新验证文件的完整性
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
var result = MainBundleInfo.VerifySelf();
if (result != EVerifyResult.Succeed)
{
YooLogger.Error($"Found possibly corrupt file ! {MainBundleInfo.Bundle.CacheGUID} Verify result : {result}");
MainBundleInfo.CacheDiscard();
}
}
}
else
{
_steps = ESteps.Done;
Status = EStatus.Succeed;
}
}
}
/// <summary>
/// 销毁
/// </summary>
public override void Destroy()
{
base.Destroy();
/// <summary>
/// 销毁
/// </summary>
public override void Destroy()
{
base.Destroy();
if (_managedStream != null)
{
_managedStream.Close();
_managedStream.Dispose();
_managedStream = null;
}
}
if (_managedStream != null)
{
_managedStream.Close();
_managedStream.Dispose();
_managedStream = null;
}
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public override void WaitForAsyncComplete()
{
_isWaitForAsyncComplete = true;
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public override void WaitForAsyncComplete()
{
_isWaitForAsyncComplete = true;
int frame = 1000;
while (true)
{
// 文件解压
if (_unpacker != null)
{
if (_unpacker.IsDone() == false)
{
_unpacker.WaitForAsyncComplete = true;
_unpacker.Update();
continue;
}
}
int frame = 1000;
while (true)
{
// 文件解压
if (_unpacker != null)
{
if (_unpacker.IsDone() == false)
{
_unpacker.WaitForAsyncComplete = true;
_unpacker.Update();
continue;
}
}
// 保险机制
// 注意如果需要从WEB端下载资源可能会触发保险机制
frame--;
if (frame == 0)
{
if (_isShowWaitForAsyncError == false)
{
_isShowWaitForAsyncError = true;
YooLogger.Error($"{nameof(WaitForAsyncComplete)} failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !");
}
break;
}
// 保险机制
// 注意如果需要从WEB端下载资源可能会触发保险机制
frame--;
if (frame == 0)
{
if (_isShowWaitForAsyncError == false)
{
_isShowWaitForAsyncError = true;
YooLogger.Error($"{nameof(WaitForAsyncComplete)} failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !");
}
break;
}
// 驱动流程
Update();
// 驱动流程
Update();
// 完成后退出
if (IsDone())
break;
}
}
}
// 完成后退出
if (IsDone())
break;
}
}
}
}

View File

@ -7,105 +7,105 @@ using UnityEngine.Networking;
namespace YooAsset
{
/// <summary>
/// WebGL平台加载器
/// </summary>
internal sealed class AssetBundleWebLoader : BundleLoaderBase
{
private enum ESteps
{
None = 0,
LoadWebSiteFile,
LoadRemoteFile,
CheckLoadFile,
Done,
}
/// <summary>
/// WebGL平台加载器
/// </summary>
internal sealed class AssetBundleWebLoader : BundleLoaderBase
{
private enum ESteps
{
None = 0,
LoadWebSiteFile,
LoadRemoteFile,
CheckLoadFile,
Done,
}
private ESteps _steps = ESteps.None;
private DownloaderBase _downloader;
private ESteps _steps = ESteps.None;
private DownloaderBase _downloader;
public AssetBundleWebLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
public AssetBundleWebLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
/// <summary>
/// 轮询更新
/// </summary>
public override void Update()
{
if (_steps == ESteps.Done)
return;
/// <summary>
/// 轮询更新
/// </summary>
public override void Update()
{
if (_steps == ESteps.Done)
return;
if (_steps == ESteps.None)
{
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.LoadRemoteFile;
FileLoadPath = string.Empty;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
_steps = ESteps.LoadWebSiteFile;
FileLoadPath = string.Empty;
}
else
{
throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
}
}
if (_steps == ESteps.None)
{
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.LoadRemoteFile;
FileLoadPath = string.Empty;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
_steps = ESteps.LoadWebSiteFile;
FileLoadPath = string.Empty;
}
else
{
throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
}
}
// 1. 跨域获取资源包
if (_steps == ESteps.LoadRemoteFile)
{
_downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
_downloader.SendRequest(true);
_steps = ESteps.CheckLoadFile;
}
// 1. 跨域获取资源包
if (_steps == ESteps.LoadRemoteFile)
{
_downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
_downloader.SendRequest(true);
_steps = ESteps.CheckLoadFile;
}
// 2. 从站点获取资源包
if (_steps == ESteps.LoadWebSiteFile)
{
_downloader = MainBundleInfo.CreateUnpacker(int.MaxValue);
_downloader.SendRequest(true);
_steps = ESteps.CheckLoadFile;
}
// 2. 从站点获取资源包
if (_steps == ESteps.LoadWebSiteFile)
{
_downloader = MainBundleInfo.CreateUnpacker(int.MaxValue);
_downloader.SendRequest(true);
_steps = ESteps.CheckLoadFile;
}
// 3. 检测加载结果
if (_steps == ESteps.CheckLoadFile)
{
DownloadProgress = _downloader.DownloadProgress;
DownloadedBytes = _downloader.DownloadedBytes;
if (_downloader.IsDone() == false)
return;
// 3. 检测加载结果
if (_steps == ESteps.CheckLoadFile)
{
DownloadProgress = _downloader.DownloadProgress;
DownloadedBytes = _downloader.DownloadedBytes;
if (_downloader.IsDone() == false)
return;
CacheBundle = _downloader.GetAssetBundle();
if (CacheBundle == null)
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"AssetBundle file is invalid : {MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
}
else
{
_steps = ESteps.Done;
Status = EStatus.Succeed;
}
}
}
CacheBundle = _downloader.GetAssetBundle();
if (CacheBundle == null)
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"AssetBundle file is invalid : {MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
}
else
{
_steps = ESteps.Done;
Status = EStatus.Succeed;
}
}
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public override void WaitForAsyncComplete()
{
if (IsDone() == false)
{
Status = EStatus.Failed;
LastError = $"{nameof(WaitForAsyncComplete)} failed ! WebGL platform not support sync load method !";
YooLogger.Error(LastError);
}
}
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public override void WaitForAsyncComplete()
{
if (IsDone() == false)
{
Status = EStatus.Failed;
LastError = $"{nameof(WaitForAsyncComplete)} failed ! WebGL platform not support sync load method !";
YooLogger.Error(LastError);
}
}
}
}

View File

@ -5,177 +5,177 @@ using UnityEngine;
namespace YooAsset
{
internal abstract class BundleLoaderBase
{
public enum EStatus
{
None = 0,
Succeed,
Failed
}
internal abstract class BundleLoaderBase
{
public enum EStatus
{
None = 0,
Succeed,
Failed
}
/// <summary>
/// 所属资源系统
/// </summary>
public ResourceManager Impl { private set; get; }
/// <summary>
/// 所属资源系统
/// </summary>
public ResourceManager Impl { private set; get; }
/// <summary>
/// 资源包文件信息
/// </summary>
public BundleInfo MainBundleInfo { private set; get; }
/// <summary>
/// 资源包文件信息
/// </summary>
public BundleInfo MainBundleInfo { private set; get; }
/// <summary>
/// 引用计数
/// </summary>
public int RefCount { private set; get; }
/// <summary>
/// 引用计数
/// </summary>
public int RefCount { private set; get; }
/// <summary>
/// 加载状态
/// </summary>
public EStatus Status { protected set; get; }
/// <summary>
/// 加载状态
/// </summary>
public EStatus Status { protected set; get; }
/// <summary>
/// 最近的错误信息
/// </summary>
public string LastError { protected set; get; }
/// <summary>
/// 最近的错误信息
/// </summary>
public string LastError { protected set; get; }
/// <summary>
/// 是否已经销毁
/// </summary>
public bool IsDestroyed { private set; get; } = false;
/// <summary>
/// 是否已经销毁
/// </summary>
public bool IsDestroyed { private set; get; } = false;
private readonly List<ProviderBase> _providers = new List<ProviderBase>(100);
private readonly List<ProviderBase> _removeList = new List<ProviderBase>(100);
protected bool IsForceDestroyComplete { private set; get; } = false;
internal AssetBundle CacheBundle { set; get; }
internal string FileLoadPath { set; get; }
internal float DownloadProgress { set; get; }
internal ulong DownloadedBytes { set; get; }
private readonly List<ProviderBase> _providers = new List<ProviderBase>(100);
private readonly List<ProviderBase> _removeList = new List<ProviderBase>(100);
protected bool IsForceDestroyComplete { private set; get; } = false;
internal AssetBundle CacheBundle { set; get; }
internal string FileLoadPath { set; get; }
internal float DownloadProgress { set; get; }
internal ulong DownloadedBytes { set; get; }
public BundleLoaderBase(ResourceManager impl, BundleInfo bundleInfo)
{
Impl = impl;
MainBundleInfo = bundleInfo;
RefCount = 0;
Status = EStatus.None;
}
public BundleLoaderBase(ResourceManager impl, BundleInfo bundleInfo)
{
Impl = impl;
MainBundleInfo = bundleInfo;
RefCount = 0;
Status = EStatus.None;
}
/// <summary>
/// 引用(引用计数递加)
/// </summary>
public void Reference()
{
RefCount++;
}
/// <summary>
/// 引用(引用计数递加)
/// </summary>
public void Reference()
{
RefCount++;
}
/// <summary>
/// 释放(引用计数递减)
/// </summary>
public void Release()
{
RefCount--;
}
/// <summary>
/// 释放(引用计数递减)
/// </summary>
public void Release()
{
RefCount--;
}
/// <summary>
/// 是否完毕(无论成功或失败)
/// </summary>
public bool IsDone()
{
return Status == EStatus.Succeed || Status == EStatus.Failed;
}
/// <summary>
/// 是否完毕(无论成功或失败)
/// </summary>
public bool IsDone()
{
return Status == EStatus.Succeed || Status == EStatus.Failed;
}
/// <summary>
/// 是否可以销毁
/// </summary>
public bool CanDestroy()
{
if (IsDone() == false)
return false;
/// <summary>
/// 是否可以销毁
/// </summary>
public bool CanDestroy()
{
if (IsDone() == false)
return false;
return RefCount <= 0;
}
return RefCount <= 0;
}
/// <summary>
/// 添加附属的资源提供者
/// </summary>
public void AddProvider(ProviderBase provider)
{
if (_providers.Contains(provider) == false)
_providers.Add(provider);
}
/// <summary>
/// 添加附属的资源提供者
/// </summary>
public void AddProvider(ProviderBase provider)
{
if (_providers.Contains(provider) == false)
_providers.Add(provider);
}
/// <summary>
/// 尝试销毁资源提供者
/// </summary>
public void TryDestroyProviders()
{
// 获取移除列表
_removeList.Clear();
foreach (var provider in _providers)
{
if (provider.CanDestroy())
{
_removeList.Add(provider);
}
}
/// <summary>
/// 尝试销毁资源提供者
/// </summary>
public void TryDestroyProviders()
{
// 获取移除列表
_removeList.Clear();
foreach (var provider in _providers)
{
if (provider.CanDestroy())
{
_removeList.Add(provider);
}
}
// 销毁资源提供者
foreach (var provider in _removeList)
{
_providers.Remove(provider);
provider.Destroy();
}
// 销毁资源提供者
foreach (var provider in _removeList)
{
_providers.Remove(provider);
provider.Destroy();
}
// 移除资源提供者
if (_removeList.Count > 0)
{
Impl.RemoveBundleProviders(_removeList);
_removeList.Clear();
}
}
// 移除资源提供者
if (_removeList.Count > 0)
{
Impl.RemoveBundleProviders(_removeList);
_removeList.Clear();
}
}
/// <summary>
/// 轮询更新
/// </summary>
public abstract void Update();
/// <summary>
/// 轮询更新
/// </summary>
public abstract void Update();
/// <summary>
/// 销毁
/// </summary>
public virtual void Destroy()
{
IsDestroyed = true;
/// <summary>
/// 销毁
/// </summary>
public virtual void Destroy()
{
IsDestroyed = true;
// Check fatal
if (RefCount > 0)
throw new Exception($"Bundle file loader ref is not zero : {MainBundleInfo.Bundle.BundleName}");
if (IsDone() == false)
throw new Exception($"Bundle file loader is not done : {MainBundleInfo.Bundle.BundleName}");
// Check fatal
if (RefCount > 0)
throw new Exception($"Bundle file loader ref is not zero : {MainBundleInfo.Bundle.BundleName}");
if (IsDone() == false)
throw new Exception($"Bundle file loader is not done : {MainBundleInfo.Bundle.BundleName}");
if (CacheBundle != null)
{
CacheBundle.Unload(true);
CacheBundle = null;
}
}
if (CacheBundle != null)
{
CacheBundle.Unload(true);
CacheBundle = null;
}
}
/// <summary>
/// 强制销毁资源提供者
/// </summary>
public void ForceDestroyComplete()
{
IsForceDestroyComplete = true;
/// <summary>
/// 强制销毁资源提供者
/// </summary>
public void ForceDestroyComplete()
{
IsForceDestroyComplete = true;
// 注意:主动轮询更新完成同步加载
// 说明:如果正在下载或解压也可以放心销毁。
Update();
}
// 注意:主动轮询更新完成同步加载
// 说明:如果正在下载或解压也可以放心销毁。
Update();
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public abstract void WaitForAsyncComplete();
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public abstract void WaitForAsyncComplete();
}
}

View File

@ -4,109 +4,109 @@ using System.Collections.Generic;
namespace YooAsset
{
internal class DependAssetBundles
{
/// <summary>
/// 依赖的资源包加载器列表
/// </summary>
internal readonly List<BundleLoaderBase> DependList;
internal class DependAssetBundles
{
/// <summary>
/// 依赖的资源包加载器列表
/// </summary>
internal readonly List<BundleLoaderBase> DependList;
public DependAssetBundles(List<BundleLoaderBase> dpendList)
{
DependList = dpendList;
}
public DependAssetBundles(List<BundleLoaderBase> dpendList)
{
DependList = dpendList;
}
/// <summary>
/// 是否已经完成(无论成功或失败)
/// </summary>
public bool IsDone()
{
foreach (var loader in DependList)
{
if (loader.IsDone() == false)
return false;
}
return true;
}
/// <summary>
/// 是否已经完成(无论成功或失败)
/// </summary>
public bool IsDone()
{
foreach (var loader in DependList)
{
if (loader.IsDone() == false)
return false;
}
return true;
}
/// <summary>
/// 依赖资源包是否全部加载成功
/// </summary>
public bool IsSucceed()
{
foreach (var loader in DependList)
{
if (loader.Status != BundleLoaderBase.EStatus.Succeed)
{
return false;
}
}
return true;
}
/// <summary>
/// 依赖资源包是否全部加载成功
/// </summary>
public bool IsSucceed()
{
foreach (var loader in DependList)
{
if (loader.Status != BundleLoaderBase.EStatus.Succeed)
{
return false;
}
}
return true;
}
/// <summary>
/// 获取某个加载失败的资源包错误信息
/// </summary>
public string GetLastError()
{
foreach (var loader in DependList)
{
if (loader.Status != BundleLoaderBase.EStatus.Succeed)
{
return loader.LastError;
}
}
return string.Empty;
}
/// <summary>
/// 获取某个加载失败的资源包错误信息
/// </summary>
public string GetLastError()
{
foreach (var loader in DependList)
{
if (loader.Status != BundleLoaderBase.EStatus.Succeed)
{
return loader.LastError;
}
}
return string.Empty;
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public void WaitForAsyncComplete()
{
foreach (var loader in DependList)
{
if (loader.IsDone() == false)
loader.WaitForAsyncComplete();
}
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public void WaitForAsyncComplete()
{
foreach (var loader in DependList)
{
if (loader.IsDone() == false)
loader.WaitForAsyncComplete();
}
}
/// <summary>
/// 增加引用计数
/// </summary>
public void Reference()
{
foreach (var loader in DependList)
{
loader.Reference();
}
}
/// <summary>
/// 增加引用计数
/// </summary>
public void Reference()
{
foreach (var loader in DependList)
{
loader.Reference();
}
}
/// <summary>
/// 减少引用计数
/// </summary>
public void Release()
{
foreach (var loader in DependList)
{
loader.Release();
}
}
/// <summary>
/// 减少引用计数
/// </summary>
public void Release()
{
foreach (var loader in DependList)
{
loader.Release();
}
}
/// <summary>
/// 获取资源包的调试信息列表
/// </summary>
internal void GetBundleDebugInfos(List<DebugBundleInfo> output)
{
foreach (var loader in DependList)
{
var bundleInfo = new DebugBundleInfo();
bundleInfo.BundleName = loader.MainBundleInfo.Bundle.BundleName;
bundleInfo.RefCount = loader.RefCount;
bundleInfo.Status = loader.Status.ToString();
output.Add(bundleInfo);
}
}
}
/// <summary>
/// 获取资源包的调试信息列表
/// </summary>
internal void GetBundleDebugInfos(List<DebugBundleInfo> output)
{
foreach (var loader in DependList)
{
var bundleInfo = new DebugBundleInfo();
bundleInfo.BundleName = loader.MainBundleInfo.Bundle.BundleName;
bundleInfo.RefCount = loader.RefCount;
bundleInfo.Status = loader.Status.ToString();
output.Add(bundleInfo);
}
}
}
}

View File

@ -2,187 +2,187 @@
namespace YooAsset
{
internal class RawBundleFileLoader : BundleLoaderBase
{
private enum ESteps
{
None,
Download,
CheckDownload,
Unpack,
CheckUnpack,
CheckFile,
Done,
}
internal class RawBundleFileLoader : BundleLoaderBase
{
private enum ESteps
{
None,
Download,
CheckDownload,
Unpack,
CheckUnpack,
CheckFile,
Done,
}
private ESteps _steps = ESteps.None;
private DownloaderBase _unpacker;
private DownloaderBase _downloader;
private ESteps _steps = ESteps.None;
private DownloaderBase _unpacker;
private DownloaderBase _downloader;
public RawBundleFileLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
public RawBundleFileLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
/// <summary>
/// 轮询更新
/// </summary>
public override void Update()
{
if (_steps == ESteps.Done)
return;
/// <summary>
/// 轮询更新
/// </summary>
public override void Update()
{
if (_steps == ESteps.Done)
return;
if (_steps == ESteps.None)
{
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.Download;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
if (_steps == ESteps.None)
{
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.Download;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
#if UNITY_ANDROID
_steps = ESteps.Unpack;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
_steps = ESteps.Unpack;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
#else
_steps = ESteps.CheckFile;
FileLoadPath = MainBundleInfo.BuildinFilePath;
#endif
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
_steps = ESteps.CheckFile;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromDelivery)
{
_steps = ESteps.CheckFile;
FileLoadPath = MainBundleInfo.DeliveryFilePath;
}
else
{
throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
}
}
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
{
_steps = ESteps.CheckFile;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromDelivery)
{
_steps = ESteps.CheckFile;
FileLoadPath = MainBundleInfo.DeliveryFilePath;
}
else
{
throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
}
}
// 1. 下载远端文件
if (_steps == ESteps.Download)
{
_downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
_downloader.SendRequest();
_steps = ESteps.CheckDownload;
}
// 1. 下载远端文件
if (_steps == ESteps.Download)
{
_downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
_downloader.SendRequest();
_steps = ESteps.CheckDownload;
}
// 2. 检测下载结果
if (_steps == ESteps.CheckDownload)
{
DownloadProgress = _downloader.DownloadProgress;
DownloadedBytes = _downloader.DownloadedBytes;
if (_downloader.IsDone() == false)
return;
// 2. 检测下载结果
if (_steps == ESteps.CheckDownload)
{
DownloadProgress = _downloader.DownloadProgress;
DownloadedBytes = _downloader.DownloadedBytes;
if (_downloader.IsDone() == false)
return;
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _downloader.GetLastError();
}
else
{
_steps = ESteps.CheckFile;
}
}
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _downloader.GetLastError();
}
else
{
_steps = ESteps.CheckFile;
}
}
// 3. 解压内置文件
if (_steps == ESteps.Unpack)
{
int failedTryAgain = 1;
_unpacker = MainBundleInfo.CreateUnpacker(failedTryAgain);
_unpacker.SendRequest();
_steps = ESteps.CheckUnpack;
}
// 3. 解压内置文件
if (_steps == ESteps.Unpack)
{
int failedTryAgain = 1;
_unpacker = MainBundleInfo.CreateUnpacker(failedTryAgain);
_unpacker.SendRequest();
_steps = ESteps.CheckUnpack;
}
// 4. 检测解压结果
if (_steps == ESteps.CheckUnpack)
{
DownloadProgress = _unpacker.DownloadProgress;
DownloadedBytes = _unpacker.DownloadedBytes;
if (_unpacker.IsDone() == false)
return;
// 4. 检测解压结果
if (_steps == ESteps.CheckUnpack)
{
DownloadProgress = _unpacker.DownloadProgress;
DownloadedBytes = _unpacker.DownloadedBytes;
if (_unpacker.IsDone() == false)
return;
if (_unpacker.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _unpacker.GetLastError();
}
else
{
_steps = ESteps.CheckFile;
}
}
if (_unpacker.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _unpacker.GetLastError();
}
else
{
_steps = ESteps.CheckFile;
}
}
// 5. 检测结果
if (_steps == ESteps.CheckFile)
{
// 设置下载进度
DownloadProgress = 1f;
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
// 5. 检测结果
if (_steps == ESteps.CheckFile)
{
// 设置下载进度
DownloadProgress = 1f;
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
if (File.Exists(FileLoadPath))
{
_steps = ESteps.Done;
Status = EStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"Raw file not found : {FileLoadPath}";
}
}
}
if (File.Exists(FileLoadPath))
{
_steps = ESteps.Done;
Status = EStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = $"Raw file not found : {FileLoadPath}";
}
}
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public override void WaitForAsyncComplete()
{
int frame = 1000;
while (true)
{
// 文件解压
if (_unpacker != null)
{
if (_unpacker.IsDone() == false)
{
_unpacker.WaitForAsyncComplete = true;
_unpacker.Update();
continue;
}
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public override void WaitForAsyncComplete()
{
int frame = 1000;
while (true)
{
// 文件解压
if (_unpacker != null)
{
if (_unpacker.IsDone() == false)
{
_unpacker.WaitForAsyncComplete = true;
_unpacker.Update();
continue;
}
}
// 保险机制
// 注意:如果需要从远端下载资源,可能会触发保险机制!
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;
}
// 保险机制
// 注意:如果需要从远端下载资源,可能会触发保险机制!
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();
// 驱动流程
Update();
// 完成后退出
if (IsDone())
break;
}
}
}
// 完成后退出
if (IsDone())
break;
}
}
}
}

View File

@ -2,144 +2,144 @@
namespace YooAsset
{
/// <summary>
/// WebGL平台加载器
/// </summary>
internal class RawBundleWebLoader : BundleLoaderBase
{
private enum ESteps
{
None,
Download,
CheckDownload,
Website,
CheckWebsite,
CheckFile,
Done,
}
/// <summary>
/// WebGL平台加载器
/// </summary>
internal class RawBundleWebLoader : BundleLoaderBase
{
private enum ESteps
{
None,
Download,
CheckDownload,
Website,
CheckWebsite,
CheckFile,
Done,
}
private ESteps _steps = ESteps.None;
private DownloaderBase _website;
private DownloaderBase _downloader;
private ESteps _steps = ESteps.None;
private DownloaderBase _website;
private DownloaderBase _downloader;
public RawBundleWebLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
public RawBundleWebLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
/// <summary>
/// 轮询更新
/// </summary>
public override void Update()
{
if (_steps == ESteps.Done)
return;
/// <summary>
/// 轮询更新
/// </summary>
public override void Update()
{
if (_steps == ESteps.Done)
return;
if (_steps == ESteps.None)
{
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.Download;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
_steps = ESteps.Website;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else
{
throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
}
}
if (_steps == ESteps.None)
{
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
{
_steps = ESteps.Download;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
{
_steps = ESteps.Website;
FileLoadPath = MainBundleInfo.CachedDataFilePath;
}
else
{
throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
}
}
// 1. 下载远端文件
if (_steps == ESteps.Download)
{
_downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
_downloader.SendRequest();
_steps = ESteps.CheckDownload;
}
// 1. 下载远端文件
if (_steps == ESteps.Download)
{
_downloader = MainBundleInfo.CreateDownloader(int.MaxValue);
_downloader.SendRequest();
_steps = ESteps.CheckDownload;
}
// 2. 检测下载结果
if (_steps == ESteps.CheckDownload)
{
DownloadProgress = _downloader.DownloadProgress;
DownloadedBytes = _downloader.DownloadedBytes;
if (_downloader.IsDone() == false)
return;
// 2. 检测下载结果
if (_steps == ESteps.CheckDownload)
{
DownloadProgress = _downloader.DownloadProgress;
DownloadedBytes = _downloader.DownloadedBytes;
if (_downloader.IsDone() == false)
return;
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _downloader.GetLastError();
}
else
{
_steps = ESteps.CheckFile;
}
}
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _downloader.GetLastError();
}
else
{
_steps = ESteps.CheckFile;
}
}
// 3. 从站点下载
if (_steps == ESteps.Website)
{
_website = MainBundleInfo.CreateUnpacker(int.MaxValue);
_website.SendRequest();
_steps = ESteps.CheckWebsite;
}
// 3. 从站点下载
if (_steps == ESteps.Website)
{
_website = MainBundleInfo.CreateUnpacker(int.MaxValue);
_website.SendRequest();
_steps = ESteps.CheckWebsite;
}
// 4. 检测站点下载
if (_steps == ESteps.CheckWebsite)
{
DownloadProgress = _website.DownloadProgress;
DownloadedBytes = _website.DownloadedBytes;
if (_website.IsDone() == false)
return;
// 4. 检测站点下载
if (_steps == ESteps.CheckWebsite)
{
DownloadProgress = _website.DownloadProgress;
DownloadedBytes = _website.DownloadedBytes;
if (_website.IsDone() == false)
return;
if (_website.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _website.GetLastError();
}
else
{
_steps = ESteps.CheckFile;
}
}
if (_website.HasError())
{
_steps = ESteps.Done;
Status = EStatus.Failed;
LastError = _website.GetLastError();
}
else
{
_steps = ESteps.CheckFile;
}
}
// 5. 检测结果
if (_steps == ESteps.CheckFile)
{
// 设置下载进度
DownloadProgress = 1f;
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
// 5. 检测结果
if (_steps == ESteps.CheckFile)
{
// 设置下载进度
DownloadProgress = 1f;
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
_steps = ESteps.Done;
if (File.Exists(FileLoadPath))
{
Status = EStatus.Succeed;
}
else
{
Status = EStatus.Failed;
LastError = $"Raw file not found : {FileLoadPath}";
}
}
}
_steps = ESteps.Done;
if (File.Exists(FileLoadPath))
{
Status = EStatus.Succeed;
}
else
{
Status = EStatus.Failed;
LastError = $"Raw file not found : {FileLoadPath}";
}
}
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public override void WaitForAsyncComplete()
{
if (IsDone() == false)
{
Status = EStatus.Failed;
LastError = $"{nameof(WaitForAsyncComplete)} failed ! WebGL platform not support sync load method !";
YooLogger.Error(LastError);
}
}
}
/// <summary>
/// 主线程等待异步操作完毕
/// </summary>
public override void WaitForAsyncComplete()
{
if (IsDone() == false)
{
Status = EStatus.Failed;
LastError = $"{nameof(WaitForAsyncComplete)} failed ! WebGL platform not support sync load method !";
YooLogger.Error(LastError);
}
}
}
}

View File

@ -1,82 +1,82 @@

namespace YooAsset
{
internal class VirtualBundleFileLoader : BundleLoaderBase
{
private enum ESteps
{
None,
CheckFile,
Done,
}
internal class VirtualBundleFileLoader : BundleLoaderBase
{
private enum ESteps
{
None,
CheckFile,
Done,
}
private ESteps _steps = ESteps.None;
private ESteps _steps = ESteps.None;
public VirtualBundleFileLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
public VirtualBundleFileLoader(ResourceManager impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
/// <summary>
/// 轮询更新
/// </summary>
public override void Update()
{
if (_steps == ESteps.Done)
return;
/// <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());
}
}
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;
// 1. 检测结果
if (_steps == ESteps.CheckFile)
{
// 设置下载进度
DownloadProgress = 1f;
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
_steps = ESteps.Done;
Status = EStatus.Succeed;
}
}
_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;
}
/// <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();
// 驱动流程
Update();
// 完成后退出
if (IsDone())
break;
}
}
}
// 完成后退出
if (IsDone())
break;
}
}
}
}

View File

@ -2,131 +2,131 @@
namespace YooAsset
{
public sealed class InstantiateOperation : AsyncOperationBase
{
private enum ESteps
{
None,
Clone,
Done,
}
public sealed class InstantiateOperation : AsyncOperationBase
{
private enum ESteps
{
None,
Clone,
Done,
}
private readonly AssetHandle _handle;
private readonly bool _setPositionAndRotation;
private readonly Vector3 _position;
private readonly Quaternion _rotation;
private readonly Transform _parent;
private readonly bool _worldPositionStays;
private ESteps _steps = ESteps.None;
private readonly AssetHandle _handle;
private readonly bool _setPositionAndRotation;
private readonly Vector3 _position;
private readonly Quaternion _rotation;
private readonly Transform _parent;
private readonly bool _worldPositionStays;
private ESteps _steps = ESteps.None;
/// <summary>
/// 实例化的游戏对象
/// </summary>
public GameObject Result = null;
/// <summary>
/// 实例化的游戏对象
/// </summary>
public GameObject Result = null;
internal InstantiateOperation(AssetHandle handle, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays)
{
_handle = handle;
_setPositionAndRotation = setPositionAndRotation;
_position = position;
_rotation = rotation;
_parent = parent;
_worldPositionStays = worldPositionStays;
}
internal override void InternalOnStart()
{
_steps = ESteps.Clone;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
internal InstantiateOperation(AssetHandle handle, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays)
{
_handle = handle;
_setPositionAndRotation = setPositionAndRotation;
_position = position;
_rotation = rotation;
_parent = parent;
_worldPositionStays = worldPositionStays;
}
internal override void InternalOnStart()
{
_steps = ESteps.Clone;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.Clone)
{
if (_handle.IsValidWithWarning == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(AssetHandle)} is invalid.";
return;
}
if (_steps == ESteps.Clone)
{
if (_handle.IsValidWithWarning == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(AssetHandle)} is invalid.";
return;
}
if (_handle.IsDone == false)
return;
if (_handle.IsDone == false)
return;
if (_handle.AssetObject == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(AssetHandle.AssetObject)} is null.";
return;
}
if (_handle.AssetObject == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(AssetHandle.AssetObject)} is null.";
return;
}
// 实例化游戏对象
Result = InstantiateInternal(_handle.AssetObject, _setPositionAndRotation, _position, _rotation, _parent, _worldPositionStays);
// 实例化游戏对象
Result = InstantiateInternal(_handle.AssetObject, _setPositionAndRotation, _position, _rotation, _parent, _worldPositionStays);
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
/// <summary>
/// 取消实例化对象操作
/// </summary>
public void Cancel()
{
if (IsDone == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"User cancelled !";
}
}
/// <summary>
/// 取消实例化对象操作
/// </summary>
public void Cancel()
{
if (IsDone == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"User cancelled !";
}
}
/// <summary>
/// 等待异步实例化结束
/// </summary>
public void WaitForAsyncComplete()
{
if (_steps == ESteps.Done)
return;
_handle.WaitForAsyncComplete();
InternalOnUpdate();
}
/// <summary>
/// 等待异步实例化结束
/// </summary>
public void WaitForAsyncComplete()
{
if (_steps == ESteps.Done)
return;
_handle.WaitForAsyncComplete();
InternalOnUpdate();
}
internal static GameObject InstantiateInternal(UnityEngine.Object assetObject, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays)
{
if (assetObject == null)
return null;
internal static GameObject InstantiateInternal(UnityEngine.Object assetObject, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays)
{
if (assetObject == null)
return null;
if (setPositionAndRotation)
{
if (parent != null)
{
GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation, parent);
return clone;
}
else
{
GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation);
return clone;
}
}
else
{
if (parent != null)
{
GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject, parent, worldPositionStays);
return clone;
}
else
{
GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject);
return clone;
}
}
}
}
if (setPositionAndRotation)
{
if (parent != null)
{
GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation, parent);
return clone;
}
else
{
GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation);
return clone;
}
}
else
{
if (parent != null)
{
GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject, parent, worldPositionStays);
return clone;
}
else
{
GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject);
return clone;
}
}
}
}
}

View File

@ -3,98 +3,98 @@ using UnityEngine.SceneManagement;
namespace YooAsset
{
/// <summary>
/// 场景卸载异步操作类
/// </summary>
public sealed class UnloadSceneOperation : AsyncOperationBase
{
private enum ESteps
{
None,
CheckError,
PrepareDone,
UnLoadScene,
Checking,
Done,
}
/// <summary>
/// 场景卸载异步操作类
/// </summary>
public sealed class UnloadSceneOperation : AsyncOperationBase
{
private enum ESteps
{
None,
CheckError,
PrepareDone,
UnLoadScene,
Checking,
Done,
}
private ESteps _steps = ESteps.None;
private readonly string _error;
private readonly ProviderBase _provider;
private AsyncOperation _asyncOp;
private ESteps _steps = ESteps.None;
private readonly string _error;
private readonly ProviderBase _provider;
private AsyncOperation _asyncOp;
internal UnloadSceneOperation(string error)
{
_error = error;
}
internal UnloadSceneOperation(ProviderBase provider)
{
_error = null;
_provider = provider;
}
internal override void InternalOnStart()
{
_steps = ESteps.CheckError;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
internal UnloadSceneOperation(string error)
{
_error = error;
}
internal UnloadSceneOperation(ProviderBase provider)
{
_error = null;
_provider = provider;
}
internal override void InternalOnStart()
{
_steps = ESteps.CheckError;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckError)
{
if (string.IsNullOrEmpty(_error) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _error;
return;
}
if (_steps == ESteps.CheckError)
{
if (string.IsNullOrEmpty(_error) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _error;
return;
}
_steps = ESteps.PrepareDone;
}
_steps = ESteps.PrepareDone;
}
if(_steps == ESteps.PrepareDone)
{
if (_provider.IsDone == false)
return;
if (_steps == ESteps.PrepareDone)
{
if (_provider.IsDone == false)
return;
if (_provider.SceneObject.IsValid() == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Scene is invalid !";
return;
}
if (_provider.SceneObject.IsValid() == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Scene is invalid !";
return;
}
if (_provider.SceneObject.isLoaded == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Scene is not loaded !";
return;
}
if (_provider.SceneObject.isLoaded == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Scene is not loaded !";
return;
}
_steps = ESteps.UnLoadScene;
}
_steps = ESteps.UnLoadScene;
}
if (_steps == ESteps.UnLoadScene)
{
_asyncOp = SceneManager.UnloadSceneAsync(_provider.SceneObject);
_provider.ResourceMgr.UnloadSubScene(_provider.SceneName);
_provider.ResourceMgr.TryUnloadUnusedAsset(_provider.MainAssetInfo);
_steps = ESteps.Checking;
}
if (_steps == ESteps.UnLoadScene)
{
_asyncOp = SceneManager.UnloadSceneAsync(_provider.SceneObject);
_provider.ResourceMgr.UnloadSubScene(_provider.SceneName);
_provider.ResourceMgr.TryUnloadUnusedAsset(_provider.MainAssetInfo);
_steps = ESteps.Checking;
}
if (_steps == ESteps.Checking)
{
Progress = _asyncOp.progress;
if (_asyncOp.isDone == false)
return;
if (_steps == ESteps.Checking)
{
Progress = _asyncOp.progress;
if (_asyncOp.isDone == false)
return;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}

View File

@ -4,119 +4,119 @@ using UnityEngine;
namespace YooAsset
{
internal sealed class BundledAllAssetsProvider : ProviderBase
{
private AssetBundleRequest _cacheRequest;
internal sealed class BundledAllAssetsProvider : ProviderBase
{
private AssetBundleRequest _cacheRequest;
public BundledAllAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
if (IsDone)
return;
public BundledAllAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
if (IsDone)
return;
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
DependBundles.WaitForAsyncComplete();
OwnerBundle.WaitForAsyncComplete();
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
DependBundles.WaitForAsyncComplete();
OwnerBundle.WaitForAsyncComplete();
}
if (DependBundles.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
if (DependBundles.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
if (DependBundles.IsSucceed() == false)
{
string error = DependBundles.GetLastError();
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (DependBundles.IsSucceed() == false)
{
string error = DependBundles.GetLastError();
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.CacheBundle == null)
{
ProcessCacheBundleException();
return;
}
if (OwnerBundle.CacheBundle == null)
{
ProcessCacheBundleException();
return;
}
_steps = ESteps.Loading;
}
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{
if (MainAssetInfo.AssetType == null)
AllAssetObjects = OwnerBundle.CacheBundle.LoadAllAssets();
else
AllAssetObjects = OwnerBundle.CacheBundle.LoadAllAssets(MainAssetInfo.AssetType);
}
else
{
if (MainAssetInfo.AssetType == null)
_cacheRequest = OwnerBundle.CacheBundle.LoadAllAssetsAsync();
else
_cacheRequest = OwnerBundle.CacheBundle.LoadAllAssetsAsync(MainAssetInfo.AssetType);
}
_steps = ESteps.Checking;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{
if (MainAssetInfo.AssetType == null)
AllAssetObjects = OwnerBundle.CacheBundle.LoadAllAssets();
else
AllAssetObjects = OwnerBundle.CacheBundle.LoadAllAssets(MainAssetInfo.AssetType);
}
else
{
if (MainAssetInfo.AssetType == null)
_cacheRequest = OwnerBundle.CacheBundle.LoadAllAssetsAsync();
else
_cacheRequest = OwnerBundle.CacheBundle.LoadAllAssetsAsync(MainAssetInfo.AssetType);
}
_steps = ESteps.Checking;
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (_cacheRequest != null)
{
if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset.");
AllAssetObjects = _cacheRequest.allAssets;
}
else
{
Progress = _cacheRequest.progress;
if (_cacheRequest.isDone == false)
return;
AllAssetObjects = _cacheRequest.allAssets;
}
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (_cacheRequest != null)
{
if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset.");
AllAssetObjects = _cacheRequest.allAssets;
}
else
{
Progress = _cacheRequest.progress;
if (_cacheRequest.isDone == false)
return;
AllAssetObjects = _cacheRequest.allAssets;
}
}
if (AllAssetObjects == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
else
error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}
}
if (AllAssetObjects == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
else
error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}
}
}

View File

@ -4,119 +4,119 @@ using UnityEngine;
namespace YooAsset
{
internal sealed class BundledAssetProvider : ProviderBase
{
private AssetBundleRequest _cacheRequest;
internal sealed class BundledAssetProvider : ProviderBase
{
private AssetBundleRequest _cacheRequest;
public BundledAssetProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
if (IsDone)
return;
public BundledAssetProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
if (IsDone)
return;
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
DependBundles.WaitForAsyncComplete();
OwnerBundle.WaitForAsyncComplete();
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
DependBundles.WaitForAsyncComplete();
OwnerBundle.WaitForAsyncComplete();
}
if (DependBundles.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
if (DependBundles.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
if (DependBundles.IsSucceed() == false)
{
string error = DependBundles.GetLastError();
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (DependBundles.IsSucceed() == false)
{
string error = DependBundles.GetLastError();
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.CacheBundle == null)
{
ProcessCacheBundleException();
return;
}
if (OwnerBundle.CacheBundle == null)
{
ProcessCacheBundleException();
return;
}
_steps = ESteps.Loading;
}
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{
if (MainAssetInfo.AssetType == null)
AssetObject = OwnerBundle.CacheBundle.LoadAsset(MainAssetInfo.AssetPath);
else
AssetObject = OwnerBundle.CacheBundle.LoadAsset(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
else
{
if (MainAssetInfo.AssetType == null)
_cacheRequest = OwnerBundle.CacheBundle.LoadAssetAsync(MainAssetInfo.AssetPath);
else
_cacheRequest = OwnerBundle.CacheBundle.LoadAssetAsync(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
_steps = ESteps.Checking;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{
if (MainAssetInfo.AssetType == null)
AssetObject = OwnerBundle.CacheBundle.LoadAsset(MainAssetInfo.AssetPath);
else
AssetObject = OwnerBundle.CacheBundle.LoadAsset(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
else
{
if (MainAssetInfo.AssetType == null)
_cacheRequest = OwnerBundle.CacheBundle.LoadAssetAsync(MainAssetInfo.AssetPath);
else
_cacheRequest = OwnerBundle.CacheBundle.LoadAssetAsync(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
_steps = ESteps.Checking;
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (_cacheRequest != null)
{
if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset.");
AssetObject = _cacheRequest.asset;
}
else
{
Progress = _cacheRequest.progress;
if (_cacheRequest.isDone == false)
return;
AssetObject = _cacheRequest.asset;
}
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (_cacheRequest != null)
{
if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset.");
AssetObject = _cacheRequest.asset;
}
else
{
Progress = _cacheRequest.progress;
if (_cacheRequest.isDone == false)
return;
AssetObject = _cacheRequest.asset;
}
}
if (AssetObject == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
else
error = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}
}
if (AssetObject == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
else
error = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}
}
}

View File

@ -1,52 +1,52 @@

namespace YooAsset
{
internal class BundledRawFileProvider : ProviderBase
{
public BundledRawFileProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
if (IsDone)
return;
internal class BundledRawFileProvider : ProviderBase
{
public BundledRawFileProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
if (IsDone)
return;
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.Checking;
}
_steps = ESteps.Checking;
}
// 2. 检测加载结果
if (_steps == ESteps.Checking)
{
RawFilePath = OwnerBundle.FileLoadPath;
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}
// 2. 检测加载结果
if (_steps == ESteps.Checking)
{
RawFilePath = OwnerBundle.FileLoadPath;
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}
}

View File

@ -6,107 +6,107 @@ using UnityEngine.SceneManagement;
namespace YooAsset
{
internal sealed class BundledSceneProvider : ProviderBase
{
public readonly LoadSceneMode SceneMode;
private readonly bool _suspendLoad;
private AsyncOperation _asyncOperation;
internal sealed class BundledSceneProvider : ProviderBase
{
public readonly LoadSceneMode SceneMode;
private readonly bool _suspendLoad;
private AsyncOperation _asyncOperation;
public BundledSceneProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool suspendLoad) : base(manager, providerGUID, assetInfo)
{
SceneMode = sceneMode;
SceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath);
_suspendLoad = suspendLoad;
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
if (IsDone)
return;
public BundledSceneProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool suspendLoad) : base(manager, providerGUID, assetInfo)
{
SceneMode = sceneMode;
SceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath);
_suspendLoad = suspendLoad;
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
if (IsDone)
return;
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (DependBundles.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (DependBundles.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
if (DependBundles.IsSucceed() == false)
{
string error = DependBundles.GetLastError();
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (DependBundles.IsSucceed() == false)
{
string error = DependBundles.GetLastError();
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.Loading;
}
_steps = ESteps.Loading;
}
// 2. 加载场景
if (_steps == ESteps.Loading)
{
// 注意如果场景不存在则返回NULL
_asyncOperation = SceneManager.LoadSceneAsync(MainAssetInfo.AssetPath, SceneMode);
if (_asyncOperation != null)
{
_asyncOperation.allowSceneActivation = !_suspendLoad;
_asyncOperation.priority = 100;
SceneObject = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
_steps = ESteps.Checking;
}
else
{
string error = $"Failed to load scene : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
}
// 2. 加载场景
if (_steps == ESteps.Loading)
{
// 注意如果场景不存在则返回NULL
_asyncOperation = SceneManager.LoadSceneAsync(MainAssetInfo.AssetPath, SceneMode);
if (_asyncOperation != null)
{
_asyncOperation.allowSceneActivation = !_suspendLoad;
_asyncOperation.priority = 100;
SceneObject = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
_steps = ESteps.Checking;
}
else
{
string error = $"Failed to load scene : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
Progress = _asyncOperation.progress;
if (_asyncOperation.isDone)
{
if (SceneObject.IsValid())
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
else
{
string error = $"The load scene is invalid : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
}
}
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
Progress = _asyncOperation.progress;
if (_asyncOperation.isDone)
{
if (SceneObject.IsValid())
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
else
{
string error = $"The load scene is invalid : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
}
}
}
/// <summary>
/// 解除场景加载挂起操作
/// </summary>
public bool UnSuspendLoad()
{
if (_asyncOperation == null)
return false;
/// <summary>
/// 解除场景加载挂起操作
/// </summary>
public bool UnSuspendLoad()
{
if (_asyncOperation == null)
return false;
_asyncOperation.allowSceneActivation = true;
return true;
}
}
_asyncOperation.allowSceneActivation = true;
return true;
}
}
}

View File

@ -4,119 +4,119 @@ using UnityEngine;
namespace YooAsset
{
internal sealed class BundledSubAssetsProvider : ProviderBase
{
private AssetBundleRequest _cacheRequest;
internal sealed class BundledSubAssetsProvider : ProviderBase
{
private AssetBundleRequest _cacheRequest;
public BundledSubAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
if (IsDone)
return;
public BundledSubAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
if (IsDone)
return;
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
DependBundles.WaitForAsyncComplete();
OwnerBundle.WaitForAsyncComplete();
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
DependBundles.WaitForAsyncComplete();
OwnerBundle.WaitForAsyncComplete();
}
if (DependBundles.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
if (DependBundles.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
if (DependBundles.IsSucceed() == false)
{
string error = DependBundles.GetLastError();
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (DependBundles.IsSucceed() == false)
{
string error = DependBundles.GetLastError();
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.CacheBundle == null)
{
ProcessCacheBundleException();
return;
}
if (OwnerBundle.CacheBundle == null)
{
ProcessCacheBundleException();
return;
}
_steps = ESteps.Loading;
}
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{
if (MainAssetInfo.AssetType == null)
AllAssetObjects = OwnerBundle.CacheBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath);
else
AllAssetObjects = OwnerBundle.CacheBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
else
{
if (MainAssetInfo.AssetType == null)
_cacheRequest = OwnerBundle.CacheBundle.LoadAssetWithSubAssetsAsync(MainAssetInfo.AssetPath);
else
_cacheRequest = OwnerBundle.CacheBundle.LoadAssetWithSubAssetsAsync(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
_steps = ESteps.Checking;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{
if (MainAssetInfo.AssetType == null)
AllAssetObjects = OwnerBundle.CacheBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath);
else
AllAssetObjects = OwnerBundle.CacheBundle.LoadAssetWithSubAssets(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
else
{
if (MainAssetInfo.AssetType == null)
_cacheRequest = OwnerBundle.CacheBundle.LoadAssetWithSubAssetsAsync(MainAssetInfo.AssetPath);
else
_cacheRequest = OwnerBundle.CacheBundle.LoadAssetWithSubAssetsAsync(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
}
_steps = ESteps.Checking;
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (_cacheRequest != null)
{
if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset.");
AllAssetObjects = _cacheRequest.allAssets;
}
else
{
Progress = _cacheRequest.progress;
if (_cacheRequest.isDone == false)
return;
AllAssetObjects = _cacheRequest.allAssets;
}
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (_cacheRequest != null)
{
if (IsWaitForAsyncComplete || IsForceDestroyComplete)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset.");
AllAssetObjects = _cacheRequest.allAssets;
}
else
{
Progress = _cacheRequest.progress;
if (_cacheRequest.isDone == false)
return;
AllAssetObjects = _cacheRequest.allAssets;
}
}
if (AllAssetObjects == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
else
error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}
}
if (AllAssetObjects == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
else
error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
}
}
}

View File

@ -1,25 +1,25 @@

namespace YooAsset
{
internal sealed class CompletedProvider : ProviderBase
{
public CompletedProvider(AssetInfo assetInfo) : base(null, string.Empty, assetInfo)
{
}
internal sealed class CompletedProvider : ProviderBase
{
public CompletedProvider(AssetInfo assetInfo) : base(null, string.Empty, assetInfo)
{
}
internal override void InternalOnStart()
{
}
internal override void InternalOnUpdate()
{
}
internal override void InternalOnStart()
{
}
internal override void InternalOnUpdate()
{
}
public void SetCompleted(string error)
{
if (_steps == ESteps.None)
{
InvokeCompletion(error, EOperationStatus.Failed);
}
}
}
public void SetCompleted(string error)
{
if (_steps == ESteps.None)
{
InvokeCompletion(error, EOperationStatus.Failed);
}
}
}
}

View File

@ -4,108 +4,108 @@ using UnityEngine;
namespace YooAsset
{
internal sealed class DatabaseAllAssetsProvider : ProviderBase
{
public DatabaseAllAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
internal sealed class DatabaseAllAssetsProvider : ProviderBase
{
public DatabaseAllAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
#if UNITY_EDITOR
if (IsDone)
return;
if (IsDone)
return;
if (_steps == ESteps.None)
{
// 检测资源文件是否存在
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
string error = $"Not found asset : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (_steps == ESteps.None)
{
// 检测资源文件是否存在
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
string error = $"Not found asset : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.CheckBundle;
_steps = ESteps.CheckBundle;
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.Loading;
}
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (MainAssetInfo.AssetType == null)
{
List<UnityEngine.Object> result = new List<Object>();
foreach (var assetPath in OwnerBundle.MainBundleInfo.IncludeAssetsInEditor)
{
UnityEngine.Object mainAsset = UnityEditor.AssetDatabase.LoadMainAssetAtPath(assetPath);
if (mainAsset != null)
result.Add(mainAsset);
}
AllAssetObjects = result.ToArray();
}
else
{
List<UnityEngine.Object> result = new List<Object>();
foreach (var assetPath in OwnerBundle.MainBundleInfo.IncludeAssetsInEditor)
{
UnityEngine.Object mainAsset = UnityEditor.AssetDatabase.LoadAssetAtPath(assetPath, MainAssetInfo.AssetType);
if (mainAsset != null)
result.Add(mainAsset);
}
AllAssetObjects = result.ToArray();
}
_steps = ESteps.Checking;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (MainAssetInfo.AssetType == null)
{
List<UnityEngine.Object> result = new List<Object>();
foreach (var assetPath in OwnerBundle.MainBundleInfo.IncludeAssetsInEditor)
{
UnityEngine.Object mainAsset = UnityEditor.AssetDatabase.LoadMainAssetAtPath(assetPath);
if (mainAsset != null)
result.Add(mainAsset);
}
AllAssetObjects = result.ToArray();
}
else
{
List<UnityEngine.Object> result = new List<Object>();
foreach (var assetPath in OwnerBundle.MainBundleInfo.IncludeAssetsInEditor)
{
UnityEngine.Object mainAsset = UnityEditor.AssetDatabase.LoadAssetAtPath(assetPath, MainAssetInfo.AssetType);
if (mainAsset != null)
result.Add(mainAsset);
}
AllAssetObjects = result.ToArray();
}
_steps = ESteps.Checking;
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (AllAssetObjects == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : null";
else
error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (AllAssetObjects == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : null";
else
error = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
#endif
}
}
}
}
}

View File

@ -4,90 +4,90 @@ using UnityEngine;
namespace YooAsset
{
internal sealed class DatabaseAssetProvider : ProviderBase
{
public DatabaseAssetProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
internal sealed class DatabaseAssetProvider : ProviderBase
{
public DatabaseAssetProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
#if UNITY_EDITOR
if (IsDone)
return;
if (IsDone)
return;
if (_steps == ESteps.None)
{
// 检测资源文件是否存在
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
string error = $"Not found asset : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (_steps == ESteps.None)
{
// 检测资源文件是否存在
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
string error = $"Not found asset : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.CheckBundle;
_steps = ESteps.CheckBundle;
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.Loading;
}
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (MainAssetInfo.AssetType == null)
AssetObject = UnityEditor.AssetDatabase.LoadMainAssetAtPath(MainAssetInfo.AssetPath);
else
AssetObject = UnityEditor.AssetDatabase.LoadAssetAtPath(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
_steps = ESteps.Checking;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (MainAssetInfo.AssetType == null)
AssetObject = UnityEditor.AssetDatabase.LoadMainAssetAtPath(MainAssetInfo.AssetPath);
else
AssetObject = UnityEditor.AssetDatabase.LoadAssetAtPath(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
_steps = ESteps.Checking;
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (AssetObject == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load asset object : {MainAssetInfo.AssetPath} AssetType : null";
else
error = $"Failed to load asset object : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (AssetObject == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load asset object : {MainAssetInfo.AssetPath} AssetType : null";
else
error = $"Failed to load asset object : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
#endif
}
}
}
}
}

View File

@ -1,68 +1,68 @@

namespace YooAsset
{
internal class DatabaseRawFileProvider : ProviderBase
{
public DatabaseRawFileProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
internal class DatabaseRawFileProvider : ProviderBase
{
public DatabaseRawFileProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
#if UNITY_EDITOR
if (IsDone)
return;
if (IsDone)
return;
if (_steps == ESteps.None)
{
// 检测资源文件是否存在
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
string error = $"Not found asset : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (_steps == ESteps.None)
{
// 检测资源文件是否存在
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
string error = $"Not found asset : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.CheckBundle;
_steps = ESteps.CheckBundle;
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.Checking;
}
_steps = ESteps.Checking;
}
// 2. 检测加载结果
if (_steps == ESteps.Checking)
{
RawFilePath = MainAssetInfo.AssetPath;
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
// 2. 检测加载结果
if (_steps == ESteps.Checking)
{
RawFilePath = MainAssetInfo.AssetPath;
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
#endif
}
}
}
}
}

View File

@ -6,106 +6,106 @@ using UnityEngine.SceneManagement;
namespace YooAsset
{
internal sealed class DatabaseSceneProvider : ProviderBase
{
public readonly LoadSceneMode SceneMode;
private readonly bool _suspendLoad;
private AsyncOperation _asyncOperation;
internal sealed class DatabaseSceneProvider : ProviderBase
{
public readonly LoadSceneMode SceneMode;
private readonly bool _suspendLoad;
private AsyncOperation _asyncOperation;
public DatabaseSceneProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool suspendLoad) : base(manager, providerGUID, assetInfo)
{
SceneMode = sceneMode;
SceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath);
_suspendLoad = suspendLoad;
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
public DatabaseSceneProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool suspendLoad) : base(manager, providerGUID, assetInfo)
{
SceneMode = sceneMode;
SceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath);
_suspendLoad = suspendLoad;
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
#if UNITY_EDITOR
if (IsDone)
return;
if (IsDone)
return;
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
if (_steps == ESteps.None)
{
_steps = ESteps.CheckBundle;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.Loading;
}
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
LoadSceneParameters loadSceneParameters = new LoadSceneParameters();
loadSceneParameters.loadSceneMode = SceneMode;
_asyncOperation = UnityEditor.SceneManagement.EditorSceneManager.LoadSceneAsyncInPlayMode(MainAssetInfo.AssetPath, loadSceneParameters);
if (_asyncOperation != null)
{
_asyncOperation.allowSceneActivation = !_suspendLoad;
_asyncOperation.priority = 100;
SceneObject = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
_steps = ESteps.Checking;
}
else
{
string error = $"Failed to load scene : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
LoadSceneParameters loadSceneParameters = new LoadSceneParameters();
loadSceneParameters.loadSceneMode = SceneMode;
_asyncOperation = UnityEditor.SceneManagement.EditorSceneManager.LoadSceneAsyncInPlayMode(MainAssetInfo.AssetPath, loadSceneParameters);
if (_asyncOperation != null)
{
_asyncOperation.allowSceneActivation = !_suspendLoad;
_asyncOperation.priority = 100;
SceneObject = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
_steps = ESteps.Checking;
}
else
{
string error = $"Failed to load scene : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
Progress = _asyncOperation.progress;
if (_asyncOperation.isDone)
{
if (SceneObject.IsValid())
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
else
{
string error = $"The loaded scene is invalid : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
}
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
Progress = _asyncOperation.progress;
if (_asyncOperation.isDone)
{
if (SceneObject.IsValid())
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
else
{
string error = $"The loaded scene is invalid : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
}
}
#endif
}
}
/// <summary>
/// 解除场景加载挂起操作
/// </summary>
public bool UnSuspendLoad()
{
if (_asyncOperation == null)
return false;
/// <summary>
/// 解除场景加载挂起操作
/// </summary>
public bool UnSuspendLoad()
{
if (_asyncOperation == null)
return false;
_asyncOperation.allowSceneActivation = true;
return true;
}
}
_asyncOperation.allowSceneActivation = true;
return true;
}
}
}

View File

@ -4,101 +4,101 @@ using UnityEngine;
namespace YooAsset
{
internal sealed class DatabaseSubAssetsProvider : ProviderBase
{
public DatabaseSubAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
internal sealed class DatabaseSubAssetsProvider : ProviderBase
{
public DatabaseSubAssetsProvider(ResourceManager manager, string providerGUID, AssetInfo assetInfo) : base(manager, providerGUID, assetInfo)
{
}
internal override void InternalOnStart()
{
DebugBeginRecording();
}
internal override void InternalOnUpdate()
{
#if UNITY_EDITOR
if (IsDone)
return;
if (IsDone)
return;
if (_steps == ESteps.None)
{
// 检测资源文件是否存在
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
string error = $"Not found asset : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (_steps == ESteps.None)
{
// 检测资源文件是否存在
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
string error = $"Not found asset : {MainAssetInfo.AssetPath}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.CheckBundle;
_steps = ESteps.CheckBundle;
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
// 1. 检测资源包
if (_steps == ESteps.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
string error = OwnerBundle.LastError;
InvokeCompletion(error, EOperationStatus.Failed);
return;
}
_steps = ESteps.Loading;
}
_steps = ESteps.Loading;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (MainAssetInfo.AssetType == null)
{
AllAssetObjects = UnityEditor.AssetDatabase.LoadAllAssetRepresentationsAtPath(MainAssetInfo.AssetPath);
}
else
{
UnityEngine.Object[] findAssets = UnityEditor.AssetDatabase.LoadAllAssetRepresentationsAtPath(MainAssetInfo.AssetPath);
List<UnityEngine.Object> result = new List<Object>(findAssets.Length);
foreach (var findAsset in findAssets)
{
if (MainAssetInfo.AssetType.IsAssignableFrom(findAsset.GetType()))
result.Add(findAsset);
}
AllAssetObjects = result.ToArray();
}
_steps = ESteps.Checking;
}
// 2. 加载资源对象
if (_steps == ESteps.Loading)
{
if (MainAssetInfo.AssetType == null)
{
AllAssetObjects = UnityEditor.AssetDatabase.LoadAllAssetRepresentationsAtPath(MainAssetInfo.AssetPath);
}
else
{
UnityEngine.Object[] findAssets = UnityEditor.AssetDatabase.LoadAllAssetRepresentationsAtPath(MainAssetInfo.AssetPath);
List<UnityEngine.Object> result = new List<Object>(findAssets.Length);
foreach (var findAsset in findAssets)
{
if (MainAssetInfo.AssetType.IsAssignableFrom(findAsset.GetType()))
result.Add(findAsset);
}
AllAssetObjects = result.ToArray();
}
_steps = ESteps.Checking;
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (AllAssetObjects == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null";
else
error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
// 3. 检测加载结果
if (_steps == ESteps.Checking)
{
if (AllAssetObjects == null)
{
string error;
if (MainAssetInfo.AssetType == null)
error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null";
else
error = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType}";
YooLogger.Error(error);
InvokeCompletion(error, EOperationStatus.Failed);
}
else
{
InvokeCompletion(string.Empty, EOperationStatus.Succeed);
}
}
#endif
}
}
}
}
}

View File

@ -6,339 +6,339 @@ using System;
namespace YooAsset
{
internal abstract class ProviderBase : AsyncOperationBase
{
protected enum ESteps
{
None = 0,
CheckBundle,
Loading,
Checking,
Done,
}
internal abstract class ProviderBase : AsyncOperationBase
{
protected enum ESteps
{
None = 0,
CheckBundle,
Loading,
Checking,
Done,
}
/// <summary>
/// 资源提供者唯一标识符
/// </summary>
public string ProviderGUID { private set; get; }
/// <summary>
/// 资源提供者唯一标识符
/// </summary>
public string ProviderGUID { private set; get; }
/// <summary>
/// 所属资源系统
/// </summary>
public ResourceManager ResourceMgr { private set; get; }
/// <summary>
/// 所属资源系统
/// </summary>
public ResourceManager ResourceMgr { private set; get; }
/// <summary>
/// 资源信息
/// </summary>
public AssetInfo MainAssetInfo { private set; get; }
/// <summary>
/// 资源信息
/// </summary>
public AssetInfo MainAssetInfo { private set; get; }
/// <summary>
/// 获取的资源对象
/// </summary>
public UnityEngine.Object AssetObject { protected set; get; }
/// <summary>
/// 获取的资源对象
/// </summary>
public UnityEngine.Object AssetObject { protected set; get; }
/// <summary>
/// 获取的资源对象集合
/// </summary>
public UnityEngine.Object[] AllAssetObjects { protected set; get; }
/// <summary>
/// 获取的资源对象集合
/// </summary>
public UnityEngine.Object[] AllAssetObjects { protected set; get; }
/// <summary>
/// 获取的场景对象
/// </summary>
public UnityEngine.SceneManagement.Scene SceneObject { protected set; get; }
/// <summary>
/// 获取的场景对象
/// </summary>
public UnityEngine.SceneManagement.Scene SceneObject { protected set; get; }
/// <summary>
/// 加载的场景名称
/// </summary>
public string SceneName { protected set; get; }
/// <summary>
/// 加载的场景名称
/// </summary>
public string SceneName { protected set; get; }
/// <summary>
/// 原生文件路径
/// </summary>
public string RawFilePath { protected set; get; }
/// <summary>
/// 原生文件路径
/// </summary>
public string RawFilePath { protected set; get; }
/// <summary>
/// 引用计数
/// </summary>
public int RefCount { private set; get; } = 0;
/// <summary>
/// 引用计数
/// </summary>
public int RefCount { private set; get; } = 0;
/// <summary>
/// 是否已经销毁
/// </summary>
public bool IsDestroyed { private set; get; } = false;
/// <summary>
/// 是否已经销毁
/// </summary>
public bool IsDestroyed { private set; get; } = false;
protected ESteps _steps = ESteps.None;
protected BundleLoaderBase OwnerBundle { private set; get; }
protected DependAssetBundles DependBundles { private set; get; }
protected bool IsWaitForAsyncComplete { private set; get; } = false;
protected bool IsForceDestroyComplete { private set; get; } = false;
private readonly List<HandleBase> _handles = new List<HandleBase>();
protected ESteps _steps = ESteps.None;
protected BundleLoaderBase OwnerBundle { private set; get; }
protected DependAssetBundles DependBundles { private set; get; }
protected bool IsWaitForAsyncComplete { private set; get; } = false;
protected bool IsForceDestroyComplete { private set; get; } = false;
private readonly List<HandleBase> _handles = new List<HandleBase>();
public ProviderBase(ResourceManager manager, string providerGUID, AssetInfo assetInfo)
{
ResourceMgr = manager;
ProviderGUID = providerGUID;
MainAssetInfo = assetInfo;
public ProviderBase(ResourceManager manager, string providerGUID, AssetInfo assetInfo)
{
ResourceMgr = manager;
ProviderGUID = providerGUID;
MainAssetInfo = assetInfo;
// 创建资源包加载器
if (manager != null)
{
OwnerBundle = manager.CreateOwnerAssetBundleLoader(assetInfo);
OwnerBundle.Reference();
OwnerBundle.AddProvider(this);
// 创建资源包加载器
if (manager != null)
{
OwnerBundle = manager.CreateOwnerAssetBundleLoader(assetInfo);
OwnerBundle.Reference();
OwnerBundle.AddProvider(this);
var dependList = manager.CreateDependAssetBundleLoaders(assetInfo);
DependBundles = new DependAssetBundles(dependList);
DependBundles.Reference();
}
}
var dependList = manager.CreateDependAssetBundleLoaders(assetInfo);
DependBundles = new DependAssetBundles(dependList);
DependBundles.Reference();
}
}
/// <summary>
/// 销毁资源提供者
/// </summary>
public void Destroy()
{
IsDestroyed = true;
/// <summary>
/// 销毁资源提供者
/// </summary>
public void Destroy()
{
IsDestroyed = true;
// 检测是否为正常销毁
if (IsDone == false)
{
Error = "User abort !";
Status = EOperationStatus.Failed;
}
// 检测是否为正常销毁
if (IsDone == false)
{
Error = "User abort !";
Status = EOperationStatus.Failed;
}
// 释放资源包加载器
if (OwnerBundle != null)
{
OwnerBundle.Release();
OwnerBundle = null;
}
if (DependBundles != null)
{
DependBundles.Release();
DependBundles = null;
}
}
// 释放资源包加载器
if (OwnerBundle != null)
{
OwnerBundle.Release();
OwnerBundle = null;
}
if (DependBundles != null)
{
DependBundles.Release();
DependBundles = null;
}
}
/// <summary>
/// 是否可以销毁
/// </summary>
public bool CanDestroy()
{
// 注意:在进行资源加载过程时不可以销毁
if (_steps == ESteps.Loading || _steps == ESteps.Checking)
return false;
/// <summary>
/// 是否可以销毁
/// </summary>
public bool CanDestroy()
{
// 注意:在进行资源加载过程时不可以销毁
if (_steps == ESteps.Loading || _steps == ESteps.Checking)
return false;
return RefCount <= 0;
}
return RefCount <= 0;
}
/// <summary>
/// 创建资源句柄
/// </summary>
public T CreateHandle<T>() where T : HandleBase
{
// 引用计数增加
RefCount++;
/// <summary>
/// 创建资源句柄
/// </summary>
public T CreateHandle<T>() where T : HandleBase
{
// 引用计数增加
RefCount++;
HandleBase handle;
if (typeof(T) == typeof(AssetHandle))
handle = new AssetHandle(this);
else if (typeof(T) == typeof(SceneHandle))
handle = new SceneHandle(this);
else if (typeof(T) == typeof(SubAssetsHandle))
handle = new SubAssetsHandle(this);
else if (typeof(T) == typeof(AllAssetsHandle))
handle = new AllAssetsHandle(this);
else if (typeof(T) == typeof(RawFileHandle))
handle = new RawFileHandle(this);
else
throw new System.NotImplementedException();
HandleBase handle;
if (typeof(T) == typeof(AssetHandle))
handle = new AssetHandle(this);
else if (typeof(T) == typeof(SceneHandle))
handle = new SceneHandle(this);
else if (typeof(T) == typeof(SubAssetsHandle))
handle = new SubAssetsHandle(this);
else if (typeof(T) == typeof(AllAssetsHandle))
handle = new AllAssetsHandle(this);
else if (typeof(T) == typeof(RawFileHandle))
handle = new RawFileHandle(this);
else
throw new System.NotImplementedException();
_handles.Add(handle);
return handle as T;
}
_handles.Add(handle);
return handle as T;
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void ReleaseHandle(HandleBase handle)
{
if (RefCount <= 0)
throw new System.Exception("Should never get here !");
/// <summary>
/// 释放资源句柄
/// </summary>
public void ReleaseHandle(HandleBase handle)
{
if (RefCount <= 0)
throw new System.Exception("Should never get here !");
if (_handles.Remove(handle) == false)
throw new System.Exception("Should never get here !");
if (_handles.Remove(handle) == false)
throw new System.Exception("Should never get here !");
// 引用计数减少
RefCount--;
}
// 引用计数减少
RefCount--;
}
/// <summary>
/// 释放所有资源句柄
/// </summary>
public void ReleaseAllHandles()
{
for (int i = _handles.Count - 1; i >= 0; i--)
{
var handle = _handles[i];
handle.ReleaseInternal();
}
}
/// <summary>
/// 释放所有资源句柄
/// </summary>
public void ReleaseAllHandles()
{
for (int i = _handles.Count - 1; i >= 0; i--)
{
var handle = _handles[i];
handle.ReleaseInternal();
}
}
/// <summary>
/// 等待异步执行完毕
/// </summary>
public void WaitForAsyncComplete()
{
IsWaitForAsyncComplete = true;
/// <summary>
/// 等待异步执行完毕
/// </summary>
public void WaitForAsyncComplete()
{
IsWaitForAsyncComplete = true;
// 注意:主动轮询更新完成同步加载
InternalOnUpdate();
// 注意:主动轮询更新完成同步加载
InternalOnUpdate();
// 验证结果
if (IsDone == false)
{
YooLogger.Warning($"{nameof(WaitForAsyncComplete)} failed to loading : {MainAssetInfo.AssetPath}");
}
}
// 验证结果
if (IsDone == false)
{
YooLogger.Warning($"{nameof(WaitForAsyncComplete)} failed to loading : {MainAssetInfo.AssetPath}");
}
}
/// <summary>
/// 强制销毁资源提供者
/// </summary>
public void ForceDestroyComplete()
{
IsForceDestroyComplete = true;
/// <summary>
/// 强制销毁资源提供者
/// </summary>
public void ForceDestroyComplete()
{
IsForceDestroyComplete = true;
// 注意:主动轮询更新完成同步加载
// 说明:如果资源包未准备完毕也可以放心销毁。
InternalOnUpdate();
}
// 注意:主动轮询更新完成同步加载
// 说明:如果资源包未准备完毕也可以放心销毁。
InternalOnUpdate();
}
/// <summary>
/// 处理特殊异常
/// </summary>
protected void ProcessCacheBundleException()
{
if (OwnerBundle.IsDestroyed)
throw new System.Exception("Should never get here !");
/// <summary>
/// 处理特殊异常
/// </summary>
protected void ProcessCacheBundleException()
{
if (OwnerBundle.IsDestroyed)
throw new System.Exception("Should never get here !");
string error = $"The bundle {OwnerBundle.MainBundleInfo.Bundle.BundleName} has been destroyed by unity bugs !";
YooLogger.Error(error);
InvokeCompletion(Error, EOperationStatus.Failed);
}
string error = $"The bundle {OwnerBundle.MainBundleInfo.Bundle.BundleName} has been destroyed by unity bugs !";
YooLogger.Error(error);
InvokeCompletion(Error, EOperationStatus.Failed);
}
/// <summary>
/// 结束流程
/// </summary>
protected void InvokeCompletion(string error, EOperationStatus status)
{
DebugEndRecording();
/// <summary>
/// 结束流程
/// </summary>
protected void InvokeCompletion(string error, EOperationStatus status)
{
DebugEndRecording();
_steps = ESteps.Done;
Error = error;
Status = status;
_steps = ESteps.Done;
Error = error;
Status = status;
// 注意:创建临时列表是为了防止外部逻辑在回调函数内创建或者释放资源句柄。
// 注意:回调方法如果发生异常,会阻断列表里的后续回调方法!
List<HandleBase> tempers = new List<HandleBase>(_handles);
foreach (var hande in tempers)
{
if (hande.IsValid)
{
hande.InvokeCallback();
}
}
}
// 注意:创建临时列表是为了防止外部逻辑在回调函数内创建或者释放资源句柄。
// 注意:回调方法如果发生异常,会阻断列表里的后续回调方法!
List<HandleBase> tempers = new List<HandleBase>(_handles);
foreach (var hande in tempers)
{
if (hande.IsValid)
{
hande.InvokeCallback();
}
}
}
#region 调试信息相关
/// <summary>
/// 出生的场景
/// </summary>
public string SpawnScene = string.Empty;
#region 调试信息相关
/// <summary>
/// 出生的场景
/// </summary>
public string SpawnScene = string.Empty;
/// <summary>
/// 出生的时间
/// </summary>
public string SpawnTime = string.Empty;
/// <summary>
/// 出生的时间
/// </summary>
public string SpawnTime = string.Empty;
/// <summary>
/// 加载耗时(单位:毫秒)
/// </summary>
public long LoadingTime { protected set; get; }
/// <summary>
/// 加载耗时(单位:毫秒)
/// </summary>
public long LoadingTime { protected set; get; }
// 加载耗时统计
private Stopwatch _watch = null;
// 加载耗时统计
private Stopwatch _watch = null;
[Conditional("DEBUG")]
public void InitSpawnDebugInfo()
{
SpawnScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; ;
SpawnTime = SpawnTimeToString(UnityEngine.Time.realtimeSinceStartup);
}
private string SpawnTimeToString(float spawnTime)
{
float h = UnityEngine.Mathf.FloorToInt(spawnTime / 3600f);
float m = UnityEngine.Mathf.FloorToInt(spawnTime / 60f - h * 60f);
float s = UnityEngine.Mathf.FloorToInt(spawnTime - m * 60f - h * 3600f);
return h.ToString("00") + ":" + m.ToString("00") + ":" + s.ToString("00");
}
[Conditional("DEBUG")]
public void InitSpawnDebugInfo()
{
SpawnScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; ;
SpawnTime = SpawnTimeToString(UnityEngine.Time.realtimeSinceStartup);
}
private string SpawnTimeToString(float spawnTime)
{
float h = UnityEngine.Mathf.FloorToInt(spawnTime / 3600f);
float m = UnityEngine.Mathf.FloorToInt(spawnTime / 60f - h * 60f);
float s = UnityEngine.Mathf.FloorToInt(spawnTime - m * 60f - h * 3600f);
return h.ToString("00") + ":" + m.ToString("00") + ":" + s.ToString("00");
}
[Conditional("DEBUG")]
protected void DebugBeginRecording()
{
if (_watch == null)
{
_watch = Stopwatch.StartNew();
}
}
[Conditional("DEBUG")]
protected void DebugBeginRecording()
{
if (_watch == null)
{
_watch = Stopwatch.StartNew();
}
}
[Conditional("DEBUG")]
private void DebugEndRecording()
{
if (_watch != null)
{
LoadingTime = _watch.ElapsedMilliseconds;
_watch = null;
}
}
[Conditional("DEBUG")]
private void DebugEndRecording()
{
if (_watch != null)
{
LoadingTime = _watch.ElapsedMilliseconds;
_watch = null;
}
}
/// <summary>
/// 获取下载报告
/// </summary>
internal DownloadStatus GetDownloadStatus()
{
DownloadStatus status = new DownloadStatus();
status.TotalBytes = (ulong)OwnerBundle.MainBundleInfo.Bundle.FileSize;
status.DownloadedBytes = OwnerBundle.DownloadedBytes;
foreach (var dependBundle in DependBundles.DependList)
{
status.TotalBytes += (ulong)dependBundle.MainBundleInfo.Bundle.FileSize;
status.DownloadedBytes += dependBundle.DownloadedBytes;
}
/// <summary>
/// 获取下载报告
/// </summary>
internal DownloadStatus GetDownloadStatus()
{
DownloadStatus status = new DownloadStatus();
status.TotalBytes = (ulong)OwnerBundle.MainBundleInfo.Bundle.FileSize;
status.DownloadedBytes = OwnerBundle.DownloadedBytes;
foreach (var dependBundle in DependBundles.DependList)
{
status.TotalBytes += (ulong)dependBundle.MainBundleInfo.Bundle.FileSize;
status.DownloadedBytes += dependBundle.DownloadedBytes;
}
if (status.TotalBytes == 0)
throw new System.Exception("Should never get here !");
if (status.TotalBytes == 0)
throw new System.Exception("Should never get here !");
status.IsDone = status.DownloadedBytes == status.TotalBytes;
status.Progress = (float)status.DownloadedBytes / status.TotalBytes;
return status;
}
status.IsDone = status.DownloadedBytes == status.TotalBytes;
status.Progress = (float)status.DownloadedBytes / status.TotalBytes;
return status;
}
/// <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);
/// <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);
DependBundles.GetBundleDebugInfos(output);
}
#endregion
}
DependBundles.GetBundleDebugInfos(output);
}
#endregion
}
}

View File

@ -3,101 +3,101 @@ using UnityEngine;
namespace YooAsset
{
internal class ResourceLoader
{
private IDecryptionServices _decryption;
private IDeliveryLoadServices _delivery;
internal class ResourceLoader
{
private IDecryptionServices _decryption;
private IDeliveryLoadServices _delivery;
public void Init(IDecryptionServices decryption, IDeliveryLoadServices delivery)
{
_decryption = decryption;
_delivery = delivery;
}
public void Init(IDecryptionServices decryption, IDeliveryLoadServices delivery)
{
_decryption = decryption;
_delivery = delivery;
}
/// <summary>
/// 同步加载资源包对象
/// </summary>
public AssetBundle LoadAssetBundle(BundleInfo bundleInfo, string fileLoadPath, out Stream managedStream)
{
managedStream = null;
if (bundleInfo.Bundle.Encrypted)
{
if (_decryption == null)
{
YooLogger.Error($"{nameof(IDecryptionServices)} is null ! when load asset bundle {bundleInfo.Bundle.BundleName}!");
return null;
}
/// <summary>
/// 同步加载资源包对象
/// </summary>
public AssetBundle LoadAssetBundle(BundleInfo bundleInfo, string fileLoadPath, out Stream managedStream)
{
managedStream = null;
if (bundleInfo.Bundle.Encrypted)
{
if (_decryption == null)
{
YooLogger.Error($"{nameof(IDecryptionServices)} is null ! when load asset bundle {bundleInfo.Bundle.BundleName}!");
return null;
}
DecryptFileInfo fileInfo = new DecryptFileInfo();
fileInfo.BundleName = bundleInfo.Bundle.BundleName;
fileInfo.FileLoadPath = fileLoadPath;
fileInfo.ConentCRC = bundleInfo.Bundle.UnityCRC;
return _decryption.LoadAssetBundle(fileInfo, out managedStream);
}
else
{
return AssetBundle.LoadFromFile(fileLoadPath);
}
}
DecryptFileInfo fileInfo = new DecryptFileInfo();
fileInfo.BundleName = bundleInfo.Bundle.BundleName;
fileInfo.FileLoadPath = fileLoadPath;
fileInfo.ConentCRC = bundleInfo.Bundle.UnityCRC;
return _decryption.LoadAssetBundle(fileInfo, out managedStream);
}
else
{
return AssetBundle.LoadFromFile(fileLoadPath);
}
}
/// <summary>
/// 异步加载资源包对象
/// </summary>
public AssetBundleCreateRequest LoadAssetBundleAsync(BundleInfo bundleInfo, string fileLoadPath, out Stream managedStream)
{
managedStream = null;
if (bundleInfo.Bundle.Encrypted)
{
if (_decryption == null)
{
YooLogger.Error($"{nameof(IDecryptionServices)} is null ! when load asset bundle {bundleInfo.Bundle.BundleName}!");
return null;
}
/// <summary>
/// 异步加载资源包对象
/// </summary>
public AssetBundleCreateRequest LoadAssetBundleAsync(BundleInfo bundleInfo, string fileLoadPath, out Stream managedStream)
{
managedStream = null;
if (bundleInfo.Bundle.Encrypted)
{
if (_decryption == null)
{
YooLogger.Error($"{nameof(IDecryptionServices)} is null ! when load asset bundle {bundleInfo.Bundle.BundleName}!");
return null;
}
DecryptFileInfo fileInfo = new DecryptFileInfo();
fileInfo.BundleName = bundleInfo.Bundle.BundleName;
fileInfo.FileLoadPath = fileLoadPath;
fileInfo.ConentCRC = bundleInfo.Bundle.UnityCRC;
return _decryption.LoadAssetBundleAsync(fileInfo, out managedStream);
}
else
{
return AssetBundle.LoadFromFileAsync(fileLoadPath);
}
}
DecryptFileInfo fileInfo = new DecryptFileInfo();
fileInfo.BundleName = bundleInfo.Bundle.BundleName;
fileInfo.FileLoadPath = fileLoadPath;
fileInfo.ConentCRC = bundleInfo.Bundle.UnityCRC;
return _decryption.LoadAssetBundleAsync(fileInfo, out managedStream);
}
else
{
return AssetBundle.LoadFromFileAsync(fileLoadPath);
}
}
/// <summary>
/// 同步加载分发的资源包对象
/// </summary>
public AssetBundle LoadDeliveryAssetBundle(BundleInfo bundleInfo, string fileLoadPath)
{
if (_delivery == null)
throw new System.Exception("Should never get here !");
/// <summary>
/// 同步加载分发的资源包对象
/// </summary>
public AssetBundle LoadDeliveryAssetBundle(BundleInfo bundleInfo, string fileLoadPath)
{
if (_delivery == null)
throw new System.Exception("Should never get here !");
// 注意:对于已经加密的资源包,需要开发者自行解密。
DeliveryFileInfo fileInfo = new DeliveryFileInfo();
fileInfo.BundleName = bundleInfo.Bundle.BundleName;
fileInfo.FileLoadPath = fileLoadPath;
fileInfo.ConentCRC = bundleInfo.Bundle.UnityCRC;
fileInfo.Encrypted = bundleInfo.Bundle.Encrypted;
return _delivery.LoadAssetBundle(fileInfo);
}
// 注意:对于已经加密的资源包,需要开发者自行解密。
DeliveryFileInfo fileInfo = new DeliveryFileInfo();
fileInfo.BundleName = bundleInfo.Bundle.BundleName;
fileInfo.FileLoadPath = fileLoadPath;
fileInfo.ConentCRC = bundleInfo.Bundle.UnityCRC;
fileInfo.Encrypted = bundleInfo.Bundle.Encrypted;
return _delivery.LoadAssetBundle(fileInfo);
}
/// <summary>
/// 异步加载分发的资源包对象
/// </summary>
public AssetBundleCreateRequest LoadDeliveryAssetBundleAsync(BundleInfo bundleInfo, string fileLoadPath)
{
if (_delivery == null)
throw new System.Exception("Should never get here !");
/// <summary>
/// 异步加载分发的资源包对象
/// </summary>
public AssetBundleCreateRequest LoadDeliveryAssetBundleAsync(BundleInfo bundleInfo, string fileLoadPath)
{
if (_delivery == null)
throw new System.Exception("Should never get here !");
// 注意:对于已经加密的资源包,需要开发者自行解密。
DeliveryFileInfo fileInfo = new DeliveryFileInfo();
fileInfo.BundleName = bundleInfo.Bundle.BundleName;
fileInfo.FileLoadPath = fileLoadPath;
fileInfo.ConentCRC = bundleInfo.Bundle.UnityCRC;
fileInfo.Encrypted = bundleInfo.Bundle.Encrypted;
return _delivery.LoadAssetBundleAsync(fileInfo);
}
}
// 注意:对于已经加密的资源包,需要开发者自行解密。
DeliveryFileInfo fileInfo = new DeliveryFileInfo();
fileInfo.BundleName = bundleInfo.Bundle.BundleName;
fileInfo.FileLoadPath = fileLoadPath;
fileInfo.ConentCRC = bundleInfo.Bundle.UnityCRC;
fileInfo.Encrypted = bundleInfo.Bundle.Encrypted;
return _delivery.LoadAssetBundleAsync(fileInfo);
}
}
}

View File

@ -7,478 +7,478 @@ using UnityEngine.SceneManagement;
namespace YooAsset
{
internal class ResourceManager
{
// 全局场景句柄集合
private readonly static Dictionary<string, SceneHandle> _sceneHandles = new Dictionary<string, SceneHandle>(100);
private static long _sceneCreateCount = 0;
internal class ResourceManager
{
// 全局场景句柄集合
private readonly static Dictionary<string, SceneHandle> _sceneHandles = new Dictionary<string, SceneHandle>(100);
private static long _sceneCreateCount = 0;
private readonly Dictionary<string, ProviderBase> _providerDic = new Dictionary<string, ProviderBase>(5000);
private readonly Dictionary<string, BundleLoaderBase> _loaderDic = new Dictionary<string, BundleLoaderBase>(5000);
private readonly List<BundleLoaderBase> _loaderList = new List<BundleLoaderBase>(5000);
private readonly Dictionary<string, ProviderBase> _providerDic = new Dictionary<string, ProviderBase>(5000);
private readonly Dictionary<string, BundleLoaderBase> _loaderDic = new Dictionary<string, BundleLoaderBase>(5000);
private readonly List<BundleLoaderBase> _loaderList = new List<BundleLoaderBase>(5000);
private bool _simulationOnEditor;
private bool _autoDestroyAssetProvider;
private IBundleQuery _bundleQuery;
private bool _simulationOnEditor;
private bool _autoDestroyAssetProvider;
private IBundleQuery _bundleQuery;
/// <summary>
/// 所属包裹
/// </summary>
public readonly string PackageName;
/// <summary>
/// 所属包裹
/// </summary>
public readonly string PackageName;
public ResourceManager(string packageName)
{
PackageName = packageName;
}
public ResourceManager(string packageName)
{
PackageName = packageName;
}
/// <summary>
/// 初始化
/// </summary>
public void Initialize(bool simulationOnEditor, bool autoDestroyAssetProvider, IBundleQuery bundleServices)
{
_simulationOnEditor = simulationOnEditor;
_autoDestroyAssetProvider = autoDestroyAssetProvider;
_bundleQuery = bundleServices;
}
/// <summary>
/// 初始化
/// </summary>
public void Initialize(bool simulationOnEditor, bool autoDestroyAssetProvider, IBundleQuery bundleServices)
{
_simulationOnEditor = simulationOnEditor;
_autoDestroyAssetProvider = autoDestroyAssetProvider;
_bundleQuery = bundleServices;
}
/// <summary>
/// 更新
/// </summary>
public void Update()
{
foreach (var loader in _loaderList)
{
loader.Update();
/// <summary>
/// 更新
/// </summary>
public void Update()
{
foreach (var loader in _loaderList)
{
loader.Update();
if (_autoDestroyAssetProvider)
loader.TryDestroyProviders();
}
}
if (_autoDestroyAssetProvider)
loader.TryDestroyProviders();
}
}
/// <summary>
/// 资源回收(卸载引用计数为零的资源)
/// </summary>
public void UnloadUnusedAssets()
{
for (int i = _loaderList.Count - 1; i >= 0; i--)
{
BundleLoaderBase loader = _loaderList[i];
loader.TryDestroyProviders();
}
/// <summary>
/// 资源回收(卸载引用计数为零的资源)
/// </summary>
public void UnloadUnusedAssets()
{
for (int i = _loaderList.Count - 1; i >= 0; i--)
{
BundleLoaderBase loader = _loaderList[i];
loader.TryDestroyProviders();
}
for (int i = _loaderList.Count - 1; i >= 0; i--)
{
BundleLoaderBase loader = _loaderList[i];
if (loader.CanDestroy())
{
string bundleName = loader.MainBundleInfo.Bundle.BundleName;
loader.Destroy();
_loaderList.RemoveAt(i);
_loaderDic.Remove(bundleName);
}
}
}
for (int i = _loaderList.Count - 1; i >= 0; i--)
{
BundleLoaderBase loader = _loaderList[i];
if (loader.CanDestroy())
{
string bundleName = loader.MainBundleInfo.Bundle.BundleName;
loader.Destroy();
_loaderList.RemoveAt(i);
_loaderDic.Remove(bundleName);
}
}
}
/// <summary>
/// 尝试卸载指定资源的资源包(包括依赖资源)
/// </summary>
public void TryUnloadUnusedAsset(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to unload asset ! {assetInfo.Error}");
return;
}
/// <summary>
/// 尝试卸载指定资源的资源包(包括依赖资源)
/// </summary>
public void TryUnloadUnusedAsset(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to unload asset ! {assetInfo.Error}");
return;
}
// 卸载主资源包加载器
string manBundleName = _bundleQuery.GetMainBundleName(assetInfo);
var mainLoader = TryGetAssetBundleLoader(manBundleName);
if (mainLoader != null)
{
mainLoader.TryDestroyProviders();
if (mainLoader.CanDestroy())
{
string bundleName = mainLoader.MainBundleInfo.Bundle.BundleName;
mainLoader.Destroy();
_loaderList.Remove(mainLoader);
_loaderDic.Remove(bundleName);
}
}
// 卸载主资源包加载器
string manBundleName = _bundleQuery.GetMainBundleName(assetInfo);
var mainLoader = TryGetAssetBundleLoader(manBundleName);
if (mainLoader != null)
{
mainLoader.TryDestroyProviders();
if (mainLoader.CanDestroy())
{
string bundleName = mainLoader.MainBundleInfo.Bundle.BundleName;
mainLoader.Destroy();
_loaderList.Remove(mainLoader);
_loaderDic.Remove(bundleName);
}
}
// 卸载依赖资源包加载器
string[] dependBundleNames = _bundleQuery.GetDependBundleNames(assetInfo);
foreach (var dependBundleName in dependBundleNames)
{
var dependLoader = TryGetAssetBundleLoader(dependBundleName);
if (dependLoader != null)
{
if (dependLoader.CanDestroy())
{
string bundleName = dependLoader.MainBundleInfo.Bundle.BundleName;
dependLoader.Destroy();
_loaderList.Remove(dependLoader);
_loaderDic.Remove(bundleName);
}
}
}
}
// 卸载依赖资源包加载器
string[] dependBundleNames = _bundleQuery.GetDependBundleNames(assetInfo);
foreach (var dependBundleName in dependBundleNames)
{
var dependLoader = TryGetAssetBundleLoader(dependBundleName);
if (dependLoader != null)
{
if (dependLoader.CanDestroy())
{
string bundleName = dependLoader.MainBundleInfo.Bundle.BundleName;
dependLoader.Destroy();
_loaderList.Remove(dependLoader);
_loaderDic.Remove(bundleName);
}
}
}
}
/// <summary>
/// 强制回收所有资源
/// 注意:加载器在销毁后关联的下载器还会继续下载!
/// </summary>
public void ForceUnloadAllAssets()
{
/// <summary>
/// 强制回收所有资源
/// 注意:加载器在销毁后关联的下载器还会继续下载!
/// </summary>
public void ForceUnloadAllAssets()
{
#if UNITY_WEBGL
throw new Exception($"WebGL not support invoke {nameof(ForceUnloadAllAssets)}");
#else
// 注意:因为场景无法异步转同步,需要等待所有场景加载完毕!
foreach (var sceneHandlePair in _sceneHandles)
{
var sceneHandle = sceneHandlePair.Value;
if (sceneHandle.PackageName == PackageName)
{
if (sceneHandle.IsDone == false)
throw new Exception($"{nameof(ForceUnloadAllAssets)} cannot be called when loading the scene !");
}
}
// 注意:因为场景无法异步转同步,需要等待所有场景加载完毕!
foreach (var sceneHandlePair in _sceneHandles)
{
var sceneHandle = sceneHandlePair.Value;
if (sceneHandle.PackageName == PackageName)
{
if (sceneHandle.IsDone == false)
throw new Exception($"{nameof(ForceUnloadAllAssets)} cannot be called when loading the scene !");
}
}
// 释放所有资源句柄
foreach (var provider in _providerDic.Values)
{
provider.ReleaseAllHandles();
}
// 释放所有资源句柄
foreach (var provider in _providerDic.Values)
{
provider.ReleaseAllHandles();
}
// 强制销毁资源提供者
foreach (var provider in _providerDic.Values)
{
provider.ForceDestroyComplete();
provider.Destroy();
}
// 强制销毁资源提供者
foreach (var provider in _providerDic.Values)
{
provider.ForceDestroyComplete();
provider.Destroy();
}
// 强制销毁资源加载器
foreach (var loader in _loaderList)
{
loader.ForceDestroyComplete();
loader.Destroy();
}
// 强制销毁资源加载器
foreach (var loader in _loaderList)
{
loader.ForceDestroyComplete();
loader.Destroy();
}
// 清空数据
_providerDic.Clear();
_loaderList.Clear();
_loaderDic.Clear();
ClearSceneHandle();
// 清空数据
_providerDic.Clear();
_loaderList.Clear();
_loaderDic.Clear();
ClearSceneHandle();
// 注意:调用底层接口释放所有资源
Resources.UnloadUnusedAssets();
// 注意:调用底层接口释放所有资源
Resources.UnloadUnusedAssets();
#endif
}
}
/// <summary>
/// 加载场景对象
/// 注意:返回的场景句柄是唯一的,每个场景句柄对应自己的场景提供者对象。
/// 注意:业务逻辑层应该避免同时加载一个子场景。
/// </summary>
public SceneHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode, bool suspendLoad, uint priority)
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load scene ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
return completedProvider.CreateHandle<SceneHandle>();
}
/// <summary>
/// 加载场景对象
/// 注意:返回的场景句柄是唯一的,每个场景句柄对应自己的场景提供者对象。
/// 注意:业务逻辑层应该避免同时加载一个子场景。
/// </summary>
public SceneHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode, bool suspendLoad, uint priority)
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load scene ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
return completedProvider.CreateHandle<SceneHandle>();
}
// 如果加载的是主场景,则卸载所有缓存的场景
if (sceneMode == LoadSceneMode.Single)
{
UnloadAllScene();
}
// 如果加载的是主场景,则卸载所有缓存的场景
if (sceneMode == LoadSceneMode.Single)
{
UnloadAllScene();
}
// 注意同一个场景的ProviderGUID每次加载都会变化
string providerGUID = $"{assetInfo.GUID}-{++_sceneCreateCount}";
ProviderBase provider;
{
if (_simulationOnEditor)
provider = new DatabaseSceneProvider(this, providerGUID, assetInfo, sceneMode, suspendLoad);
else
provider = new BundledSceneProvider(this, providerGUID, assetInfo, sceneMode, suspendLoad);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
// 注意同一个场景的ProviderGUID每次加载都会变化
string providerGUID = $"{assetInfo.GUID}-{++_sceneCreateCount}";
ProviderBase provider;
{
if (_simulationOnEditor)
provider = new DatabaseSceneProvider(this, providerGUID, assetInfo, sceneMode, suspendLoad);
else
provider = new BundledSceneProvider(this, providerGUID, assetInfo, sceneMode, suspendLoad);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
provider.Priority = priority;
var handle = provider.CreateHandle<SceneHandle>();
handle.PackageName = PackageName;
_sceneHandles.Add(providerGUID, handle);
return handle;
}
provider.Priority = priority;
var handle = provider.CreateHandle<SceneHandle>();
handle.PackageName = PackageName;
_sceneHandles.Add(providerGUID, handle);
return handle;
}
/// <summary>
/// 加载资源对象
/// </summary>
public AssetHandle LoadAssetAsync(AssetInfo assetInfo, uint priority)
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load asset ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
return completedProvider.CreateHandle<AssetHandle>();
}
/// <summary>
/// 加载资源对象
/// </summary>
public AssetHandle LoadAssetAsync(AssetInfo assetInfo, uint priority)
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load asset ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
return completedProvider.CreateHandle<AssetHandle>();
}
string providerGUID = nameof(LoadAssetAsync) + assetInfo.GUID;
ProviderBase provider = TryGetProvider(providerGUID);
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseAssetProvider(this, providerGUID, assetInfo);
else
provider = new BundledAssetProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
string providerGUID = nameof(LoadAssetAsync) + assetInfo.GUID;
ProviderBase provider = TryGetProvider(providerGUID);
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseAssetProvider(this, providerGUID, assetInfo);
else
provider = new BundledAssetProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
provider.Priority = priority;
return provider.CreateHandle<AssetHandle>();
}
provider.Priority = priority;
return provider.CreateHandle<AssetHandle>();
}
/// <summary>
/// 加载子资源对象
/// </summary>
public SubAssetsHandle LoadSubAssetsAsync(AssetInfo assetInfo, uint priority)
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load sub assets ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
return completedProvider.CreateHandle<SubAssetsHandle>();
}
/// <summary>
/// 加载子资源对象
/// </summary>
public SubAssetsHandle LoadSubAssetsAsync(AssetInfo assetInfo, uint priority)
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load sub assets ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
return completedProvider.CreateHandle<SubAssetsHandle>();
}
string providerGUID = nameof(LoadSubAssetsAsync) + assetInfo.GUID;
ProviderBase provider = TryGetProvider(providerGUID);
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseSubAssetsProvider(this, providerGUID, assetInfo);
else
provider = new BundledSubAssetsProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
string providerGUID = nameof(LoadSubAssetsAsync) + assetInfo.GUID;
ProviderBase provider = TryGetProvider(providerGUID);
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseSubAssetsProvider(this, providerGUID, assetInfo);
else
provider = new BundledSubAssetsProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
provider.Priority = priority;
return provider.CreateHandle<SubAssetsHandle>();
}
provider.Priority = priority;
return provider.CreateHandle<SubAssetsHandle>();
}
/// <summary>
/// 加载所有资源对象
/// </summary>
public AllAssetsHandle LoadAllAssetsAsync(AssetInfo assetInfo, uint priority)
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load all assets ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
return completedProvider.CreateHandle<AllAssetsHandle>();
}
/// <summary>
/// 加载所有资源对象
/// </summary>
public AllAssetsHandle LoadAllAssetsAsync(AssetInfo assetInfo, uint priority)
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load all assets ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
return completedProvider.CreateHandle<AllAssetsHandle>();
}
string providerGUID = nameof(LoadAllAssetsAsync) + assetInfo.GUID;
ProviderBase provider = TryGetProvider(providerGUID);
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseAllAssetsProvider(this, providerGUID, assetInfo);
else
provider = new BundledAllAssetsProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
string providerGUID = nameof(LoadAllAssetsAsync) + assetInfo.GUID;
ProviderBase provider = TryGetProvider(providerGUID);
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseAllAssetsProvider(this, providerGUID, assetInfo);
else
provider = new BundledAllAssetsProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
provider.Priority = priority;
return provider.CreateHandle<AllAssetsHandle>();
}
provider.Priority = priority;
return provider.CreateHandle<AllAssetsHandle>();
}
/// <summary>
/// 加载原生文件
/// </summary>
public RawFileHandle LoadRawFileAsync(AssetInfo assetInfo, uint priority)
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load raw file ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
return completedProvider.CreateHandle<RawFileHandle>();
}
/// <summary>
/// 加载原生文件
/// </summary>
public RawFileHandle LoadRawFileAsync(AssetInfo assetInfo, uint priority)
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load raw file ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
return completedProvider.CreateHandle<RawFileHandle>();
}
string providerGUID = nameof(LoadRawFileAsync) + assetInfo.GUID;
ProviderBase provider = TryGetProvider(providerGUID);
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseRawFileProvider(this, providerGUID, assetInfo);
else
provider = new BundledRawFileProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
string providerGUID = nameof(LoadRawFileAsync) + assetInfo.GUID;
ProviderBase provider = TryGetProvider(providerGUID);
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseRawFileProvider(this, providerGUID, assetInfo);
else
provider = new BundledRawFileProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
provider.Priority = priority;
return provider.CreateHandle<RawFileHandle>();
}
provider.Priority = priority;
return provider.CreateHandle<RawFileHandle>();
}
internal void UnloadSubScene(string sceneName)
{
List<string> removeKeys = new List<string>();
foreach (var valuePair in _sceneHandles)
{
var sceneHandle = valuePair.Value;
if (sceneHandle.SceneName == sceneName)
{
// 释放子场景句柄
sceneHandle.ReleaseInternal();
removeKeys.Add(valuePair.Key);
}
}
internal void UnloadSubScene(string sceneName)
{
List<string> removeKeys = new List<string>();
foreach (var valuePair in _sceneHandles)
{
var sceneHandle = valuePair.Value;
if (sceneHandle.SceneName == sceneName)
{
// 释放子场景句柄
sceneHandle.ReleaseInternal();
removeKeys.Add(valuePair.Key);
}
}
foreach (string key in removeKeys)
{
_sceneHandles.Remove(key);
}
}
private void UnloadAllScene()
{
// 释放所有场景句柄
foreach (var valuePair in _sceneHandles)
{
valuePair.Value.ReleaseInternal();
}
_sceneHandles.Clear();
}
private void ClearSceneHandle()
{
// 释放资源包下的所有场景
if (_bundleQuery.ManifestValid())
{
string packageName = PackageName;
List<string> removeList = new List<string>();
foreach (var valuePair in _sceneHandles)
{
if (valuePair.Value.PackageName == packageName)
{
removeList.Add(valuePair.Key);
}
}
foreach (var key in removeList)
{
_sceneHandles.Remove(key);
}
}
}
foreach (string key in removeKeys)
{
_sceneHandles.Remove(key);
}
}
private void UnloadAllScene()
{
// 释放所有场景句柄
foreach (var valuePair in _sceneHandles)
{
valuePair.Value.ReleaseInternal();
}
_sceneHandles.Clear();
}
private void ClearSceneHandle()
{
// 释放资源包下的所有场景
if (_bundleQuery.ManifestValid())
{
string packageName = PackageName;
List<string> removeList = new List<string>();
foreach (var valuePair in _sceneHandles)
{
if (valuePair.Value.PackageName == packageName)
{
removeList.Add(valuePair.Key);
}
}
foreach (var key in removeList)
{
_sceneHandles.Remove(key);
}
}
}
internal BundleLoaderBase CreateOwnerAssetBundleLoader(AssetInfo assetInfo)
{
BundleInfo bundleInfo = _bundleQuery.GetMainBundleInfo(assetInfo);
return CreateAssetBundleLoaderInternal(bundleInfo);
}
internal List<BundleLoaderBase> CreateDependAssetBundleLoaders(AssetInfo assetInfo)
{
BundleInfo[] depends = _bundleQuery.GetDependBundleInfos(assetInfo);
List<BundleLoaderBase> result = new List<BundleLoaderBase>(depends.Length);
foreach (var bundleInfo in depends)
{
BundleLoaderBase dependLoader = CreateAssetBundleLoaderInternal(bundleInfo);
result.Add(dependLoader);
}
return result;
}
internal void RemoveBundleProviders(List<ProviderBase> removeList)
{
foreach (var provider in removeList)
{
_providerDic.Remove(provider.ProviderGUID);
}
}
internal bool HasAnyLoader()
{
return _loaderList.Count > 0;
}
internal BundleLoaderBase CreateOwnerAssetBundleLoader(AssetInfo assetInfo)
{
BundleInfo bundleInfo = _bundleQuery.GetMainBundleInfo(assetInfo);
return CreateAssetBundleLoaderInternal(bundleInfo);
}
internal List<BundleLoaderBase> CreateDependAssetBundleLoaders(AssetInfo assetInfo)
{
BundleInfo[] depends = _bundleQuery.GetDependBundleInfos(assetInfo);
List<BundleLoaderBase> result = new List<BundleLoaderBase>(depends.Length);
foreach (var bundleInfo in depends)
{
BundleLoaderBase dependLoader = CreateAssetBundleLoaderInternal(bundleInfo);
result.Add(dependLoader);
}
return result;
}
internal void RemoveBundleProviders(List<ProviderBase> removeList)
{
foreach (var provider in removeList)
{
_providerDic.Remove(provider.ProviderGUID);
}
}
internal bool HasAnyLoader()
{
return _loaderList.Count > 0;
}
private BundleLoaderBase CreateAssetBundleLoaderInternal(BundleInfo bundleInfo)
{
// 如果加载器已经存在
string bundleName = bundleInfo.Bundle.BundleName;
BundleLoaderBase loader = TryGetAssetBundleLoader(bundleName);
if (loader != null)
return loader;
private BundleLoaderBase CreateAssetBundleLoaderInternal(BundleInfo bundleInfo)
{
// 如果加载器已经存在
string bundleName = bundleInfo.Bundle.BundleName;
BundleLoaderBase loader = TryGetAssetBundleLoader(bundleName);
if (loader != null)
return loader;
// 新增下载需求
if (_simulationOnEditor)
{
loader = new VirtualBundleFileLoader(this, bundleInfo);
}
else
{
// 新增下载需求
if (_simulationOnEditor)
{
loader = new VirtualBundleFileLoader(this, bundleInfo);
}
else
{
#if UNITY_WEBGL
if (bundleInfo.Bundle.Buildpipeline== EDefaultBuildPipeline.RawFileBuildPipeline.ToString())
loader = new RawBundleWebLoader(this, bundleInfo);
else
loader = new AssetBundleWebLoader(this, bundleInfo);
#else
if (bundleInfo.Bundle.Buildpipeline == EDefaultBuildPipeline.RawFileBuildPipeline.ToString())
loader = new RawBundleFileLoader(this, bundleInfo);
else
loader = new AssetBundleFileLoader(this, bundleInfo);
if (bundleInfo.Bundle.Buildpipeline == EDefaultBuildPipeline.RawFileBuildPipeline.ToString())
loader = new RawBundleFileLoader(this, bundleInfo);
else
loader = new AssetBundleFileLoader(this, bundleInfo);
#endif
}
}
_loaderList.Add(loader);
_loaderDic.Add(bundleName, loader);
return loader;
}
private BundleLoaderBase TryGetAssetBundleLoader(string bundleName)
{
if (_loaderDic.TryGetValue(bundleName, out BundleLoaderBase value))
return value;
else
return null;
}
private ProviderBase TryGetProvider(string providerGUID)
{
if (_providerDic.TryGetValue(providerGUID, out ProviderBase value))
return value;
else
return null;
}
_loaderList.Add(loader);
_loaderDic.Add(bundleName, loader);
return loader;
}
private BundleLoaderBase TryGetAssetBundleLoader(string bundleName)
{
if (_loaderDic.TryGetValue(bundleName, out BundleLoaderBase value))
return value;
else
return null;
}
private ProviderBase TryGetProvider(string providerGUID)
{
if (_providerDic.TryGetValue(providerGUID, out ProviderBase value))
return value;
else
return null;
}
#region 调试信息
internal List<DebugProviderInfo> GetDebugReportInfos()
{
List<DebugProviderInfo> result = new List<DebugProviderInfo>(_providerDic.Count);
foreach (var provider in _providerDic.Values)
{
DebugProviderInfo providerInfo = new DebugProviderInfo();
providerInfo.AssetPath = provider.MainAssetInfo.AssetPath;
providerInfo.SpawnScene = provider.SpawnScene;
providerInfo.SpawnTime = provider.SpawnTime;
providerInfo.LoadingTime = provider.LoadingTime;
providerInfo.RefCount = provider.RefCount;
providerInfo.Status = provider.Status.ToString();
providerInfo.DependBundleInfos = new List<DebugBundleInfo>();
provider.GetBundleDebugInfos(providerInfo.DependBundleInfos);
result.Add(providerInfo);
}
return result;
}
#endregion
}
#region 调试信息
internal List<DebugProviderInfo> GetDebugReportInfos()
{
List<DebugProviderInfo> result = new List<DebugProviderInfo>(_providerDic.Count);
foreach (var provider in _providerDic.Values)
{
DebugProviderInfo providerInfo = new DebugProviderInfo();
providerInfo.AssetPath = provider.MainAssetInfo.AssetPath;
providerInfo.SpawnScene = provider.SpawnScene;
providerInfo.SpawnTime = provider.SpawnTime;
providerInfo.LoadingTime = provider.LoadingTime;
providerInfo.RefCount = provider.RefCount;
providerInfo.Status = provider.Status.ToString();
providerInfo.DependBundleInfos = new List<DebugBundleInfo>();
provider.GetBundleDebugInfos(providerInfo.DependBundleInfos);
result.Add(providerInfo);
}
return result;
}
#endregion
}
}

View File

@ -1,105 +1,105 @@

namespace YooAsset
{
public class AssetInfo
{
private readonly PackageAsset _packageAsset;
private string _providerGUID;
public class AssetInfo
{
private readonly PackageAsset _packageAsset;
private string _providerGUID;
/// <summary>
/// 所属包裹
/// </summary>
public string PackageName { private set; get; }
/// <summary>
/// 所属包裹
/// </summary>
public string PackageName { private set; get; }
/// <summary>
/// 资源类型
/// </summary>
public System.Type AssetType { private set; get; }
/// <summary>
/// 资源类型
/// </summary>
public System.Type AssetType { private set; get; }
/// <summary>
/// 错误信息
/// </summary>
public string Error { private set; get; }
/// <summary>
/// 错误信息
/// </summary>
public string Error { private set; get; }
/// <summary>
/// 唯一标识符
/// </summary>
internal string GUID
{
get
{
if (string.IsNullOrEmpty(_providerGUID) == false)
return _providerGUID;
/// <summary>
/// 唯一标识符
/// </summary>
internal string GUID
{
get
{
if (string.IsNullOrEmpty(_providerGUID) == false)
return _providerGUID;
if (AssetType == null)
_providerGUID = $"[{AssetPath}][null]";
else
_providerGUID = $"[{AssetPath}][{AssetType.Name}]";
return _providerGUID;
}
}
if (AssetType == null)
_providerGUID = $"[{AssetPath}][null]";
else
_providerGUID = $"[{AssetPath}][{AssetType.Name}]";
return _providerGUID;
}
}
/// <summary>
/// 身份是否无效
/// </summary>
internal bool IsInvalid
{
get
{
return _packageAsset == null;
}
}
/// <summary>
/// 身份是否无效
/// </summary>
internal bool IsInvalid
{
get
{
return _packageAsset == null;
}
}
/// <summary>
/// 可寻址地址
/// </summary>
public string Address
{
get
{
if (_packageAsset == null)
return string.Empty;
return _packageAsset.Address;
}
}
/// <summary>
/// 可寻址地址
/// </summary>
public string Address
{
get
{
if (_packageAsset == null)
return string.Empty;
return _packageAsset.Address;
}
}
/// <summary>
/// 资源路径
/// </summary>
public string AssetPath
{
get
{
if (_packageAsset == null)
return string.Empty;
return _packageAsset.AssetPath;
}
}
/// <summary>
/// 资源路径
/// </summary>
public string AssetPath
{
get
{
if (_packageAsset == null)
return string.Empty;
return _packageAsset.AssetPath;
}
}
private AssetInfo()
{
// 注意:禁止从外部创建该类
}
internal AssetInfo(string packageName, PackageAsset packageAsset, System.Type assetType)
{
if (packageAsset == null)
throw new System.Exception("Should never get here !");
private AssetInfo()
{
// 注意:禁止从外部创建该类
}
internal AssetInfo(string packageName, PackageAsset packageAsset, System.Type assetType)
{
if (packageAsset == null)
throw new System.Exception("Should never get here !");
_providerGUID = string.Empty;
_packageAsset = packageAsset;
PackageName = packageName;
AssetType = assetType;
Error = string.Empty;
}
internal AssetInfo(string packageName, string error)
{
_providerGUID = string.Empty;
_packageAsset = null;
PackageName = packageName;
AssetType = null;
Error = error;
}
}
_providerGUID = string.Empty;
_packageAsset = packageAsset;
PackageName = packageName;
AssetType = assetType;
Error = string.Empty;
}
internal AssetInfo(string packageName, string error)
{
_providerGUID = string.Empty;
_packageAsset = null;
PackageName = packageName;
AssetType = null;
Error = error;
}
}
}

View File

@ -4,206 +4,206 @@ using UnityEngine;
namespace YooAsset
{
internal class BundleInfo
{
public enum ELoadMode
{
None,
LoadFromDelivery,
LoadFromStreaming,
LoadFromCache,
LoadFromRemote,
LoadFromEditor,
}
internal class BundleInfo
{
public enum ELoadMode
{
None,
LoadFromDelivery,
LoadFromStreaming,
LoadFromCache,
LoadFromRemote,
LoadFromEditor,
}
private readonly ResourceAssist _assist;
private readonly ResourceAssist _assist;
/// <summary>
/// 资源包对象
/// </summary>
public readonly PackageBundle Bundle;
/// <summary>
/// 资源包对象
/// </summary>
public readonly PackageBundle Bundle;
/// <summary>
/// 资源包加载模式
/// </summary>
public readonly ELoadMode LoadMode;
/// <summary>
/// 资源包加载模式
/// </summary>
public readonly ELoadMode LoadMode;
/// <summary>
/// 远端下载地址
/// </summary>
public string RemoteMainURL { private set; get; }
/// <summary>
/// 远端下载地址
/// </summary>
public string RemoteMainURL { private set; get; }
/// <summary>
/// 远端下载备用地址
/// </summary>
public string RemoteFallbackURL { private set; get; }
/// <summary>
/// 远端下载备用地址
/// </summary>
public string RemoteFallbackURL { private set; get; }
/// <summary>
/// 分发资源文件路径
/// </summary>
public string DeliveryFilePath { private set; get; }
/// <summary>
/// 分发资源文件路径
/// </summary>
public string DeliveryFilePath { private set; get; }
/// <summary>
/// 注意:该字段只用于帮助编辑器下的模拟模式。
/// </summary>
public string[] IncludeAssetsInEditor;
/// <summary>
/// 注意:该字段只用于帮助编辑器下的模拟模式。
/// </summary>
public string[] IncludeAssetsInEditor;
private BundleInfo()
{
}
public BundleInfo(ResourceAssist assist, PackageBundle bundle, ELoadMode loadMode, string mainURL, string fallbackURL)
{
_assist = assist;
Bundle = bundle;
LoadMode = loadMode;
RemoteMainURL = mainURL;
RemoteFallbackURL = fallbackURL;
DeliveryFilePath = string.Empty;
}
public BundleInfo(ResourceAssist assist, PackageBundle bundle, ELoadMode loadMode, string deliveryFilePath)
{
_assist = assist;
Bundle = bundle;
LoadMode = loadMode;
RemoteMainURL = string.Empty;
RemoteFallbackURL = string.Empty;
DeliveryFilePath = deliveryFilePath;
}
public BundleInfo(ResourceAssist assist, PackageBundle bundle, ELoadMode loadMode)
{
_assist = assist;
Bundle = bundle;
LoadMode = loadMode;
RemoteMainURL = string.Empty;
RemoteFallbackURL = string.Empty;
DeliveryFilePath = string.Empty;
}
private BundleInfo()
{
}
public BundleInfo(ResourceAssist assist, PackageBundle bundle, ELoadMode loadMode, string mainURL, string fallbackURL)
{
_assist = assist;
Bundle = bundle;
LoadMode = loadMode;
RemoteMainURL = mainURL;
RemoteFallbackURL = fallbackURL;
DeliveryFilePath = string.Empty;
}
public BundleInfo(ResourceAssist assist, PackageBundle bundle, ELoadMode loadMode, string deliveryFilePath)
{
_assist = assist;
Bundle = bundle;
LoadMode = loadMode;
RemoteMainURL = string.Empty;
RemoteFallbackURL = string.Empty;
DeliveryFilePath = deliveryFilePath;
}
public BundleInfo(ResourceAssist assist, PackageBundle bundle, ELoadMode loadMode)
{
_assist = assist;
Bundle = bundle;
LoadMode = loadMode;
RemoteMainURL = string.Empty;
RemoteFallbackURL = string.Empty;
DeliveryFilePath = string.Empty;
}
#region Cache
public bool IsCached()
{
return _assist.Cache.IsCached(Bundle.CacheGUID);
}
public void CacheRecord()
{
string infoFilePath = CachedInfoFilePath;
string dataFilePath = CachedDataFilePath;
string dataFileCRC = Bundle.FileCRC;
long dataFileSize = Bundle.FileSize;
var wrapper = new CacheManager.RecordWrapper(infoFilePath, dataFilePath, dataFileCRC, dataFileSize);
_assist.Cache.Record(Bundle.CacheGUID, wrapper);
}
public void CacheDiscard()
{
_assist.Cache.Discard(Bundle.CacheGUID);
}
public EVerifyResult VerifySelf()
{
return CacheHelper.VerifyingRecordFile(_assist.Cache, Bundle.CacheGUID);
}
#endregion
#region Cache
public bool IsCached()
{
return _assist.Cache.IsCached(Bundle.CacheGUID);
}
public void CacheRecord()
{
string infoFilePath = CachedInfoFilePath;
string dataFilePath = CachedDataFilePath;
string dataFileCRC = Bundle.FileCRC;
long dataFileSize = Bundle.FileSize;
var wrapper = new CacheManager.RecordWrapper(infoFilePath, dataFilePath, dataFileCRC, dataFileSize);
_assist.Cache.Record(Bundle.CacheGUID, wrapper);
}
public void CacheDiscard()
{
_assist.Cache.Discard(Bundle.CacheGUID);
}
public EVerifyResult VerifySelf()
{
return CacheHelper.VerifyingRecordFile(_assist.Cache, Bundle.CacheGUID);
}
#endregion
#region Persistent
public string CachedDataFilePath
{
get
{
return _assist.Persistent.GetCachedDataFilePath(Bundle);
}
}
public string CachedInfoFilePath
{
get
{
return _assist.Persistent.GetCachedInfoFilePath(Bundle);
}
}
public string TempDataFilePath
{
get
{
return _assist.Persistent.GetTempDataFilePath(Bundle);
}
}
public string BuildinFilePath
{
get
{
return _assist.Persistent.GetBuildinFilePath(Bundle);
}
}
#endregion
#region Persistent
public string CachedDataFilePath
{
get
{
return _assist.Persistent.GetCachedDataFilePath(Bundle);
}
}
public string CachedInfoFilePath
{
get
{
return _assist.Persistent.GetCachedInfoFilePath(Bundle);
}
}
public string TempDataFilePath
{
get
{
return _assist.Persistent.GetTempDataFilePath(Bundle);
}
}
public string BuildinFilePath
{
get
{
return _assist.Persistent.GetBuildinFilePath(Bundle);
}
}
#endregion
#region Download
public DownloaderBase CreateDownloader(int failedTryAgain, int timeout = 60)
{
return _assist.Download.CreateDownload(this, failedTryAgain, timeout);
}
public DownloaderBase CreateUnpacker(int failedTryAgain, int timeout = 60)
{
var unpackBundleInfo = ConvertToUnpackInfo();
return _assist.Download.CreateDownload(unpackBundleInfo, failedTryAgain, timeout);
}
#endregion
#region Download
public DownloaderBase CreateDownloader(int failedTryAgain, int timeout = 60)
{
return _assist.Download.CreateDownload(this, failedTryAgain, timeout);
}
public DownloaderBase CreateUnpacker(int failedTryAgain, int timeout = 60)
{
var unpackBundleInfo = ConvertToUnpackInfo();
return _assist.Download.CreateDownload(unpackBundleInfo, failedTryAgain, timeout);
}
#endregion
#region AssetBundle
internal AssetBundle LoadAssetBundle(string fileLoadPath, out Stream managedStream)
{
return _assist.Loader.LoadAssetBundle(this, fileLoadPath, out managedStream);
}
internal AssetBundleCreateRequest LoadAssetBundleAsync(string fileLoadPath, out Stream managedStream)
{
return _assist.Loader.LoadAssetBundleAsync(this, fileLoadPath, out managedStream);
}
internal AssetBundle LoadDeliveryAssetBundle(string fileLoadPath)
{
return _assist.Loader.LoadDeliveryAssetBundle(this, fileLoadPath);
}
internal AssetBundleCreateRequest LoadDeliveryAssetBundleAsync(string fileLoadPath)
{
return _assist.Loader.LoadDeliveryAssetBundleAsync(this, fileLoadPath);
}
#endregion
#region AssetBundle
internal AssetBundle LoadAssetBundle(string fileLoadPath, out Stream managedStream)
{
return _assist.Loader.LoadAssetBundle(this, fileLoadPath, out managedStream);
}
internal AssetBundleCreateRequest LoadAssetBundleAsync(string fileLoadPath, out Stream managedStream)
{
return _assist.Loader.LoadAssetBundleAsync(this, fileLoadPath, out managedStream);
}
internal AssetBundle LoadDeliveryAssetBundle(string fileLoadPath)
{
return _assist.Loader.LoadDeliveryAssetBundle(this, fileLoadPath);
}
internal AssetBundleCreateRequest LoadDeliveryAssetBundleAsync(string fileLoadPath)
{
return _assist.Loader.LoadDeliveryAssetBundleAsync(this, fileLoadPath);
}
#endregion
/// <summary>
/// 转换为解压BundleInfo
/// </summary>
private BundleInfo ConvertToUnpackInfo()
{
string streamingPath = PersistentHelper.ConvertToWWWPath(BuildinFilePath);
BundleInfo newBundleInfo = new BundleInfo(_assist, Bundle, ELoadMode.LoadFromStreaming, streamingPath, streamingPath);
return newBundleInfo;
}
/// <summary>
/// 转换为解压BundleInfo
/// </summary>
private BundleInfo ConvertToUnpackInfo()
{
string streamingPath = PersistentHelper.ConvertToWWWPath(BuildinFilePath);
BundleInfo newBundleInfo = new BundleInfo(_assist, Bundle, ELoadMode.LoadFromStreaming, streamingPath, streamingPath);
return newBundleInfo;
}
/// <summary>
/// 批量创建解压BundleInfo
/// </summary>
public static List<BundleInfo> CreateUnpackInfos(ResourceAssist assist, List<PackageBundle> unpackList)
{
List<BundleInfo> result = new List<BundleInfo>(unpackList.Count);
foreach (var packageBundle in unpackList)
{
var bundleInfo = CreateUnpackInfo(assist, packageBundle);
result.Add(bundleInfo);
}
return result;
}
private static BundleInfo CreateUnpackInfo(ResourceAssist assist, PackageBundle packageBundle)
{
string streamingPath = PersistentHelper.ConvertToWWWPath(assist.Persistent.GetBuildinFilePath(packageBundle));
BundleInfo newBundleInfo = new BundleInfo(assist, packageBundle, ELoadMode.LoadFromStreaming, streamingPath, streamingPath);
return newBundleInfo;
}
/// <summary>
/// 批量创建解压BundleInfo
/// </summary>
public static List<BundleInfo> CreateUnpackInfos(ResourceAssist assist, List<PackageBundle> unpackList)
{
List<BundleInfo> result = new List<BundleInfo>(unpackList.Count);
foreach (var packageBundle in unpackList)
{
var bundleInfo = CreateUnpackInfo(assist, packageBundle);
result.Add(bundleInfo);
}
return result;
}
private static BundleInfo CreateUnpackInfo(ResourceAssist assist, PackageBundle packageBundle)
{
string streamingPath = PersistentHelper.ConvertToWWWPath(assist.Persistent.GetBuildinFilePath(packageBundle));
BundleInfo newBundleInfo = new BundleInfo(assist, packageBundle, ELoadMode.LoadFromStreaming, streamingPath, streamingPath);
return newBundleInfo;
}
/// <summary>
/// 创建导入BundleInfo
/// </summary>
public static BundleInfo CreateImportInfo(ResourceAssist assist, PackageBundle packageBundle, string filePath)
{
// 注意:我们把本地文件路径指定为远端下载地址
string persistentPath = PersistentHelper.ConvertToWWWPath(filePath);
BundleInfo bundleInfo = new BundleInfo(assist, packageBundle, BundleInfo.ELoadMode.None, persistentPath, persistentPath);
return bundleInfo;
}
}
/// <summary>
/// 创建导入BundleInfo
/// </summary>
public static BundleInfo CreateImportInfo(ResourceAssist assist, PackageBundle packageBundle, string filePath)
{
// 注意:我们把本地文件路径指定为远端下载地址
string persistentPath = PersistentHelper.ConvertToWWWPath(filePath);
BundleInfo bundleInfo = new BundleInfo(assist, packageBundle, BundleInfo.ELoadMode.None, persistentPath, persistentPath);
return bundleInfo;
}
}
}

View File

@ -1,31 +1,31 @@

namespace YooAsset
{
internal interface IBundleQuery
{
/// <summary>
/// 获取主资源包信息
/// </summary>
BundleInfo GetMainBundleInfo(AssetInfo assetInfo);
internal interface IBundleQuery
{
/// <summary>
/// 获取主资源包信息
/// </summary>
BundleInfo GetMainBundleInfo(AssetInfo assetInfo);
/// <summary>
/// 获取依赖的资源包信息集合
/// </summary>
BundleInfo[] GetDependBundleInfos(AssetInfo assetPath);
/// <summary>
/// 获取依赖的资源包信息集合
/// </summary>
BundleInfo[] GetDependBundleInfos(AssetInfo assetPath);
/// <summary>
/// 获取主资源包名称
/// </summary>
string GetMainBundleName(AssetInfo assetInfo);
/// <summary>
/// 获取主资源包名称
/// </summary>
string GetMainBundleName(AssetInfo assetInfo);
/// <summary>
/// 获取依赖的资源包名称集合
/// </summary>
string[] GetDependBundleNames(AssetInfo assetInfo);
/// <summary>
/// 获取依赖的资源包名称集合
/// </summary>
string[] GetDependBundleNames(AssetInfo assetInfo);
/// <summary>
/// 清单是否有效
/// </summary>
bool ManifestValid();
}
/// <summary>
/// 清单是否有效
/// </summary>
bool ManifestValid();
}
}

View File

@ -1,43 +1,43 @@

namespace YooAsset
{
internal interface IPlayMode
{
/// <summary>
/// 激活的清单
/// </summary>
PackageManifest ActiveManifest { set; get; }
internal interface IPlayMode
{
/// <summary>
/// 激活的清单
/// </summary>
PackageManifest ActiveManifest { set; get; }
/// <summary>
/// 保存清单版本文件到沙盒
/// </summary>
void FlushManifestVersionFile();
/// <summary>
/// 保存清单版本文件到沙盒
/// </summary>
void FlushManifestVersionFile();
/// <summary>
/// 向网络端请求最新的资源版本
/// </summary>
UpdatePackageVersionOperation UpdatePackageVersionAsync(bool appendTimeTicks, int timeout);
/// <summary>
/// 向网络端请求最新的资源版本
/// </summary>
UpdatePackageVersionOperation UpdatePackageVersionAsync(bool appendTimeTicks, int timeout);
/// <summary>
/// 向网络端请求并更新清单
/// </summary>
UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion, int timeout);
/// <summary>
/// 向网络端请求并更新清单
/// </summary>
UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion, int timeout);
/// <summary>
/// 预下载指定版本的包裹内容
/// </summary>
PreDownloadContentOperation PreDownloadContentAsync(string packageVersion, int timeout);
/// <summary>
/// 预下载指定版本的包裹内容
/// </summary>
PreDownloadContentOperation PreDownloadContentAsync(string packageVersion, int timeout);
// 下载相关
ResourceDownloaderOperation CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout);
ResourceDownloaderOperation CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout);
ResourceDownloaderOperation CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout);
// 下载相关
ResourceDownloaderOperation CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout);
ResourceDownloaderOperation CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout);
ResourceDownloaderOperation CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout);
// 解压相关
ResourceUnpackerOperation CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout);
ResourceUnpackerOperation CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout);
// 解压相关
ResourceUnpackerOperation CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout);
ResourceUnpackerOperation CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout);
// 导入相关
ResourceImporterOperation CreateResourceImporterByFilePaths(string[] filePaths, int importerMaxNumber, int failedTryAgain, int timeout);
}
// 导入相关
ResourceImporterOperation CreateResourceImporterByFilePaths(string[] filePaths, int importerMaxNumber, int failedTryAgain, int timeout);
}
}

View File

@ -6,228 +6,228 @@ using UnityEngine;
namespace YooAsset
{
internal static class ManifestTools
{
internal static class ManifestTools
{
#if UNITY_EDITOR
/// <summary>
/// 序列化JSON文件
/// </summary>
public static void SerializeToJson(string savePath, PackageManifest manifest)
{
string json = JsonUtility.ToJson(manifest, true);
FileUtility.WriteAllText(savePath, json);
}
/// <summary>
/// 序列化JSON文件
/// </summary>
public static void SerializeToJson(string savePath, PackageManifest manifest)
{
string json = JsonUtility.ToJson(manifest, true);
FileUtility.WriteAllText(savePath, json);
}
/// <summary>
/// 序列化(二进制文件)
/// </summary>
public static void SerializeToBinary(string savePath, PackageManifest manifest)
{
using (FileStream fs = new FileStream(savePath, FileMode.Create))
{
// 创建缓存器
BufferWriter buffer = new BufferWriter(YooAssetSettings.ManifestFileMaxSize);
/// <summary>
/// 序列化(二进制文件)
/// </summary>
public static void SerializeToBinary(string savePath, PackageManifest manifest)
{
using (FileStream fs = new FileStream(savePath, FileMode.Create))
{
// 创建缓存器
BufferWriter buffer = new BufferWriter(YooAssetSettings.ManifestFileMaxSize);
// 写入文件标记
buffer.WriteUInt32(YooAssetSettings.ManifestFileSign);
// 写入文件标记
buffer.WriteUInt32(YooAssetSettings.ManifestFileSign);
// 写入文件版本
buffer.WriteUTF8(manifest.FileVersion);
// 写入文件版本
buffer.WriteUTF8(manifest.FileVersion);
// 写入文件头信息
buffer.WriteBool(manifest.EnableAddressable);
buffer.WriteBool(manifest.LocationToLower);
buffer.WriteBool(manifest.IncludeAssetGUID);
buffer.WriteInt32(manifest.OutputNameStyle);
buffer.WriteUTF8(manifest.BuildPipeline);
buffer.WriteUTF8(manifest.PackageName);
buffer.WriteUTF8(manifest.PackageVersion);
// 写入文件头信息
buffer.WriteBool(manifest.EnableAddressable);
buffer.WriteBool(manifest.LocationToLower);
buffer.WriteBool(manifest.IncludeAssetGUID);
buffer.WriteInt32(manifest.OutputNameStyle);
buffer.WriteUTF8(manifest.BuildPipeline);
buffer.WriteUTF8(manifest.PackageName);
buffer.WriteUTF8(manifest.PackageVersion);
// 写入资源列表
buffer.WriteInt32(manifest.AssetList.Count);
for (int i = 0; i < manifest.AssetList.Count; i++)
{
var packageAsset = manifest.AssetList[i];
buffer.WriteUTF8(packageAsset.Address);
buffer.WriteUTF8(packageAsset.AssetPath);
buffer.WriteUTF8(packageAsset.AssetGUID);
buffer.WriteUTF8Array(packageAsset.AssetTags);
buffer.WriteInt32(packageAsset.BundleID);
}
// 写入资源列表
buffer.WriteInt32(manifest.AssetList.Count);
for (int i = 0; i < manifest.AssetList.Count; i++)
{
var packageAsset = manifest.AssetList[i];
buffer.WriteUTF8(packageAsset.Address);
buffer.WriteUTF8(packageAsset.AssetPath);
buffer.WriteUTF8(packageAsset.AssetGUID);
buffer.WriteUTF8Array(packageAsset.AssetTags);
buffer.WriteInt32(packageAsset.BundleID);
}
// 写入资源包列表
buffer.WriteInt32(manifest.BundleList.Count);
for (int i = 0; i < manifest.BundleList.Count; i++)
{
var packageBundle = manifest.BundleList[i];
buffer.WriteUTF8(packageBundle.BundleName);
buffer.WriteUInt32(packageBundle.UnityCRC);
buffer.WriteUTF8(packageBundle.FileHash);
buffer.WriteUTF8(packageBundle.FileCRC);
buffer.WriteInt64(packageBundle.FileSize);
buffer.WriteBool(packageBundle.Encrypted);
buffer.WriteUTF8Array(packageBundle.Tags);
buffer.WriteInt32Array(packageBundle.DependIDs);
}
// 写入资源包列表
buffer.WriteInt32(manifest.BundleList.Count);
for (int i = 0; i < manifest.BundleList.Count; i++)
{
var packageBundle = manifest.BundleList[i];
buffer.WriteUTF8(packageBundle.BundleName);
buffer.WriteUInt32(packageBundle.UnityCRC);
buffer.WriteUTF8(packageBundle.FileHash);
buffer.WriteUTF8(packageBundle.FileCRC);
buffer.WriteInt64(packageBundle.FileSize);
buffer.WriteBool(packageBundle.Encrypted);
buffer.WriteUTF8Array(packageBundle.Tags);
buffer.WriteInt32Array(packageBundle.DependIDs);
}
// 写入文件流
buffer.WriteToStream(fs);
fs.Flush();
}
}
// 写入文件流
buffer.WriteToStream(fs);
fs.Flush();
}
}
/// <summary>
/// 反序列化JSON文件
/// </summary>
public static PackageManifest DeserializeFromJson(string jsonContent)
{
return JsonUtility.FromJson<PackageManifest>(jsonContent);
}
/// <summary>
/// 反序列化JSON文件
/// </summary>
public static PackageManifest DeserializeFromJson(string jsonContent)
{
return JsonUtility.FromJson<PackageManifest>(jsonContent);
}
/// <summary>
/// 反序列化(二进制文件)
/// </summary>
public static PackageManifest DeserializeFromBinary(byte[] binaryData)
{
// 创建缓存器
BufferReader buffer = new BufferReader(binaryData);
/// <summary>
/// 反序列化(二进制文件)
/// </summary>
public static PackageManifest DeserializeFromBinary(byte[] binaryData)
{
// 创建缓存器
BufferReader buffer = new BufferReader(binaryData);
// 读取文件标记
uint fileSign = buffer.ReadUInt32();
if (fileSign != YooAssetSettings.ManifestFileSign)
throw new Exception("Invalid manifest file !");
// 读取文件标记
uint fileSign = buffer.ReadUInt32();
if (fileSign != YooAssetSettings.ManifestFileSign)
throw new Exception("Invalid manifest file !");
// 读取文件版本
string fileVersion = buffer.ReadUTF8();
if (fileVersion != YooAssetSettings.ManifestFileVersion)
throw new Exception($"The manifest file version are not compatible : {fileVersion} != {YooAssetSettings.ManifestFileVersion}");
// 读取文件版本
string fileVersion = buffer.ReadUTF8();
if (fileVersion != YooAssetSettings.ManifestFileVersion)
throw new Exception($"The manifest file version are not compatible : {fileVersion} != {YooAssetSettings.ManifestFileVersion}");
PackageManifest manifest = new PackageManifest();
{
// 读取文件头信息
manifest.FileVersion = fileVersion;
manifest.EnableAddressable = buffer.ReadBool();
manifest.LocationToLower = buffer.ReadBool();
manifest.IncludeAssetGUID = buffer.ReadBool();
manifest.OutputNameStyle = buffer.ReadInt32();
manifest.BuildPipeline = buffer.ReadUTF8();
manifest.PackageName = buffer.ReadUTF8();
manifest.PackageVersion = buffer.ReadUTF8();
PackageManifest manifest = new PackageManifest();
{
// 读取文件头信息
manifest.FileVersion = fileVersion;
manifest.EnableAddressable = buffer.ReadBool();
manifest.LocationToLower = buffer.ReadBool();
manifest.IncludeAssetGUID = buffer.ReadBool();
manifest.OutputNameStyle = buffer.ReadInt32();
manifest.BuildPipeline = buffer.ReadUTF8();
manifest.PackageName = buffer.ReadUTF8();
manifest.PackageVersion = buffer.ReadUTF8();
// 检测配置
if (manifest.EnableAddressable && manifest.LocationToLower)
throw new Exception("Addressable not support location to lower !");
// 检测配置
if (manifest.EnableAddressable && manifest.LocationToLower)
throw new Exception("Addressable not support location to lower !");
// 读取资源列表
int packageAssetCount = buffer.ReadInt32();
manifest.AssetList = new List<PackageAsset>(packageAssetCount);
for (int i = 0; i < packageAssetCount; i++)
{
var packageAsset = new PackageAsset();
packageAsset.Address = buffer.ReadUTF8();
packageAsset.AssetPath = buffer.ReadUTF8();
packageAsset.AssetGUID = buffer.ReadUTF8();
packageAsset.AssetTags = buffer.ReadUTF8Array();
packageAsset.BundleID = buffer.ReadInt32();
manifest.AssetList.Add(packageAsset);
}
// 读取资源列表
int packageAssetCount = buffer.ReadInt32();
manifest.AssetList = new List<PackageAsset>(packageAssetCount);
for (int i = 0; i < packageAssetCount; i++)
{
var packageAsset = new PackageAsset();
packageAsset.Address = buffer.ReadUTF8();
packageAsset.AssetPath = buffer.ReadUTF8();
packageAsset.AssetGUID = buffer.ReadUTF8();
packageAsset.AssetTags = buffer.ReadUTF8Array();
packageAsset.BundleID = buffer.ReadInt32();
manifest.AssetList.Add(packageAsset);
}
// 读取资源包列表
int packageBundleCount = buffer.ReadInt32();
manifest.BundleList = new List<PackageBundle>(packageBundleCount);
for (int i = 0; i < packageBundleCount; i++)
{
var packageBundle = new PackageBundle();
packageBundle.BundleName = buffer.ReadUTF8();
packageBundle.UnityCRC = buffer.ReadUInt32();
packageBundle.FileHash = buffer.ReadUTF8();
packageBundle.FileCRC = buffer.ReadUTF8();
packageBundle.FileSize = buffer.ReadInt64();
packageBundle.Encrypted = buffer.ReadBool();
packageBundle.Tags = buffer.ReadUTF8Array();
packageBundle.DependIDs = buffer.ReadInt32Array();
manifest.BundleList.Add(packageBundle);
}
}
// 读取资源包列表
int packageBundleCount = buffer.ReadInt32();
manifest.BundleList = new List<PackageBundle>(packageBundleCount);
for (int i = 0; i < packageBundleCount; i++)
{
var packageBundle = new PackageBundle();
packageBundle.BundleName = buffer.ReadUTF8();
packageBundle.UnityCRC = buffer.ReadUInt32();
packageBundle.FileHash = buffer.ReadUTF8();
packageBundle.FileCRC = buffer.ReadUTF8();
packageBundle.FileSize = buffer.ReadInt64();
packageBundle.Encrypted = buffer.ReadBool();
packageBundle.Tags = buffer.ReadUTF8Array();
packageBundle.DependIDs = buffer.ReadInt32Array();
manifest.BundleList.Add(packageBundle);
}
}
// 填充BundleDic
manifest.BundleDic1 = new Dictionary<string, PackageBundle>(manifest.BundleList.Count);
manifest.BundleDic2 = new Dictionary<string, PackageBundle>(manifest.BundleList.Count);
foreach (var packageBundle in manifest.BundleList)
{
packageBundle.ParseBundle(manifest);
manifest.BundleDic1.Add(packageBundle.BundleName, packageBundle);
manifest.BundleDic2.Add(packageBundle.FileName, packageBundle);
}
// 填充BundleDic
manifest.BundleDic1 = new Dictionary<string, PackageBundle>(manifest.BundleList.Count);
manifest.BundleDic2 = new Dictionary<string, PackageBundle>(manifest.BundleList.Count);
foreach (var packageBundle in manifest.BundleList)
{
packageBundle.ParseBundle(manifest);
manifest.BundleDic1.Add(packageBundle.BundleName, packageBundle);
manifest.BundleDic2.Add(packageBundle.FileName, packageBundle);
}
// 填充AssetDic
manifest.AssetDic = new Dictionary<string, PackageAsset>(manifest.AssetList.Count);
foreach (var packageAsset in manifest.AssetList)
{
// 注意:我们不允许原始路径存在重名
string assetPath = packageAsset.AssetPath;
if (manifest.AssetDic.ContainsKey(assetPath))
throw new Exception($"AssetPath have existed : {assetPath}");
else
manifest.AssetDic.Add(assetPath, packageAsset);
}
// 填充AssetDic
manifest.AssetDic = new Dictionary<string, PackageAsset>(manifest.AssetList.Count);
foreach (var packageAsset in manifest.AssetList)
{
// 注意:我们不允许原始路径存在重名
string assetPath = packageAsset.AssetPath;
if (manifest.AssetDic.ContainsKey(assetPath))
throw new Exception($"AssetPath have existed : {assetPath}");
else
manifest.AssetDic.Add(assetPath, packageAsset);
}
return manifest;
}
return manifest;
}
#endif
/// <summary>
/// 注意:该类拷贝自编辑器
/// </summary>
private enum EFileNameStyle
{
/// <summary>
/// 哈希值名称
/// </summary>
HashName = 0,
/// <summary>
/// 注意:该类拷贝自编辑器
/// </summary>
private enum EFileNameStyle
{
/// <summary>
/// 哈希值名称
/// </summary>
HashName = 0,
/// <summary>
/// 资源包名称(不推荐)
/// </summary>
BundleName = 1,
/// <summary>
/// 资源包名称(不推荐)
/// </summary>
BundleName = 1,
/// <summary>
/// 资源包名称 + 哈希值名称
/// </summary>
BundleName_HashName = 2,
}
/// <summary>
/// 资源包名称 + 哈希值名称
/// </summary>
BundleName_HashName = 2,
}
/// <summary>
/// 获取资源文件的后缀名
/// </summary>
public static string GetRemoteBundleFileExtension(string bundleName)
{
string fileExtension = Path.GetExtension(bundleName);
return fileExtension;
}
/// <summary>
/// 获取资源文件的后缀名
/// </summary>
public static string GetRemoteBundleFileExtension(string bundleName)
{
string fileExtension = Path.GetExtension(bundleName);
return fileExtension;
}
/// <summary>
/// 获取远端的资源文件名
/// </summary>
public static string GetRemoteBundleFileName(int nameStyle, string bundleName, string fileExtension, string fileHash)
{
if (nameStyle == (int)EFileNameStyle.HashName)
{
return StringUtility.Format("{0}{1}", fileHash, fileExtension);
}
else if (nameStyle == (int)EFileNameStyle.BundleName)
{
return bundleName;
}
else if (nameStyle == (int)EFileNameStyle.BundleName_HashName)
{
string fileName = bundleName.Remove(bundleName.LastIndexOf('.'));
return StringUtility.Format("{0}_{1}{2}", fileName, fileHash, fileExtension);
}
else
{
throw new NotImplementedException($"Invalid name style : {nameStyle}");
}
}
}
/// <summary>
/// 获取远端的资源文件名
/// </summary>
public static string GetRemoteBundleFileName(int nameStyle, string bundleName, string fileExtension, string fileHash)
{
if (nameStyle == (int)EFileNameStyle.HashName)
{
return StringUtility.Format("{0}{1}", fileHash, fileExtension);
}
else if (nameStyle == (int)EFileNameStyle.BundleName)
{
return bundleName;
}
else if (nameStyle == (int)EFileNameStyle.BundleName_HashName)
{
string fileName = bundleName.Remove(bundleName.LastIndexOf('.'));
return StringUtility.Format("{0}_{1}{2}", fileName, fileHash, fileExtension);
}
else
{
throw new NotImplementedException($"Invalid name style : {nameStyle}");
}
}
}
}

View File

@ -3,366 +3,366 @@ using System.Collections.Generic;
namespace YooAsset
{
public abstract class DownloaderOperation : AsyncOperationBase
{
private enum ESteps
{
None,
Check,
Loading,
Done,
}
public abstract class DownloaderOperation : AsyncOperationBase
{
private enum ESteps
{
None,
Check,
Loading,
Done,
}
private const int MAX_LOADER_COUNT = 64;
private const int MAX_LOADER_COUNT = 64;
public delegate void OnDownloadOver(bool isSucceed);
public delegate void OnDownloadProgress(int totalDownloadCount, int currentDownloadCount, long totalDownloadBytes, long currentDownloadBytes);
public delegate void OnDownloadError(string fileName, string error);
public delegate void OnStartDownloadFile(string fileName, long sizeBytes);
public delegate void OnDownloadOver(bool isSucceed);
public delegate void OnDownloadProgress(int totalDownloadCount, int currentDownloadCount, long totalDownloadBytes, long currentDownloadBytes);
public delegate void OnDownloadError(string fileName, string error);
public delegate void OnStartDownloadFile(string fileName, long sizeBytes);
private readonly DownloadManager _downloadMgr;
private readonly string _packageName;
private readonly int _downloadingMaxNumber;
private readonly int _failedTryAgain;
private readonly int _timeout;
private readonly List<BundleInfo> _bundleInfoList;
private readonly List<DownloaderBase> _downloaders = new List<DownloaderBase>(MAX_LOADER_COUNT);
private readonly List<DownloaderBase> _removeList = new List<DownloaderBase>(MAX_LOADER_COUNT);
private readonly List<DownloaderBase> _failedList = new List<DownloaderBase>(MAX_LOADER_COUNT);
private readonly DownloadManager _downloadMgr;
private readonly string _packageName;
private readonly int _downloadingMaxNumber;
private readonly int _failedTryAgain;
private readonly int _timeout;
private readonly List<BundleInfo> _bundleInfoList;
private readonly List<DownloaderBase> _downloaders = new List<DownloaderBase>(MAX_LOADER_COUNT);
private readonly List<DownloaderBase> _removeList = new List<DownloaderBase>(MAX_LOADER_COUNT);
private readonly List<DownloaderBase> _failedList = new List<DownloaderBase>(MAX_LOADER_COUNT);
// 数据相关
private bool _isPause = false;
private long _lastDownloadBytes = 0;
private int _lastDownloadCount = 0;
private long _cachedDownloadBytes = 0;
private int _cachedDownloadCount = 0;
private ESteps _steps = ESteps.None;
// 数据相关
private bool _isPause = false;
private long _lastDownloadBytes = 0;
private int _lastDownloadCount = 0;
private long _cachedDownloadBytes = 0;
private int _cachedDownloadCount = 0;
private ESteps _steps = ESteps.None;
/// <summary>
/// 统计的下载文件总数量
/// </summary>
public int TotalDownloadCount { private set; get; }
/// <summary>
/// 统计的下载文件总数量
/// </summary>
public int TotalDownloadCount { private set; get; }
/// <summary>
/// 统计的下载文件的总大小
/// </summary>
public long TotalDownloadBytes { private set; get; }
/// <summary>
/// 统计的下载文件的总大小
/// </summary>
public long TotalDownloadBytes { private set; get; }
/// <summary>
/// 当前已经完成的下载总数量
/// </summary>
public int CurrentDownloadCount
{
get { return _lastDownloadCount; }
}
/// <summary>
/// 当前已经完成的下载总数量
/// </summary>
public int CurrentDownloadCount
{
get { return _lastDownloadCount; }
}
/// <summary>
/// 当前已经完成的下载总大小
/// </summary>
public long CurrentDownloadBytes
{
get { return _lastDownloadBytes; }
}
/// <summary>
/// 当前已经完成的下载总大小
/// </summary>
public long CurrentDownloadBytes
{
get { return _lastDownloadBytes; }
}
/// <summary>
/// 当下载器结束(无论成功或失败)
/// </summary>
public OnDownloadOver OnDownloadOverCallback { set; get; }
/// <summary>
/// 当下载器结束(无论成功或失败)
/// </summary>
public OnDownloadOver OnDownloadOverCallback { set; get; }
/// <summary>
/// 当下载进度发生变化
/// </summary>
public OnDownloadProgress OnDownloadProgressCallback { set; get; }
/// <summary>
/// 当下载进度发生变化
/// </summary>
public OnDownloadProgress OnDownloadProgressCallback { set; get; }
/// <summary>
/// 当某个文件下载失败
/// </summary>
public OnDownloadError OnDownloadErrorCallback { set; get; }
/// <summary>
/// 当某个文件下载失败
/// </summary>
public OnDownloadError OnDownloadErrorCallback { set; get; }
/// <summary>
/// 当开始下载某个文件
/// </summary>
public OnStartDownloadFile OnStartDownloadFileCallback { set; get; }
/// <summary>
/// 当开始下载某个文件
/// </summary>
public OnStartDownloadFile OnStartDownloadFileCallback { set; get; }
internal DownloaderOperation(DownloadManager downloadMgr, string packageName, List<BundleInfo> downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
_downloadMgr = downloadMgr;
_packageName = packageName;
_bundleInfoList = downloadList;
_downloadingMaxNumber = UnityEngine.Mathf.Clamp(downloadingMaxNumber, 1, MAX_LOADER_COUNT); ;
_failedTryAgain = failedTryAgain;
_timeout = timeout;
internal DownloaderOperation(DownloadManager downloadMgr, string packageName, List<BundleInfo> downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
_downloadMgr = downloadMgr;
_packageName = packageName;
_bundleInfoList = downloadList;
_downloadingMaxNumber = UnityEngine.Mathf.Clamp(downloadingMaxNumber, 1, MAX_LOADER_COUNT); ;
_failedTryAgain = failedTryAgain;
_timeout = timeout;
// 统计下载信息
CalculatDownloaderInfo();
}
internal override void InternalOnStart()
{
YooLogger.Log($"Begine to download : {TotalDownloadCount} files and {TotalDownloadBytes} bytes");
_steps = ESteps.Check;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 统计下载信息
CalculatDownloaderInfo();
}
internal override void InternalOnStart()
{
YooLogger.Log($"Begine to download : {TotalDownloadCount} files and {TotalDownloadBytes} bytes");
_steps = ESteps.Check;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.Check)
{
if (_bundleInfoList == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Download list is null.";
}
else
{
_steps = ESteps.Loading;
}
}
if (_steps == ESteps.Check)
{
if (_bundleInfoList == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Download list is null.";
}
else
{
_steps = ESteps.Loading;
}
}
if (_steps == ESteps.Loading)
{
// 检测下载器结果
_removeList.Clear();
long downloadBytes = _cachedDownloadBytes;
foreach (var downloader in _downloaders)
{
downloadBytes += (long)downloader.DownloadedBytes;
if (downloader.IsDone() == false)
continue;
if (_steps == ESteps.Loading)
{
// 检测下载器结果
_removeList.Clear();
long downloadBytes = _cachedDownloadBytes;
foreach (var downloader in _downloaders)
{
downloadBytes += (long)downloader.DownloadedBytes;
if (downloader.IsDone() == false)
continue;
// 检测是否下载失败
if (downloader.HasError())
{
_removeList.Add(downloader);
_failedList.Add(downloader);
continue;
}
// 检测是否下载失败
if (downloader.HasError())
{
_removeList.Add(downloader);
_failedList.Add(downloader);
continue;
}
// 下载成功
_removeList.Add(downloader);
_cachedDownloadCount++;
_cachedDownloadBytes += downloader.GetDownloadFileSize();
}
// 下载成功
_removeList.Add(downloader);
_cachedDownloadCount++;
_cachedDownloadBytes += downloader.GetDownloadFileSize();
}
// 移除已经完成的下载器(无论成功或失败)
foreach (var loader in _removeList)
{
_downloaders.Remove(loader);
}
// 移除已经完成的下载器(无论成功或失败)
foreach (var loader in _removeList)
{
_downloaders.Remove(loader);
}
// 如果下载进度发生变化
if (_lastDownloadBytes != downloadBytes || _lastDownloadCount != _cachedDownloadCount)
{
_lastDownloadBytes = downloadBytes;
_lastDownloadCount = _cachedDownloadCount;
Progress = (float)_lastDownloadBytes / TotalDownloadBytes;
OnDownloadProgressCallback?.Invoke(TotalDownloadCount, _lastDownloadCount, TotalDownloadBytes, _lastDownloadBytes);
}
// 如果下载进度发生变化
if (_lastDownloadBytes != downloadBytes || _lastDownloadCount != _cachedDownloadCount)
{
_lastDownloadBytes = downloadBytes;
_lastDownloadCount = _cachedDownloadCount;
Progress = (float)_lastDownloadBytes / TotalDownloadBytes;
OnDownloadProgressCallback?.Invoke(TotalDownloadCount, _lastDownloadCount, TotalDownloadBytes, _lastDownloadBytes);
}
// 动态创建新的下载器到最大数量限制
// 注意:如果期间有下载失败的文件,暂停动态创建下载器
if (_bundleInfoList.Count > 0 && _failedList.Count == 0)
{
if (_isPause)
return;
// 动态创建新的下载器到最大数量限制
// 注意:如果期间有下载失败的文件,暂停动态创建下载器
if (_bundleInfoList.Count > 0 && _failedList.Count == 0)
{
if (_isPause)
return;
if (_downloaders.Count < _downloadingMaxNumber)
{
int index = _bundleInfoList.Count - 1;
var bundleInfo = _bundleInfoList[index];
var downloader = bundleInfo.CreateDownloader(_failedTryAgain, _timeout);
downloader.SendRequest();
_downloaders.Add(downloader);
_bundleInfoList.RemoveAt(index);
OnStartDownloadFileCallback?.Invoke(bundleInfo.Bundle.BundleName, bundleInfo.Bundle.FileSize);
}
}
if (_downloaders.Count < _downloadingMaxNumber)
{
int index = _bundleInfoList.Count - 1;
var bundleInfo = _bundleInfoList[index];
var downloader = bundleInfo.CreateDownloader(_failedTryAgain, _timeout);
downloader.SendRequest();
_downloaders.Add(downloader);
_bundleInfoList.RemoveAt(index);
OnStartDownloadFileCallback?.Invoke(bundleInfo.Bundle.BundleName, bundleInfo.Bundle.FileSize);
}
}
// 下载结算
if (_downloaders.Count == 0)
{
if (_failedList.Count > 0)
{
var failedDownloader = _failedList[0];
string bundleName = failedDownloader.GetDownloadBundleName();
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed to download file : {bundleName}";
OnDownloadErrorCallback?.Invoke(bundleName, failedDownloader.GetLastError());
OnDownloadOverCallback?.Invoke(false);
}
else
{
// 结算成功
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
OnDownloadOverCallback?.Invoke(true);
}
}
}
}
private void CalculatDownloaderInfo()
{
if (_bundleInfoList != null)
{
TotalDownloadBytes = 0;
TotalDownloadCount = _bundleInfoList.Count;
foreach (var packageBundle in _bundleInfoList)
{
TotalDownloadBytes += packageBundle.Bundle.FileSize;
}
}
else
{
TotalDownloadBytes = 0;
TotalDownloadCount = 0;
}
}
// 下载结算
if (_downloaders.Count == 0)
{
if (_failedList.Count > 0)
{
var failedDownloader = _failedList[0];
string bundleName = failedDownloader.GetDownloadBundleName();
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed to download file : {bundleName}";
OnDownloadErrorCallback?.Invoke(bundleName, failedDownloader.GetLastError());
OnDownloadOverCallback?.Invoke(false);
}
else
{
// 结算成功
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
OnDownloadOverCallback?.Invoke(true);
}
}
}
}
private void CalculatDownloaderInfo()
{
if (_bundleInfoList != null)
{
TotalDownloadBytes = 0;
TotalDownloadCount = _bundleInfoList.Count;
foreach (var packageBundle in _bundleInfoList)
{
TotalDownloadBytes += packageBundle.Bundle.FileSize;
}
}
else
{
TotalDownloadBytes = 0;
TotalDownloadCount = 0;
}
}
/// <summary>
/// 合并其它下载器
/// </summary>
/// <param name="downloader">合并的下载器</param>
public void Combine(DownloaderOperation downloader)
{
if (_packageName != downloader._packageName)
{
YooLogger.Error("The downloaders have different resource packages !");
return;
}
/// <summary>
/// 合并其它下载器
/// </summary>
/// <param name="downloader">合并的下载器</param>
public void Combine(DownloaderOperation downloader)
{
if (_packageName != downloader._packageName)
{
YooLogger.Error("The downloaders have different resource packages !");
return;
}
if (Status != EOperationStatus.None)
{
YooLogger.Error("The downloader is running, can not combine with other downloader !");
return;
}
if (Status != EOperationStatus.None)
{
YooLogger.Error("The downloader is running, can not combine with other downloader !");
return;
}
HashSet<string> temper = new HashSet<string>();
foreach (var bundleInfo in _bundleInfoList)
{
if (temper.Contains(bundleInfo.CachedDataFilePath) == false)
{
temper.Add(bundleInfo.CachedDataFilePath);
}
}
HashSet<string> temper = new HashSet<string>();
foreach (var bundleInfo in _bundleInfoList)
{
if (temper.Contains(bundleInfo.CachedDataFilePath) == false)
{
temper.Add(bundleInfo.CachedDataFilePath);
}
}
// 合并下载列表
foreach (var bundleInfo in downloader._bundleInfoList)
{
if (temper.Contains(bundleInfo.CachedDataFilePath) == false)
{
_bundleInfoList.Add(bundleInfo);
}
}
// 合并下载列表
foreach (var bundleInfo in downloader._bundleInfoList)
{
if (temper.Contains(bundleInfo.CachedDataFilePath) == false)
{
_bundleInfoList.Add(bundleInfo);
}
}
// 重新统计下载信息
CalculatDownloaderInfo();
}
// 重新统计下载信息
CalculatDownloaderInfo();
}
/// <summary>
/// 开始下载
/// </summary>
public void BeginDownload()
{
if (_steps == ESteps.None)
{
OperationSystem.StartOperation(_packageName, this);
}
}
/// <summary>
/// 开始下载
/// </summary>
public void BeginDownload()
{
if (_steps == ESteps.None)
{
OperationSystem.StartOperation(_packageName, this);
}
}
/// <summary>
/// 暂停下载
/// </summary>
public void PauseDownload()
{
_isPause = true;
}
/// <summary>
/// 暂停下载
/// </summary>
public void PauseDownload()
{
_isPause = true;
}
/// <summary>
/// 恢复下载
/// </summary>
public void ResumeDownload()
{
_isPause = false;
}
/// <summary>
/// 恢复下载
/// </summary>
public void ResumeDownload()
{
_isPause = false;
}
/// <summary>
/// 取消下载
/// </summary>
public void CancelDownload()
{
if (_steps != ESteps.Done)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "User cancel.";
ReleaseAllDownloader();
}
}
private void ReleaseAllDownloader()
{
foreach (var downloader in _downloaders)
{
downloader.Release();
}
/// <summary>
/// 取消下载
/// </summary>
public void CancelDownload()
{
if (_steps != ESteps.Done)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "User cancel.";
ReleaseAllDownloader();
}
}
private void ReleaseAllDownloader()
{
foreach (var downloader in _downloaders)
{
downloader.Release();
}
// 注意:停止不再使用的下载器
_downloadMgr.AbortUnusedDownloader();
}
}
// 注意:停止不再使用的下载器
_downloadMgr.AbortUnusedDownloader();
}
}
public sealed class ResourceDownloaderOperation : DownloaderOperation
{
internal ResourceDownloaderOperation(DownloadManager downloadMgr, string packageName, List<BundleInfo> downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout)
: base(downloadMgr, packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout)
{
}
public sealed class ResourceDownloaderOperation : DownloaderOperation
{
internal ResourceDownloaderOperation(DownloadManager downloadMgr, string packageName, List<BundleInfo> downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout)
: base(downloadMgr, packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout)
{
}
/// <summary>
/// 创建空的下载器
/// </summary>
internal static ResourceDownloaderOperation CreateEmptyDownloader(DownloadManager downloadMgr, string packageName, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> downloadList = new List<BundleInfo>();
var operation = new ResourceDownloaderOperation(downloadMgr, packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
}
public sealed class ResourceUnpackerOperation : DownloaderOperation
{
internal ResourceUnpackerOperation(DownloadManager downloadMgr, string packageName, List<BundleInfo> downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout)
: base(downloadMgr, packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout)
{
}
/// <summary>
/// 创建空的下载器
/// </summary>
internal static ResourceDownloaderOperation CreateEmptyDownloader(DownloadManager downloadMgr, string packageName, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> downloadList = new List<BundleInfo>();
var operation = new ResourceDownloaderOperation(downloadMgr, packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
}
public sealed class ResourceUnpackerOperation : DownloaderOperation
{
internal ResourceUnpackerOperation(DownloadManager downloadMgr, string packageName, List<BundleInfo> downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout)
: base(downloadMgr, packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout)
{
}
/// <summary>
/// 创建空的解压器
/// </summary>
internal static ResourceUnpackerOperation CreateEmptyUnpacker(DownloadManager downloadMgr, string packageName, int upackingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> downloadList = new List<BundleInfo>();
var operation = new ResourceUnpackerOperation(downloadMgr, packageName, downloadList, upackingMaxNumber, failedTryAgain, int.MaxValue);
return operation;
}
}
public sealed class ResourceImporterOperation : DownloaderOperation
{
internal ResourceImporterOperation(DownloadManager downloadMgr, string packageName, List<BundleInfo> downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout)
: base(downloadMgr, packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout)
{
}
/// <summary>
/// 创建空的解压器
/// </summary>
internal static ResourceUnpackerOperation CreateEmptyUnpacker(DownloadManager downloadMgr, string packageName, int upackingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> downloadList = new List<BundleInfo>();
var operation = new ResourceUnpackerOperation(downloadMgr, packageName, downloadList, upackingMaxNumber, failedTryAgain, int.MaxValue);
return operation;
}
}
public sealed class ResourceImporterOperation : DownloaderOperation
{
internal ResourceImporterOperation(DownloadManager downloadMgr, string packageName, List<BundleInfo> downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout)
: base(downloadMgr, packageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout)
{
}
/// <summary>
/// 创建空的导入器
/// </summary>
internal static ResourceImporterOperation CreateEmptyImporter(DownloadManager downloadMgr, string packageName, int upackingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> downloadList = new List<BundleInfo>();
var operation = new ResourceImporterOperation(downloadMgr, packageName, downloadList, upackingMaxNumber, failedTryAgain, int.MaxValue);
return operation;
}
}
/// <summary>
/// 创建空的导入器
/// </summary>
internal static ResourceImporterOperation CreateEmptyImporter(DownloadManager downloadMgr, string packageName, int upackingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> downloadList = new List<BundleInfo>();
var operation = new ResourceImporterOperation(downloadMgr, packageName, downloadList, upackingMaxNumber, failedTryAgain, int.MaxValue);
return operation;
}
}
}

View File

@ -5,500 +5,500 @@ using UnityEngine;
namespace YooAsset
{
/// <summary>
/// 初始化操作
/// </summary>
public abstract class InitializationOperation : AsyncOperationBase
{
public string PackageVersion { protected set; get; }
}
/// <summary>
/// 初始化操作
/// </summary>
public abstract class InitializationOperation : AsyncOperationBase
{
public string PackageVersion { protected set; get; }
}
/// <summary>
/// 编辑器下模拟模式的初始化操作
/// </summary>
internal sealed class EditorSimulateModeInitializationOperation : InitializationOperation
{
private enum ESteps
{
None,
LoadEditorManifest,
Done,
}
/// <summary>
/// 编辑器下模拟模式的初始化操作
/// </summary>
internal sealed class EditorSimulateModeInitializationOperation : InitializationOperation
{
private enum ESteps
{
None,
LoadEditorManifest,
Done,
}
private readonly EditorSimulateModeImpl _impl;
private readonly string _simulateManifestFilePath;
private LoadEditorManifestOperation _loadEditorManifestOp;
private ESteps _steps = ESteps.None;
private readonly EditorSimulateModeImpl _impl;
private readonly string _simulateManifestFilePath;
private LoadEditorManifestOperation _loadEditorManifestOp;
private ESteps _steps = ESteps.None;
internal EditorSimulateModeInitializationOperation(EditorSimulateModeImpl impl, string simulateManifestFilePath)
{
_impl = impl;
_simulateManifestFilePath = simulateManifestFilePath;
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadEditorManifest;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.LoadEditorManifest)
{
if (_loadEditorManifestOp == null)
{
_loadEditorManifestOp = new LoadEditorManifestOperation(_impl.PackageName, _simulateManifestFilePath);
OperationSystem.StartOperation(_impl.PackageName, _loadEditorManifestOp);
}
internal EditorSimulateModeInitializationOperation(EditorSimulateModeImpl impl, string simulateManifestFilePath)
{
_impl = impl;
_simulateManifestFilePath = simulateManifestFilePath;
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadEditorManifest;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.LoadEditorManifest)
{
if (_loadEditorManifestOp == null)
{
_loadEditorManifestOp = new LoadEditorManifestOperation(_impl.PackageName, _simulateManifestFilePath);
OperationSystem.StartOperation(_impl.PackageName, _loadEditorManifestOp);
}
if (_loadEditorManifestOp.IsDone == false)
return;
if (_loadEditorManifestOp.IsDone == false)
return;
if (_loadEditorManifestOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _loadEditorManifestOp.Manifest.PackageVersion;
_impl.ActiveManifest = _loadEditorManifestOp.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadEditorManifestOp.Error;
}
}
}
}
if (_loadEditorManifestOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _loadEditorManifestOp.Manifest.PackageVersion;
_impl.ActiveManifest = _loadEditorManifestOp.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadEditorManifestOp.Error;
}
}
}
}
/// <summary>
/// 离线运行模式的初始化操作
/// </summary>
internal sealed class OfflinePlayModeInitializationOperation : InitializationOperation
{
private enum ESteps
{
None,
QueryBuildinPackageVersion,
LoadBuildinManifest,
PackageCaching,
Done,
}
/// <summary>
/// 离线运行模式的初始化操作
/// </summary>
internal sealed class OfflinePlayModeInitializationOperation : InitializationOperation
{
private enum ESteps
{
None,
QueryBuildinPackageVersion,
LoadBuildinManifest,
PackageCaching,
Done,
}
private readonly OfflinePlayModeImpl _impl;
private QueryBuildinPackageVersionOperation _queryBuildinPackageVersionOp;
private LoadBuildinManifestOperation _loadBuildinManifestOp;
private PackageCachingOperation _cachingOperation;
private ESteps _steps = ESteps.None;
private readonly OfflinePlayModeImpl _impl;
private QueryBuildinPackageVersionOperation _queryBuildinPackageVersionOp;
private LoadBuildinManifestOperation _loadBuildinManifestOp;
private PackageCachingOperation _cachingOperation;
private ESteps _steps = ESteps.None;
internal OfflinePlayModeInitializationOperation(OfflinePlayModeImpl impl)
{
_impl = impl;
}
internal override void InternalOnStart()
{
_steps = ESteps.QueryBuildinPackageVersion;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
internal OfflinePlayModeInitializationOperation(OfflinePlayModeImpl impl)
{
_impl = impl;
}
internal override void InternalOnStart()
{
_steps = ESteps.QueryBuildinPackageVersion;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.QueryBuildinPackageVersion)
{
if (_queryBuildinPackageVersionOp == null)
{
_queryBuildinPackageVersionOp = new QueryBuildinPackageVersionOperation(_impl.Persistent);
OperationSystem.StartOperation(_impl.PackageName, _queryBuildinPackageVersionOp);
}
if (_steps == ESteps.QueryBuildinPackageVersion)
{
if (_queryBuildinPackageVersionOp == null)
{
_queryBuildinPackageVersionOp = new QueryBuildinPackageVersionOperation(_impl.Persistent);
OperationSystem.StartOperation(_impl.PackageName, _queryBuildinPackageVersionOp);
}
if (_queryBuildinPackageVersionOp.IsDone == false)
return;
if (_queryBuildinPackageVersionOp.IsDone == false)
return;
if (_queryBuildinPackageVersionOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadBuildinManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _queryBuildinPackageVersionOp.Error;
}
}
if (_queryBuildinPackageVersionOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadBuildinManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _queryBuildinPackageVersionOp.Error;
}
}
if (_steps == ESteps.LoadBuildinManifest)
{
if (_loadBuildinManifestOp == null)
{
_loadBuildinManifestOp = new LoadBuildinManifestOperation(_impl.Persistent, _queryBuildinPackageVersionOp.PackageVersion);
OperationSystem.StartOperation(_impl.PackageName, _loadBuildinManifestOp);
}
if (_steps == ESteps.LoadBuildinManifest)
{
if (_loadBuildinManifestOp == null)
{
_loadBuildinManifestOp = new LoadBuildinManifestOperation(_impl.Persistent, _queryBuildinPackageVersionOp.PackageVersion);
OperationSystem.StartOperation(_impl.PackageName, _loadBuildinManifestOp);
}
Progress = _loadBuildinManifestOp.Progress;
if (_loadBuildinManifestOp.IsDone == false)
return;
Progress = _loadBuildinManifestOp.Progress;
if (_loadBuildinManifestOp.IsDone == false)
return;
if (_loadBuildinManifestOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _loadBuildinManifestOp.Manifest.PackageVersion;
_impl.ActiveManifest = _loadBuildinManifestOp.Manifest;
_steps = ESteps.PackageCaching;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadBuildinManifestOp.Error;
}
}
if (_loadBuildinManifestOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _loadBuildinManifestOp.Manifest.PackageVersion;
_impl.ActiveManifest = _loadBuildinManifestOp.Manifest;
_steps = ESteps.PackageCaching;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadBuildinManifestOp.Error;
}
}
if (_steps == ESteps.PackageCaching)
{
if (_cachingOperation == null)
{
_cachingOperation = new PackageCachingOperation(_impl.Persistent, _impl.Cache);
OperationSystem.StartOperation(_impl.PackageName, _cachingOperation);
}
if (_steps == ESteps.PackageCaching)
{
if (_cachingOperation == null)
{
_cachingOperation = new PackageCachingOperation(_impl.Persistent, _impl.Cache);
OperationSystem.StartOperation(_impl.PackageName, _cachingOperation);
}
Progress = _cachingOperation.Progress;
if (_cachingOperation.IsDone)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
Progress = _cachingOperation.Progress;
if (_cachingOperation.IsDone)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
/// <summary>
/// 联机运行模式的初始化操作
/// 注意:优先从沙盒里加载清单,如果沙盒里不存在就尝试把内置清单拷贝到沙盒并加载该清单。
/// </summary>
internal sealed class HostPlayModeInitializationOperation : InitializationOperation
{
private enum ESteps
{
None,
CheckAppFootPrint,
QueryCachePackageVersion,
TryLoadCacheManifest,
QueryBuildinPackageVersion,
UnpackBuildinManifest,
LoadBuildinManifest,
PackageCaching,
Done,
}
/// <summary>
/// 联机运行模式的初始化操作
/// 注意:优先从沙盒里加载清单,如果沙盒里不存在就尝试把内置清单拷贝到沙盒并加载该清单。
/// </summary>
internal sealed class HostPlayModeInitializationOperation : InitializationOperation
{
private enum ESteps
{
None,
CheckAppFootPrint,
QueryCachePackageVersion,
TryLoadCacheManifest,
QueryBuildinPackageVersion,
UnpackBuildinManifest,
LoadBuildinManifest,
PackageCaching,
Done,
}
private readonly HostPlayModeImpl _impl;
private QueryBuildinPackageVersionOperation _queryBuildinPackageVersionOp;
private QueryCachePackageVersionOperation _queryCachePackageVersionOp;
private UnpackBuildinManifestOperation _unpackBuildinManifestOp;
private LoadBuildinManifestOperation _loadBuildinManifestOp;
private LoadCacheManifestOperation _loadCacheManifestOp;
private PackageCachingOperation _cachingOperation;
private ESteps _steps = ESteps.None;
private readonly HostPlayModeImpl _impl;
private QueryBuildinPackageVersionOperation _queryBuildinPackageVersionOp;
private QueryCachePackageVersionOperation _queryCachePackageVersionOp;
private UnpackBuildinManifestOperation _unpackBuildinManifestOp;
private LoadBuildinManifestOperation _loadBuildinManifestOp;
private LoadCacheManifestOperation _loadCacheManifestOp;
private PackageCachingOperation _cachingOperation;
private ESteps _steps = ESteps.None;
internal HostPlayModeInitializationOperation(HostPlayModeImpl impl)
{
_impl = impl;
}
internal override void InternalOnStart()
{
_steps = ESteps.CheckAppFootPrint;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
internal HostPlayModeInitializationOperation(HostPlayModeImpl impl)
{
_impl = impl;
}
internal override void InternalOnStart()
{
_steps = ESteps.CheckAppFootPrint;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckAppFootPrint)
{
var appFootPrint = new AppFootPrint(_impl.Persistent);
appFootPrint.Load(_impl.PackageName);
if (_steps == ESteps.CheckAppFootPrint)
{
var appFootPrint = new AppFootPrint(_impl.Persistent);
appFootPrint.Load(_impl.PackageName);
// 如果水印发生变化,则说明覆盖安装后首次打开游戏
if (appFootPrint.IsDirty())
{
_impl.Persistent.DeleteSandboxManifestFilesFolder();
appFootPrint.Coverage(_impl.PackageName);
YooLogger.Log("Delete manifest files when application foot print dirty !");
}
_steps = ESteps.QueryCachePackageVersion;
}
// 如果水印发生变化,则说明覆盖安装后首次打开游戏
if (appFootPrint.IsDirty())
{
_impl.Persistent.DeleteSandboxManifestFilesFolder();
appFootPrint.Coverage(_impl.PackageName);
YooLogger.Log("Delete manifest files when application foot print dirty !");
}
_steps = ESteps.QueryCachePackageVersion;
}
if (_steps == ESteps.QueryCachePackageVersion)
{
if (_queryCachePackageVersionOp == null)
{
_queryCachePackageVersionOp = new QueryCachePackageVersionOperation(_impl.Persistent);
OperationSystem.StartOperation(_impl.PackageName, _queryCachePackageVersionOp);
}
if (_steps == ESteps.QueryCachePackageVersion)
{
if (_queryCachePackageVersionOp == null)
{
_queryCachePackageVersionOp = new QueryCachePackageVersionOperation(_impl.Persistent);
OperationSystem.StartOperation(_impl.PackageName, _queryCachePackageVersionOp);
}
if (_queryCachePackageVersionOp.IsDone == false)
return;
if (_queryCachePackageVersionOp.IsDone == false)
return;
if (_queryCachePackageVersionOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.TryLoadCacheManifest;
}
else
{
_steps = ESteps.QueryBuildinPackageVersion;
}
}
if (_queryCachePackageVersionOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.TryLoadCacheManifest;
}
else
{
_steps = ESteps.QueryBuildinPackageVersion;
}
}
if (_steps == ESteps.TryLoadCacheManifest)
{
if (_loadCacheManifestOp == null)
{
_loadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _queryCachePackageVersionOp.PackageVersion);
OperationSystem.StartOperation(_impl.PackageName, _loadCacheManifestOp);
}
if (_steps == ESteps.TryLoadCacheManifest)
{
if (_loadCacheManifestOp == null)
{
_loadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _queryCachePackageVersionOp.PackageVersion);
OperationSystem.StartOperation(_impl.PackageName, _loadCacheManifestOp);
}
if (_loadCacheManifestOp.IsDone == false)
return;
if (_loadCacheManifestOp.IsDone == false)
return;
if (_loadCacheManifestOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _loadCacheManifestOp.Manifest.PackageVersion;
_impl.ActiveManifest = _loadCacheManifestOp.Manifest;
_steps = ESteps.PackageCaching;
}
else
{
_steps = ESteps.QueryBuildinPackageVersion;
}
}
if (_loadCacheManifestOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _loadCacheManifestOp.Manifest.PackageVersion;
_impl.ActiveManifest = _loadCacheManifestOp.Manifest;
_steps = ESteps.PackageCaching;
}
else
{
_steps = ESteps.QueryBuildinPackageVersion;
}
}
if (_steps == ESteps.QueryBuildinPackageVersion)
{
if (_queryBuildinPackageVersionOp == null)
{
_queryBuildinPackageVersionOp = new QueryBuildinPackageVersionOperation(_impl.Persistent);
OperationSystem.StartOperation(_impl.PackageName, _queryBuildinPackageVersionOp);
}
if (_steps == ESteps.QueryBuildinPackageVersion)
{
if (_queryBuildinPackageVersionOp == null)
{
_queryBuildinPackageVersionOp = new QueryBuildinPackageVersionOperation(_impl.Persistent);
OperationSystem.StartOperation(_impl.PackageName, _queryBuildinPackageVersionOp);
}
if (_queryBuildinPackageVersionOp.IsDone == false)
return;
if (_queryBuildinPackageVersionOp.IsDone == false)
return;
if (_queryBuildinPackageVersionOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.UnpackBuildinManifest;
}
else
{
// 注意为了兼容MOD模式初始化动态新增的包裹的时候如果内置清单不存在也不需要报错
_steps = ESteps.PackageCaching;
string error = _queryBuildinPackageVersionOp.Error;
YooLogger.Log($"Failed to load buildin package version file : {error}");
}
}
if (_queryBuildinPackageVersionOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.UnpackBuildinManifest;
}
else
{
// 注意为了兼容MOD模式初始化动态新增的包裹的时候如果内置清单不存在也不需要报错
_steps = ESteps.PackageCaching;
string error = _queryBuildinPackageVersionOp.Error;
YooLogger.Log($"Failed to load buildin package version file : {error}");
}
}
if (_steps == ESteps.UnpackBuildinManifest)
{
if (_unpackBuildinManifestOp == null)
{
_unpackBuildinManifestOp = new UnpackBuildinManifestOperation(_impl.Persistent, _queryBuildinPackageVersionOp.PackageVersion);
OperationSystem.StartOperation(_impl.PackageName, _unpackBuildinManifestOp);
}
if (_steps == ESteps.UnpackBuildinManifest)
{
if (_unpackBuildinManifestOp == null)
{
_unpackBuildinManifestOp = new UnpackBuildinManifestOperation(_impl.Persistent, _queryBuildinPackageVersionOp.PackageVersion);
OperationSystem.StartOperation(_impl.PackageName, _unpackBuildinManifestOp);
}
if (_unpackBuildinManifestOp.IsDone == false)
return;
if (_unpackBuildinManifestOp.IsDone == false)
return;
if (_unpackBuildinManifestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadBuildinManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _unpackBuildinManifestOp.Error;
}
}
if (_unpackBuildinManifestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadBuildinManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _unpackBuildinManifestOp.Error;
}
}
if (_steps == ESteps.LoadBuildinManifest)
{
if (_loadBuildinManifestOp == null)
{
_loadBuildinManifestOp = new LoadBuildinManifestOperation(_impl.Persistent, _queryBuildinPackageVersionOp.PackageVersion);
OperationSystem.StartOperation(_impl.PackageName, _loadBuildinManifestOp);
}
if (_steps == ESteps.LoadBuildinManifest)
{
if (_loadBuildinManifestOp == null)
{
_loadBuildinManifestOp = new LoadBuildinManifestOperation(_impl.Persistent, _queryBuildinPackageVersionOp.PackageVersion);
OperationSystem.StartOperation(_impl.PackageName, _loadBuildinManifestOp);
}
Progress = _loadBuildinManifestOp.Progress;
if (_loadBuildinManifestOp.IsDone == false)
return;
Progress = _loadBuildinManifestOp.Progress;
if (_loadBuildinManifestOp.IsDone == false)
return;
if (_loadBuildinManifestOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _loadBuildinManifestOp.Manifest.PackageVersion;
_impl.ActiveManifest = _loadBuildinManifestOp.Manifest;
_steps = ESteps.PackageCaching;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadBuildinManifestOp.Error;
}
}
if (_loadBuildinManifestOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _loadBuildinManifestOp.Manifest.PackageVersion;
_impl.ActiveManifest = _loadBuildinManifestOp.Manifest;
_steps = ESteps.PackageCaching;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadBuildinManifestOp.Error;
}
}
if (_steps == ESteps.PackageCaching)
{
if (_cachingOperation == null)
{
_cachingOperation = new PackageCachingOperation(_impl.Persistent, _impl.Cache);
OperationSystem.StartOperation(_impl.PackageName,_cachingOperation);
}
if (_steps == ESteps.PackageCaching)
{
if (_cachingOperation == null)
{
_cachingOperation = new PackageCachingOperation(_impl.Persistent, _impl.Cache);
OperationSystem.StartOperation(_impl.PackageName, _cachingOperation);
}
Progress = _cachingOperation.Progress;
if (_cachingOperation.IsDone)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
Progress = _cachingOperation.Progress;
if (_cachingOperation.IsDone)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
/// <summary>
/// WebGL运行模式的初始化操作
/// </summary>
internal sealed class WebPlayModeInitializationOperation : InitializationOperation
{
private enum ESteps
{
None,
QueryWebPackageVersion,
LoadWebManifest,
Done,
}
/// <summary>
/// WebGL运行模式的初始化操作
/// </summary>
internal sealed class WebPlayModeInitializationOperation : InitializationOperation
{
private enum ESteps
{
None,
QueryWebPackageVersion,
LoadWebManifest,
Done,
}
private readonly WebPlayModeImpl _impl;
private QueryBuildinPackageVersionOperation _queryWebPackageVersionOp;
private LoadBuildinManifestOperation _loadWebManifestOp;
private ESteps _steps = ESteps.None;
private readonly WebPlayModeImpl _impl;
private QueryBuildinPackageVersionOperation _queryWebPackageVersionOp;
private LoadBuildinManifestOperation _loadWebManifestOp;
private ESteps _steps = ESteps.None;
internal WebPlayModeInitializationOperation(WebPlayModeImpl impl)
{
_impl = impl;
}
internal override void InternalOnStart()
{
_steps = ESteps.QueryWebPackageVersion;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
internal WebPlayModeInitializationOperation(WebPlayModeImpl impl)
{
_impl = impl;
}
internal override void InternalOnStart()
{
_steps = ESteps.QueryWebPackageVersion;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.QueryWebPackageVersion)
{
if (_queryWebPackageVersionOp == null)
{
_queryWebPackageVersionOp = new QueryBuildinPackageVersionOperation(_impl.Persistent);
OperationSystem.StartOperation(_impl.PackageName, _queryWebPackageVersionOp);
}
if (_steps == ESteps.QueryWebPackageVersion)
{
if (_queryWebPackageVersionOp == null)
{
_queryWebPackageVersionOp = new QueryBuildinPackageVersionOperation(_impl.Persistent);
OperationSystem.StartOperation(_impl.PackageName, _queryWebPackageVersionOp);
}
if (_queryWebPackageVersionOp.IsDone == false)
return;
if (_queryWebPackageVersionOp.IsDone == false)
return;
if (_queryWebPackageVersionOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadWebManifest;
}
else
{
// 注意WebGL平台可能因为网络的原因会导致请求失败。如果内置清单不存在或者超时也不需要报错
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
string error = _queryWebPackageVersionOp.Error;
YooLogger.Log($"Failed to load web package version file : {error}");
}
}
if (_queryWebPackageVersionOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadWebManifest;
}
else
{
// 注意WebGL平台可能因为网络的原因会导致请求失败。如果内置清单不存在或者超时也不需要报错
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
string error = _queryWebPackageVersionOp.Error;
YooLogger.Log($"Failed to load web package version file : {error}");
}
}
if (_steps == ESteps.LoadWebManifest)
{
if (_loadWebManifestOp == null)
{
_loadWebManifestOp = new LoadBuildinManifestOperation(_impl.Persistent, _queryWebPackageVersionOp.PackageVersion);
OperationSystem.StartOperation(_impl.PackageName, _loadWebManifestOp);
}
if (_steps == ESteps.LoadWebManifest)
{
if (_loadWebManifestOp == null)
{
_loadWebManifestOp = new LoadBuildinManifestOperation(_impl.Persistent, _queryWebPackageVersionOp.PackageVersion);
OperationSystem.StartOperation(_impl.PackageName, _loadWebManifestOp);
}
Progress = _loadWebManifestOp.Progress;
if (_loadWebManifestOp.IsDone == false)
return;
Progress = _loadWebManifestOp.Progress;
if (_loadWebManifestOp.IsDone == false)
return;
if (_loadWebManifestOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _loadWebManifestOp.Manifest.PackageVersion;
_impl.ActiveManifest = _loadWebManifestOp.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadWebManifestOp.Error;
}
}
}
}
if (_loadWebManifestOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _loadWebManifestOp.Manifest.PackageVersion;
_impl.ActiveManifest = _loadWebManifestOp.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadWebManifestOp.Error;
}
}
}
}
/// <summary>
/// 应用程序水印
/// </summary>
internal class AppFootPrint
{
private PersistentManager _persistent;
private string _footPrint;
/// <summary>
/// 应用程序水印
/// </summary>
internal class AppFootPrint
{
private PersistentManager _persistent;
private string _footPrint;
public AppFootPrint(PersistentManager persistent)
{
_persistent = persistent;
}
public AppFootPrint(PersistentManager persistent)
{
_persistent = persistent;
}
/// <summary>
/// 读取应用程序水印
/// </summary>
public void Load(string packageName)
{
string footPrintFilePath = _persistent.SandboxAppFootPrintFilePath;
if (File.Exists(footPrintFilePath))
{
_footPrint = FileUtility.ReadAllText(footPrintFilePath);
}
else
{
Coverage(packageName);
}
}
/// <summary>
/// 读取应用程序水印
/// </summary>
public void Load(string packageName)
{
string footPrintFilePath = _persistent.SandboxAppFootPrintFilePath;
if (File.Exists(footPrintFilePath))
{
_footPrint = FileUtility.ReadAllText(footPrintFilePath);
}
else
{
Coverage(packageName);
}
}
/// <summary>
/// 检测水印是否发生变化
/// </summary>
public bool IsDirty()
{
/// <summary>
/// 检测水印是否发生变化
/// </summary>
public bool IsDirty()
{
#if UNITY_EDITOR
return _footPrint != Application.version;
return _footPrint != Application.version;
#else
return _footPrint != Application.buildGUID;
#endif
}
}
/// <summary>
/// 覆盖掉水印
/// </summary>
public void Coverage(string packageName)
{
/// <summary>
/// 覆盖掉水印
/// </summary>
public void Coverage(string packageName)
{
#if UNITY_EDITOR
_footPrint = Application.version;
_footPrint = Application.version;
#else
_footPrint = Application.buildGUID;
#endif
string footPrintFilePath = _persistent.SandboxAppFootPrintFilePath;
FileUtility.WriteAllText(footPrintFilePath, _footPrint);
YooLogger.Log($"Save application foot print : {_footPrint}");
}
}
string footPrintFilePath = _persistent.SandboxAppFootPrintFilePath;
FileUtility.WriteAllText(footPrintFilePath, _footPrint);
YooLogger.Log($"Save application foot print : {_footPrint}");
}
}
}

View File

@ -4,237 +4,237 @@ using System.Collections.Generic;
namespace YooAsset
{
internal class DeserializeManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
DeserializeFileHeader,
PrepareAssetList,
DeserializeAssetList,
PrepareBundleList,
DeserializeBundleList,
Done,
}
internal class DeserializeManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
DeserializeFileHeader,
PrepareAssetList,
DeserializeAssetList,
PrepareBundleList,
DeserializeBundleList,
Done,
}
private readonly BufferReader _buffer;
private int _packageAssetCount;
private int _packageBundleCount;
private int _progressTotalValue;
private ESteps _steps = ESteps.None;
private readonly BufferReader _buffer;
private int _packageAssetCount;
private int _packageBundleCount;
private int _progressTotalValue;
private ESteps _steps = ESteps.None;
/// <summary>
/// 解析的清单实例
/// </summary>
public PackageManifest Manifest { private set; get; }
/// <summary>
/// 解析的清单实例
/// </summary>
public PackageManifest Manifest { private set; get; }
public DeserializeManifestOperation(byte[] binaryData)
{
_buffer = new BufferReader(binaryData);
}
internal override void InternalOnStart()
{
_steps = ESteps.DeserializeFileHeader;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public DeserializeManifestOperation(byte[] binaryData)
{
_buffer = new BufferReader(binaryData);
}
internal override void InternalOnStart()
{
_steps = ESteps.DeserializeFileHeader;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
try
{
if (_steps == ESteps.DeserializeFileHeader)
{
if (_buffer.IsValid == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Buffer is invalid !";
return;
}
try
{
if (_steps == ESteps.DeserializeFileHeader)
{
if (_buffer.IsValid == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Buffer is invalid !";
return;
}
// 读取文件标记
uint fileSign = _buffer.ReadUInt32();
if (fileSign != YooAssetSettings.ManifestFileSign)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "The manifest file format is invalid !";
return;
}
// 读取文件标记
uint fileSign = _buffer.ReadUInt32();
if (fileSign != YooAssetSettings.ManifestFileSign)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "The manifest file format is invalid !";
return;
}
// 读取文件版本
string fileVersion = _buffer.ReadUTF8();
if (fileVersion != YooAssetSettings.ManifestFileVersion)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"The manifest file version are not compatible : {fileVersion} != {YooAssetSettings.ManifestFileVersion}";
return;
}
// 读取文件版本
string fileVersion = _buffer.ReadUTF8();
if (fileVersion != YooAssetSettings.ManifestFileVersion)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"The manifest file version are not compatible : {fileVersion} != {YooAssetSettings.ManifestFileVersion}";
return;
}
// 读取文件头信息
Manifest = new PackageManifest();
Manifest.FileVersion = fileVersion;
Manifest.EnableAddressable = _buffer.ReadBool();
Manifest.LocationToLower = _buffer.ReadBool();
Manifest.IncludeAssetGUID = _buffer.ReadBool();
Manifest.OutputNameStyle = _buffer.ReadInt32();
Manifest.BuildPipeline = _buffer.ReadUTF8();
Manifest.PackageName = _buffer.ReadUTF8();
Manifest.PackageVersion = _buffer.ReadUTF8();
// 读取文件头信息
Manifest = new PackageManifest();
Manifest.FileVersion = fileVersion;
Manifest.EnableAddressable = _buffer.ReadBool();
Manifest.LocationToLower = _buffer.ReadBool();
Manifest.IncludeAssetGUID = _buffer.ReadBool();
Manifest.OutputNameStyle = _buffer.ReadInt32();
Manifest.BuildPipeline = _buffer.ReadUTF8();
Manifest.PackageName = _buffer.ReadUTF8();
Manifest.PackageVersion = _buffer.ReadUTF8();
// 检测配置
if (Manifest.EnableAddressable && Manifest.LocationToLower)
throw new System.Exception("Addressable not support location to lower !");
// 检测配置
if (Manifest.EnableAddressable && Manifest.LocationToLower)
throw new System.Exception("Addressable not support location to lower !");
_steps = ESteps.PrepareAssetList;
}
_steps = ESteps.PrepareAssetList;
}
if (_steps == ESteps.PrepareAssetList)
{
_packageAssetCount = _buffer.ReadInt32();
Manifest.AssetList = new List<PackageAsset>(_packageAssetCount);
Manifest.AssetDic = new Dictionary<string, PackageAsset>(_packageAssetCount);
if (_steps == ESteps.PrepareAssetList)
{
_packageAssetCount = _buffer.ReadInt32();
Manifest.AssetList = new List<PackageAsset>(_packageAssetCount);
Manifest.AssetDic = new Dictionary<string, PackageAsset>(_packageAssetCount);
if (Manifest.EnableAddressable)
Manifest.AssetPathMapping1 = new Dictionary<string, string>(_packageAssetCount * 3);
else
Manifest.AssetPathMapping1 = new Dictionary<string, string>(_packageAssetCount * 2);
if (Manifest.EnableAddressable)
Manifest.AssetPathMapping1 = new Dictionary<string, string>(_packageAssetCount * 3);
else
Manifest.AssetPathMapping1 = new Dictionary<string, string>(_packageAssetCount * 2);
if (Manifest.IncludeAssetGUID)
Manifest.AssetPathMapping2 = new Dictionary<string, string>(_packageAssetCount);
else
Manifest.AssetPathMapping2 = new Dictionary<string, string>();
if (Manifest.IncludeAssetGUID)
Manifest.AssetPathMapping2 = new Dictionary<string, string>(_packageAssetCount);
else
Manifest.AssetPathMapping2 = new Dictionary<string, string>();
_progressTotalValue = _packageAssetCount;
_steps = ESteps.DeserializeAssetList;
}
if (_steps == ESteps.DeserializeAssetList)
{
while (_packageAssetCount > 0)
{
var packageAsset = new PackageAsset();
packageAsset.Address = _buffer.ReadUTF8();
packageAsset.AssetPath = _buffer.ReadUTF8();
packageAsset.AssetGUID = _buffer.ReadUTF8();
packageAsset.AssetTags = _buffer.ReadUTF8Array();
packageAsset.BundleID = _buffer.ReadInt32();
Manifest.AssetList.Add(packageAsset);
_progressTotalValue = _packageAssetCount;
_steps = ESteps.DeserializeAssetList;
}
if (_steps == ESteps.DeserializeAssetList)
{
while (_packageAssetCount > 0)
{
var packageAsset = new PackageAsset();
packageAsset.Address = _buffer.ReadUTF8();
packageAsset.AssetPath = _buffer.ReadUTF8();
packageAsset.AssetGUID = _buffer.ReadUTF8();
packageAsset.AssetTags = _buffer.ReadUTF8Array();
packageAsset.BundleID = _buffer.ReadInt32();
Manifest.AssetList.Add(packageAsset);
// 注意:我们不允许原始路径存在重名
string assetPath = packageAsset.AssetPath;
if (Manifest.AssetDic.ContainsKey(assetPath))
throw new System.Exception($"AssetPath have existed : {assetPath}");
else
Manifest.AssetDic.Add(assetPath, packageAsset);
// 注意:我们不允许原始路径存在重名
string assetPath = packageAsset.AssetPath;
if (Manifest.AssetDic.ContainsKey(assetPath))
throw new System.Exception($"AssetPath have existed : {assetPath}");
else
Manifest.AssetDic.Add(assetPath, packageAsset);
// 填充AssetPathMapping1
{
string location = packageAsset.AssetPath;
if (Manifest.LocationToLower)
location = location.ToLower();
// 填充AssetPathMapping1
{
string location = packageAsset.AssetPath;
if (Manifest.LocationToLower)
location = location.ToLower();
// 添加原生路径的映射
if (Manifest.AssetPathMapping1.ContainsKey(location))
throw new System.Exception($"Location have existed : {location}");
else
Manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
// 添加原生路径的映射
if (Manifest.AssetPathMapping1.ContainsKey(location))
throw new System.Exception($"Location have existed : {location}");
else
Manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
// 添加无后缀名路径的映射
if (Path.HasExtension(location))
{
string locationWithoutExtension = PathUtility.RemoveExtension(location);
if (Manifest.AssetPathMapping1.ContainsKey(locationWithoutExtension))
YooLogger.Warning($"Location have existed : {locationWithoutExtension}");
else
Manifest.AssetPathMapping1.Add(locationWithoutExtension, packageAsset.AssetPath);
}
}
if (Manifest.EnableAddressable)
{
string location = packageAsset.Address;
if (string.IsNullOrEmpty(location) == false)
{
if (Manifest.AssetPathMapping1.ContainsKey(location))
throw new System.Exception($"Location have existed : {location}");
else
Manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
}
}
// 添加无后缀名路径的映射
if (Path.HasExtension(location))
{
string locationWithoutExtension = PathUtility.RemoveExtension(location);
if (Manifest.AssetPathMapping1.ContainsKey(locationWithoutExtension))
YooLogger.Warning($"Location have existed : {locationWithoutExtension}");
else
Manifest.AssetPathMapping1.Add(locationWithoutExtension, packageAsset.AssetPath);
}
}
if (Manifest.EnableAddressable)
{
string location = packageAsset.Address;
if (string.IsNullOrEmpty(location) == false)
{
if (Manifest.AssetPathMapping1.ContainsKey(location))
throw new System.Exception($"Location have existed : {location}");
else
Manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
}
}
// 填充AssetPathMapping2
if (Manifest.IncludeAssetGUID)
{
if (Manifest.AssetPathMapping2.ContainsKey(packageAsset.AssetGUID))
throw new System.Exception($"AssetGUID have existed : {packageAsset.AssetGUID}");
else
Manifest.AssetPathMapping2.Add(packageAsset.AssetGUID, packageAsset.AssetPath);
}
// 填充AssetPathMapping2
if (Manifest.IncludeAssetGUID)
{
if (Manifest.AssetPathMapping2.ContainsKey(packageAsset.AssetGUID))
throw new System.Exception($"AssetGUID have existed : {packageAsset.AssetGUID}");
else
Manifest.AssetPathMapping2.Add(packageAsset.AssetGUID, packageAsset.AssetPath);
}
_packageAssetCount--;
Progress = 1f - _packageAssetCount / _progressTotalValue;
if (OperationSystem.IsBusy)
break;
}
_packageAssetCount--;
Progress = 1f - _packageAssetCount / _progressTotalValue;
if (OperationSystem.IsBusy)
break;
}
if (_packageAssetCount <= 0)
{
_steps = ESteps.PrepareBundleList;
}
}
if (_packageAssetCount <= 0)
{
_steps = ESteps.PrepareBundleList;
}
}
if (_steps == ESteps.PrepareBundleList)
{
_packageBundleCount = _buffer.ReadInt32();
Manifest.BundleList = new List<PackageBundle>(_packageBundleCount);
Manifest.BundleDic1 = new Dictionary<string, PackageBundle>(_packageBundleCount);
Manifest.BundleDic2 = new Dictionary<string, PackageBundle>(_packageBundleCount);
_progressTotalValue = _packageBundleCount;
_steps = ESteps.DeserializeBundleList;
}
if (_steps == ESteps.DeserializeBundleList)
{
while (_packageBundleCount > 0)
{
var packageBundle = new PackageBundle();
packageBundle.BundleName = _buffer.ReadUTF8();
packageBundle.UnityCRC = _buffer.ReadUInt32();
packageBundle.FileHash = _buffer.ReadUTF8();
packageBundle.FileCRC = _buffer.ReadUTF8();
packageBundle.FileSize = _buffer.ReadInt64();
packageBundle.Encrypted = _buffer.ReadBool();
packageBundle.Tags = _buffer.ReadUTF8Array();
packageBundle.DependIDs = _buffer.ReadInt32Array();
packageBundle.ParseBundle(Manifest);
Manifest.BundleList.Add(packageBundle);
Manifest.BundleDic1.Add(packageBundle.BundleName, packageBundle);
Manifest.BundleDic2.Add(packageBundle.FileName, packageBundle);
if (_steps == ESteps.PrepareBundleList)
{
_packageBundleCount = _buffer.ReadInt32();
Manifest.BundleList = new List<PackageBundle>(_packageBundleCount);
Manifest.BundleDic1 = new Dictionary<string, PackageBundle>(_packageBundleCount);
Manifest.BundleDic2 = new Dictionary<string, PackageBundle>(_packageBundleCount);
_progressTotalValue = _packageBundleCount;
_steps = ESteps.DeserializeBundleList;
}
if (_steps == ESteps.DeserializeBundleList)
{
while (_packageBundleCount > 0)
{
var packageBundle = new PackageBundle();
packageBundle.BundleName = _buffer.ReadUTF8();
packageBundle.UnityCRC = _buffer.ReadUInt32();
packageBundle.FileHash = _buffer.ReadUTF8();
packageBundle.FileCRC = _buffer.ReadUTF8();
packageBundle.FileSize = _buffer.ReadInt64();
packageBundle.Encrypted = _buffer.ReadBool();
packageBundle.Tags = _buffer.ReadUTF8Array();
packageBundle.DependIDs = _buffer.ReadInt32Array();
packageBundle.ParseBundle(Manifest);
Manifest.BundleList.Add(packageBundle);
Manifest.BundleDic1.Add(packageBundle.BundleName, packageBundle);
Manifest.BundleDic2.Add(packageBundle.FileName, packageBundle);
// 注意原始文件可能存在相同的CacheGUID
if (Manifest.CacheGUIDs.Contains(packageBundle.CacheGUID) == false)
Manifest.CacheGUIDs.Add(packageBundle.CacheGUID);
// 注意原始文件可能存在相同的CacheGUID
if (Manifest.CacheGUIDs.Contains(packageBundle.CacheGUID) == false)
Manifest.CacheGUIDs.Add(packageBundle.CacheGUID);
_packageBundleCount--;
Progress = 1f - _packageBundleCount / _progressTotalValue;
if (OperationSystem.IsBusy)
break;
}
_packageBundleCount--;
Progress = 1f - _packageBundleCount / _progressTotalValue;
if (OperationSystem.IsBusy)
break;
}
if (_packageBundleCount <= 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
catch (System.Exception e)
{
Manifest = null;
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = e.Message;
}
}
}
if (_packageBundleCount <= 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
catch (System.Exception e)
{
Manifest = null;
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = e.Message;
}
}
}
}

View File

@ -1,113 +1,113 @@

namespace YooAsset
{
internal class DownloadManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
DownloadPackageHashFile,
DownloadManifestFile,
Done,
}
internal class DownloadManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
DownloadPackageHashFile,
DownloadManifestFile,
Done,
}
private readonly PersistentManager _persistent;
private readonly IRemoteServices _remoteServices;
private readonly string _packageVersion;
private readonly int _timeout;
private UnityWebFileRequester _downloader1;
private UnityWebFileRequester _downloader2;
private ESteps _steps = ESteps.None;
private int _requestCount = 0;
private readonly PersistentManager _persistent;
private readonly IRemoteServices _remoteServices;
private readonly string _packageVersion;
private readonly int _timeout;
private UnityWebFileRequester _downloader1;
private UnityWebFileRequester _downloader2;
private ESteps _steps = ESteps.None;
private int _requestCount = 0;
internal DownloadManifestOperation(PersistentManager persistent, IRemoteServices remoteServices, string packageVersion, int timeout)
{
_persistent = persistent;
_remoteServices = remoteServices;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_requestCount = RequestHelper.GetRequestFailedCount(_persistent.PackageName, nameof(DownloadManifestOperation));
_steps = ESteps.DownloadPackageHashFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
internal DownloadManifestOperation(PersistentManager persistent, IRemoteServices remoteServices, string packageVersion, int timeout)
{
_persistent = persistent;
_remoteServices = remoteServices;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_requestCount = RequestHelper.GetRequestFailedCount(_persistent.PackageName, nameof(DownloadManifestOperation));
_steps = ESteps.DownloadPackageHashFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.DownloadPackageHashFile)
{
if (_downloader1 == null)
{
string savePath = _persistent.GetSandboxPackageHashFilePath(_packageVersion);
string fileName = YooAssetSettingsData.GetPackageHashFileName(_persistent.PackageName, _packageVersion);
string webURL = GetDownloadRequestURL(fileName);
YooLogger.Log($"Beginning to download package hash file : {webURL}");
_downloader1 = new UnityWebFileRequester();
_downloader1.SendRequest(webURL, savePath, _timeout);
}
if (_steps == ESteps.DownloadPackageHashFile)
{
if (_downloader1 == null)
{
string savePath = _persistent.GetSandboxPackageHashFilePath(_packageVersion);
string fileName = YooAssetSettingsData.GetPackageHashFileName(_persistent.PackageName, _packageVersion);
string webURL = GetDownloadRequestURL(fileName);
YooLogger.Log($"Beginning to download package hash file : {webURL}");
_downloader1 = new UnityWebFileRequester();
_downloader1.SendRequest(webURL, savePath, _timeout);
}
_downloader1.CheckTimeout();
if (_downloader1.IsDone() == false)
return;
_downloader1.CheckTimeout();
if (_downloader1.IsDone() == false)
return;
if (_downloader1.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader1.GetError();
RequestHelper.RecordRequestFailed(_persistent.PackageName, nameof(DownloadManifestOperation));
}
else
{
_steps = ESteps.DownloadManifestFile;
}
if (_downloader1.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader1.GetError();
RequestHelper.RecordRequestFailed(_persistent.PackageName, nameof(DownloadManifestOperation));
}
else
{
_steps = ESteps.DownloadManifestFile;
}
_downloader1.Dispose();
}
_downloader1.Dispose();
}
if (_steps == ESteps.DownloadManifestFile)
{
if (_downloader2 == null)
{
string savePath = _persistent.GetSandboxPackageManifestFilePath(_packageVersion);
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_persistent.PackageName, _packageVersion);
string webURL = GetDownloadRequestURL(fileName);
YooLogger.Log($"Beginning to download package manifest file : {webURL}");
_downloader2 = new UnityWebFileRequester();
_downloader2.SendRequest(webURL, savePath, _timeout);
}
if (_steps == ESteps.DownloadManifestFile)
{
if (_downloader2 == null)
{
string savePath = _persistent.GetSandboxPackageManifestFilePath(_packageVersion);
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_persistent.PackageName, _packageVersion);
string webURL = GetDownloadRequestURL(fileName);
YooLogger.Log($"Beginning to download package manifest file : {webURL}");
_downloader2 = new UnityWebFileRequester();
_downloader2.SendRequest(webURL, savePath, _timeout);
}
_downloader2.CheckTimeout();
if (_downloader2.IsDone() == false)
return;
_downloader2.CheckTimeout();
if (_downloader2.IsDone() == false)
return;
if (_downloader2.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader2.GetError();
RequestHelper.RecordRequestFailed(_persistent.PackageName, nameof(DownloadManifestOperation));
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
if (_downloader2.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader2.GetError();
RequestHelper.RecordRequestFailed(_persistent.PackageName, nameof(DownloadManifestOperation));
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
_downloader2.Dispose();
}
}
_downloader2.Dispose();
}
}
private string GetDownloadRequestURL(string fileName)
{
// 轮流返回请求地址
if (_requestCount % 2 == 0)
return _remoteServices.GetRemoteMainURL(fileName);
else
return _remoteServices.GetRemoteFallbackURL(fileName);
}
}
private string GetDownloadRequestURL(string fileName)
{
// 轮流返回请求地址
if (_requestCount % 2 == 0)
return _remoteServices.GetRemoteMainURL(fileName);
else
return _remoteServices.GetRemoteFallbackURL(fileName);
}
}
}

View File

@ -1,91 +1,91 @@

namespace YooAsset
{
internal class LoadBuildinManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
LoadBuildinManifest,
CheckDeserializeManifest,
Done,
}
internal class LoadBuildinManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
LoadBuildinManifest,
CheckDeserializeManifest,
Done,
}
private readonly PersistentManager _persistent;
private readonly string _buildinPackageVersion;
private UnityWebDataRequester _downloader;
private DeserializeManifestOperation _deserializer;
private ESteps _steps = ESteps.None;
private readonly PersistentManager _persistent;
private readonly string _buildinPackageVersion;
private UnityWebDataRequester _downloader;
private DeserializeManifestOperation _deserializer;
private ESteps _steps = ESteps.None;
/// <summary>
/// 加载的清单实例
/// </summary>
public PackageManifest Manifest { private set; get; }
/// <summary>
/// 加载的清单实例
/// </summary>
public PackageManifest Manifest { private set; get; }
public LoadBuildinManifestOperation(PersistentManager persistent, string buildinPackageVersion)
{
_persistent = persistent;
_buildinPackageVersion = buildinPackageVersion;
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadBuildinManifest;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public LoadBuildinManifestOperation(PersistentManager persistent, string buildinPackageVersion)
{
_persistent = persistent;
_buildinPackageVersion = buildinPackageVersion;
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadBuildinManifest;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadBuildinManifest)
{
if (_downloader == null)
{
string filePath = _persistent.GetBuildinPackageManifestFilePath(_buildinPackageVersion);
string url = PersistentHelper.ConvertToWWWPath(filePath);
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(url);
}
if (_steps == ESteps.LoadBuildinManifest)
{
if (_downloader == null)
{
string filePath = _persistent.GetBuildinPackageManifestFilePath(_buildinPackageVersion);
string url = PersistentHelper.ConvertToWWWPath(filePath);
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(url);
}
if (_downloader.IsDone() == false)
return;
if (_downloader.IsDone() == false)
return;
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader.GetError();
}
else
{
byte[] bytesData = _downloader.GetData();
_deserializer = new DeserializeManifestOperation(bytesData);
OperationSystem.StartOperation(_persistent.PackageName, _deserializer);
_steps = ESteps.CheckDeserializeManifest;
}
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader.GetError();
}
else
{
byte[] bytesData = _downloader.GetData();
_deserializer = new DeserializeManifestOperation(bytesData);
OperationSystem.StartOperation(_persistent.PackageName, _deserializer);
_steps = ESteps.CheckDeserializeManifest;
}
_downloader.Dispose();
}
_downloader.Dispose();
}
if (_steps == ESteps.CheckDeserializeManifest)
{
Progress = _deserializer.Progress;
if (_deserializer.IsDone == false)
return;
if (_steps == ESteps.CheckDeserializeManifest)
{
Progress = _deserializer.Progress;
if (_deserializer.IsDone == false)
return;
if (_deserializer.Status == EOperationStatus.Succeed)
{
Manifest = _deserializer.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _deserializer.Error;
}
}
}
}
if (_deserializer.Status == EOperationStatus.Succeed)
{
Manifest = _deserializer.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _deserializer.Error;
}
}
}
}
}

View File

@ -2,140 +2,140 @@
namespace YooAsset
{
internal class LoadCacheManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
QueryCachePackageHash,
VerifyFileHash,
LoadCacheManifest,
CheckDeserializeManifest,
Done,
}
internal class LoadCacheManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
QueryCachePackageHash,
VerifyFileHash,
LoadCacheManifest,
CheckDeserializeManifest,
Done,
}
private readonly PersistentManager _persistent;
private readonly string _packageVersion;
private QueryCachePackageHashOperation _queryCachePackageHashOp;
private DeserializeManifestOperation _deserializer;
private string _manifestFilePath;
private ESteps _steps = ESteps.None;
private readonly PersistentManager _persistent;
private readonly string _packageVersion;
private QueryCachePackageHashOperation _queryCachePackageHashOp;
private DeserializeManifestOperation _deserializer;
private string _manifestFilePath;
private ESteps _steps = ESteps.None;
/// <summary>
/// 加载的清单实例
/// </summary>
public PackageManifest Manifest { private set; get; }
/// <summary>
/// 加载的清单实例
/// </summary>
public PackageManifest Manifest { private set; get; }
public LoadCacheManifestOperation(PersistentManager persistent, string packageVersion)
{
_persistent = persistent;
_packageVersion = packageVersion;
}
internal override void InternalOnStart()
{
_steps = ESteps.QueryCachePackageHash;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public LoadCacheManifestOperation(PersistentManager persistent, string packageVersion)
{
_persistent = persistent;
_packageVersion = packageVersion;
}
internal override void InternalOnStart()
{
_steps = ESteps.QueryCachePackageHash;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.QueryCachePackageHash)
{
if (_queryCachePackageHashOp == null)
{
_queryCachePackageHashOp = new QueryCachePackageHashOperation(_persistent, _packageVersion);
OperationSystem.StartOperation(_persistent.PackageName, _queryCachePackageHashOp);
}
if (_steps == ESteps.QueryCachePackageHash)
{
if (_queryCachePackageHashOp == null)
{
_queryCachePackageHashOp = new QueryCachePackageHashOperation(_persistent, _packageVersion);
OperationSystem.StartOperation(_persistent.PackageName, _queryCachePackageHashOp);
}
if (_queryCachePackageHashOp.IsDone == false)
return;
if (_queryCachePackageHashOp.IsDone == false)
return;
if (_queryCachePackageHashOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.VerifyFileHash;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _queryCachePackageHashOp.Error;
ClearCacheFile();
}
}
if (_queryCachePackageHashOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.VerifyFileHash;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _queryCachePackageHashOp.Error;
ClearCacheFile();
}
}
if (_steps == ESteps.VerifyFileHash)
{
_manifestFilePath = _persistent.GetSandboxPackageManifestFilePath(_packageVersion);
if (File.Exists(_manifestFilePath) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Not found cache manifest file : {_manifestFilePath}";
ClearCacheFile();
return;
}
if (_steps == ESteps.VerifyFileHash)
{
_manifestFilePath = _persistent.GetSandboxPackageManifestFilePath(_packageVersion);
if (File.Exists(_manifestFilePath) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Not found cache manifest file : {_manifestFilePath}";
ClearCacheFile();
return;
}
string fileHash = HashUtility.FileMD5(_manifestFilePath);
if (fileHash != _queryCachePackageHashOp.PackageHash)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Failed to verify cache manifest file hash !";
ClearCacheFile();
}
else
{
_steps = ESteps.LoadCacheManifest;
}
}
string fileHash = HashUtility.FileMD5(_manifestFilePath);
if (fileHash != _queryCachePackageHashOp.PackageHash)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Failed to verify cache manifest file hash !";
ClearCacheFile();
}
else
{
_steps = ESteps.LoadCacheManifest;
}
}
if (_steps == ESteps.LoadCacheManifest)
{
byte[] bytesData = File.ReadAllBytes(_manifestFilePath);
_deserializer = new DeserializeManifestOperation(bytesData);
OperationSystem.StartOperation(_persistent.PackageName, _deserializer);
_steps = ESteps.CheckDeserializeManifest;
}
if (_steps == ESteps.LoadCacheManifest)
{
byte[] bytesData = File.ReadAllBytes(_manifestFilePath);
_deserializer = new DeserializeManifestOperation(bytesData);
OperationSystem.StartOperation(_persistent.PackageName, _deserializer);
_steps = ESteps.CheckDeserializeManifest;
}
if (_steps == ESteps.CheckDeserializeManifest)
{
Progress = _deserializer.Progress;
if (_deserializer.IsDone == false)
return;
if (_steps == ESteps.CheckDeserializeManifest)
{
Progress = _deserializer.Progress;
if (_deserializer.IsDone == false)
return;
if (_deserializer.Status == EOperationStatus.Succeed)
{
Manifest = _deserializer.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _deserializer.Error;
ClearCacheFile();
}
}
}
if (_deserializer.Status == EOperationStatus.Succeed)
{
Manifest = _deserializer.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _deserializer.Error;
ClearCacheFile();
}
}
}
private void ClearCacheFile()
{
// 注意:如果加载沙盒内的清单报错,为了避免流程被卡住,主动把损坏的文件删除。
if (File.Exists(_manifestFilePath))
{
YooLogger.Warning($"Failed to load cache manifest file : {Error}");
YooLogger.Warning($"Invalid cache manifest file have been removed : {_manifestFilePath}");
File.Delete(_manifestFilePath);
}
private void ClearCacheFile()
{
// 注意:如果加载沙盒内的清单报错,为了避免流程被卡住,主动把损坏的文件删除。
if (File.Exists(_manifestFilePath))
{
YooLogger.Warning($"Failed to load cache manifest file : {Error}");
YooLogger.Warning($"Invalid cache manifest file have been removed : {_manifestFilePath}");
File.Delete(_manifestFilePath);
}
string hashFilePath = _persistent.GetSandboxPackageHashFilePath(_packageVersion);
if (File.Exists(hashFilePath))
{
File.Delete(hashFilePath);
}
}
}
string hashFilePath = _persistent.GetSandboxPackageHashFilePath(_packageVersion);
if (File.Exists(hashFilePath))
{
File.Delete(hashFilePath);
}
}
}
}

View File

@ -2,77 +2,77 @@
namespace YooAsset
{
internal class LoadEditorManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
LoadEditorManifest,
CheckDeserializeManifest,
Done,
}
internal class LoadEditorManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
LoadEditorManifest,
CheckDeserializeManifest,
Done,
}
private readonly string _packageName;
private readonly string _manifestFilePath;
private DeserializeManifestOperation _deserializer;
private ESteps _steps = ESteps.None;
private readonly string _packageName;
private readonly string _manifestFilePath;
private DeserializeManifestOperation _deserializer;
private ESteps _steps = ESteps.None;
/// <summary>
/// 加载的清单实例
/// </summary>
public PackageManifest Manifest { private set; get; }
/// <summary>
/// 加载的清单实例
/// </summary>
public PackageManifest Manifest { private set; get; }
public LoadEditorManifestOperation(string packageName, string manifestFilePath)
{
_packageName = packageName;
_manifestFilePath = manifestFilePath;
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadEditorManifest;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public LoadEditorManifestOperation(string packageName, string manifestFilePath)
{
_packageName = packageName;
_manifestFilePath = manifestFilePath;
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadEditorManifest;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadEditorManifest)
{
if (File.Exists(_manifestFilePath) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Not found simulation manifest file : {_manifestFilePath}";
return;
}
if (_steps == ESteps.LoadEditorManifest)
{
if (File.Exists(_manifestFilePath) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Not found simulation manifest file : {_manifestFilePath}";
return;
}
YooLogger.Log($"Load editor manifest file : {_manifestFilePath}");
byte[] bytesData = FileUtility.ReadAllBytes(_manifestFilePath);
_deserializer = new DeserializeManifestOperation(bytesData);
OperationSystem.StartOperation(_packageName, _deserializer);
_steps = ESteps.CheckDeserializeManifest;
}
YooLogger.Log($"Load editor manifest file : {_manifestFilePath}");
byte[] bytesData = FileUtility.ReadAllBytes(_manifestFilePath);
_deserializer = new DeserializeManifestOperation(bytesData);
OperationSystem.StartOperation(_packageName, _deserializer);
_steps = ESteps.CheckDeserializeManifest;
}
if (_steps == ESteps.CheckDeserializeManifest)
{
Progress = _deserializer.Progress;
if (_deserializer.IsDone == false)
return;
if (_steps == ESteps.CheckDeserializeManifest)
{
Progress = _deserializer.Progress;
if (_deserializer.IsDone == false)
return;
if (_deserializer.Status == EOperationStatus.Succeed)
{
Manifest = _deserializer.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _deserializer.Error;
}
}
}
}
if (_deserializer.Status == EOperationStatus.Succeed)
{
Manifest = _deserializer.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _deserializer.Error;
}
}
}
}
}

View File

@ -1,151 +1,151 @@

namespace YooAsset
{
internal class LoadRemoteManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
DownloadPackageHashFile,
DownloadManifestFile,
VerifyFileHash,
CheckDeserializeManifest,
Done,
}
internal class LoadRemoteManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
DownloadPackageHashFile,
DownloadManifestFile,
VerifyFileHash,
CheckDeserializeManifest,
Done,
}
private readonly IRemoteServices _remoteServices;
private readonly string _packageName;
private readonly string _packageVersion;
private readonly int _timeout;
private QueryRemotePackageHashOperation _queryRemotePackageHashOp;
private UnityWebDataRequester _downloader;
private DeserializeManifestOperation _deserializer;
private byte[] _fileData;
private ESteps _steps = ESteps.None;
private int _requestCount = 0;
private readonly IRemoteServices _remoteServices;
private readonly string _packageName;
private readonly string _packageVersion;
private readonly int _timeout;
private QueryRemotePackageHashOperation _queryRemotePackageHashOp;
private UnityWebDataRequester _downloader;
private DeserializeManifestOperation _deserializer;
private byte[] _fileData;
private ESteps _steps = ESteps.None;
private int _requestCount = 0;
/// <summary>
/// 加载的清单实例
/// </summary>
public PackageManifest Manifest { private set; get; }
/// <summary>
/// 加载的清单实例
/// </summary>
public PackageManifest Manifest { private set; get; }
internal LoadRemoteManifestOperation(IRemoteServices remoteServices, string packageName, string packageVersion, int timeout)
{
_remoteServices = remoteServices;
_packageName = packageName;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_requestCount = RequestHelper.GetRequestFailedCount(_packageName, nameof(LoadRemoteManifestOperation));
_steps = ESteps.DownloadPackageHashFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
internal LoadRemoteManifestOperation(IRemoteServices remoteServices, string packageName, string packageVersion, int timeout)
{
_remoteServices = remoteServices;
_packageName = packageName;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_requestCount = RequestHelper.GetRequestFailedCount(_packageName, nameof(LoadRemoteManifestOperation));
_steps = ESteps.DownloadPackageHashFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.DownloadPackageHashFile)
{
if (_queryRemotePackageHashOp == null)
{
_queryRemotePackageHashOp = new QueryRemotePackageHashOperation(_remoteServices, _packageName, _packageVersion, _timeout);
OperationSystem.StartOperation(_packageName, _queryRemotePackageHashOp);
}
if (_steps == ESteps.DownloadPackageHashFile)
{
if (_queryRemotePackageHashOp == null)
{
_queryRemotePackageHashOp = new QueryRemotePackageHashOperation(_remoteServices, _packageName, _packageVersion, _timeout);
OperationSystem.StartOperation(_packageName, _queryRemotePackageHashOp);
}
if (_queryRemotePackageHashOp.IsDone == false)
return;
if (_queryRemotePackageHashOp.IsDone == false)
return;
if (_queryRemotePackageHashOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.DownloadManifestFile;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _queryRemotePackageHashOp.Error;
}
}
if (_queryRemotePackageHashOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.DownloadManifestFile;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _queryRemotePackageHashOp.Error;
}
}
if (_steps == ESteps.DownloadManifestFile)
{
if (_downloader == null)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_packageName, _packageVersion);
string webURL = GetDownloadRequestURL(fileName);
YooLogger.Log($"Beginning to download manifest file : {webURL}");
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(webURL, _timeout);
}
if (_steps == ESteps.DownloadManifestFile)
{
if (_downloader == null)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_packageName, _packageVersion);
string webURL = GetDownloadRequestURL(fileName);
YooLogger.Log($"Beginning to download manifest file : {webURL}");
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(webURL, _timeout);
}
_downloader.CheckTimeout();
if (_downloader.IsDone() == false)
return;
_downloader.CheckTimeout();
if (_downloader.IsDone() == false)
return;
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader.GetError();
RequestHelper.RecordRequestFailed(_packageName, nameof(LoadRemoteManifestOperation));
}
else
{
_fileData = _downloader.GetData();
_steps = ESteps.VerifyFileHash;
}
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader.GetError();
RequestHelper.RecordRequestFailed(_packageName, nameof(LoadRemoteManifestOperation));
}
else
{
_fileData = _downloader.GetData();
_steps = ESteps.VerifyFileHash;
}
_downloader.Dispose();
}
_downloader.Dispose();
}
if (_steps == ESteps.VerifyFileHash)
{
string fileHash = HashUtility.BytesMD5(_fileData);
if (fileHash != _queryRemotePackageHashOp.PackageHash)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Failed to verify remote manifest file hash !";
}
else
{
_deserializer = new DeserializeManifestOperation(_fileData);
OperationSystem.StartOperation(_packageName, _deserializer);
_steps = ESteps.CheckDeserializeManifest;
}
}
if (_steps == ESteps.VerifyFileHash)
{
string fileHash = HashUtility.BytesMD5(_fileData);
if (fileHash != _queryRemotePackageHashOp.PackageHash)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Failed to verify remote manifest file hash !";
}
else
{
_deserializer = new DeserializeManifestOperation(_fileData);
OperationSystem.StartOperation(_packageName, _deserializer);
_steps = ESteps.CheckDeserializeManifest;
}
}
if (_steps == ESteps.CheckDeserializeManifest)
{
Progress = _deserializer.Progress;
if (_deserializer.IsDone == false)
return;
if (_steps == ESteps.CheckDeserializeManifest)
{
Progress = _deserializer.Progress;
if (_deserializer.IsDone == false)
return;
if (_deserializer.Status == EOperationStatus.Succeed)
{
Manifest = _deserializer.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _deserializer.Error;
}
}
}
if (_deserializer.Status == EOperationStatus.Succeed)
{
Manifest = _deserializer.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _deserializer.Error;
}
}
}
private string GetDownloadRequestURL(string fileName)
{
// 轮流返回请求地址
if (_requestCount % 2 == 0)
return _remoteServices.GetRemoteMainURL(fileName);
else
return _remoteServices.GetRemoteFallbackURL(fileName);
}
}
private string GetDownloadRequestURL(string fileName)
{
// 轮流返回请求地址
if (_requestCount % 2 == 0)
return _remoteServices.GetRemoteMainURL(fileName);
else
return _remoteServices.GetRemoteFallbackURL(fileName);
}
}
}

View File

@ -1,75 +1,75 @@

namespace YooAsset
{
internal class QueryBuildinPackageVersionOperation : AsyncOperationBase
{
private enum ESteps
{
None,
LoadBuildinPackageVersionFile,
Done,
}
internal class QueryBuildinPackageVersionOperation : AsyncOperationBase
{
private enum ESteps
{
None,
LoadBuildinPackageVersionFile,
Done,
}
private readonly PersistentManager _persistent;
private UnityWebDataRequester _downloader;
private ESteps _steps = ESteps.None;
private readonly PersistentManager _persistent;
private UnityWebDataRequester _downloader;
private ESteps _steps = ESteps.None;
/// <summary>
/// 包裹版本
/// </summary>
public string PackageVersion { private set; get; }
/// <summary>
/// 包裹版本
/// </summary>
public string PackageVersion { private set; get; }
public QueryBuildinPackageVersionOperation(PersistentManager persistent)
{
_persistent = persistent;
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadBuildinPackageVersionFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public QueryBuildinPackageVersionOperation(PersistentManager persistent)
{
_persistent = persistent;
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadBuildinPackageVersionFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadBuildinPackageVersionFile)
{
if (_downloader == null)
{
string filePath = _persistent.GetBuildinPackageVersionFilePath();
string url = PersistentHelper.ConvertToWWWPath(filePath);
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(url);
}
if (_steps == ESteps.LoadBuildinPackageVersionFile)
{
if (_downloader == null)
{
string filePath = _persistent.GetBuildinPackageVersionFilePath();
string url = PersistentHelper.ConvertToWWWPath(filePath);
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(url);
}
if (_downloader.IsDone() == false)
return;
if (_downloader.IsDone() == false)
return;
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader.GetError();
}
else
{
PackageVersion = _downloader.GetText();
if (string.IsNullOrEmpty(PackageVersion))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Buildin package version file content is empty !";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader.GetError();
}
else
{
PackageVersion = _downloader.GetText();
if (string.IsNullOrEmpty(PackageVersion))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Buildin package version file content is empty !";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
_downloader.Dispose();
}
}
}
_downloader.Dispose();
}
}
}
}

View File

@ -2,63 +2,63 @@
namespace YooAsset
{
internal class QueryCachePackageHashOperation : AsyncOperationBase
{
private enum ESteps
{
None,
LoadCachePackageHashFile,
Done,
}
internal class QueryCachePackageHashOperation : AsyncOperationBase
{
private enum ESteps
{
None,
LoadCachePackageHashFile,
Done,
}
private readonly PersistentManager _persistent;
private readonly string _packageVersion;
private ESteps _steps = ESteps.None;
private readonly PersistentManager _persistent;
private readonly string _packageVersion;
private ESteps _steps = ESteps.None;
/// <summary>
/// 包裹哈希值
/// </summary>
public string PackageHash { private set; get; }
/// <summary>
/// 包裹哈希值
/// </summary>
public string PackageHash { private set; get; }
public QueryCachePackageHashOperation(PersistentManager persistent, string packageVersion)
{
_persistent = persistent;
_packageVersion = packageVersion;
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadCachePackageHashFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public QueryCachePackageHashOperation(PersistentManager persistent, string packageVersion)
{
_persistent = persistent;
_packageVersion = packageVersion;
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadCachePackageHashFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadCachePackageHashFile)
{
string filePath = _persistent.GetSandboxPackageHashFilePath(_packageVersion);
if (File.Exists(filePath) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Cache package hash file not found : {filePath}";
return;
}
if (_steps == ESteps.LoadCachePackageHashFile)
{
string filePath = _persistent.GetSandboxPackageHashFilePath(_packageVersion);
if (File.Exists(filePath) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Cache package hash file not found : {filePath}";
return;
}
PackageHash = FileUtility.ReadAllText(filePath);
if (string.IsNullOrEmpty(PackageHash))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Cache package hash file content is empty !";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
PackageHash = FileUtility.ReadAllText(filePath);
if (string.IsNullOrEmpty(PackageHash))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Cache package hash file content is empty !";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
}

View File

@ -2,61 +2,61 @@
namespace YooAsset
{
internal class QueryCachePackageVersionOperation : AsyncOperationBase
{
private enum ESteps
{
None,
LoadCachePackageVersionFile,
Done,
}
internal class QueryCachePackageVersionOperation : AsyncOperationBase
{
private enum ESteps
{
None,
LoadCachePackageVersionFile,
Done,
}
private readonly PersistentManager _persistent;
private ESteps _steps = ESteps.None;
private readonly PersistentManager _persistent;
private ESteps _steps = ESteps.None;
/// <summary>
/// 包裹版本
/// </summary>
public string PackageVersion { private set; get; }
/// <summary>
/// 包裹版本
/// </summary>
public string PackageVersion { private set; get; }
public QueryCachePackageVersionOperation(PersistentManager persistent)
{
_persistent = persistent;
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadCachePackageVersionFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public QueryCachePackageVersionOperation(PersistentManager persistent)
{
_persistent = persistent;
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadCachePackageVersionFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadCachePackageVersionFile)
{
string filePath = _persistent.GetSandboxPackageVersionFilePath();
if (File.Exists(filePath) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Cache package version file not found : {filePath}";
return;
}
if (_steps == ESteps.LoadCachePackageVersionFile)
{
string filePath = _persistent.GetSandboxPackageVersionFilePath();
if (File.Exists(filePath) == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Cache package version file not found : {filePath}";
return;
}
PackageVersion = FileUtility.ReadAllText(filePath);
if (string.IsNullOrEmpty(PackageVersion))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Cache package version file content is empty !";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
PackageVersion = FileUtility.ReadAllText(filePath);
if (string.IsNullOrEmpty(PackageVersion))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Cache package version file content is empty !";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
}

View File

@ -1,100 +1,100 @@

namespace YooAsset
{
internal class QueryRemotePackageHashOperation : AsyncOperationBase
{
private enum ESteps
{
None,
DownloadPackageHash,
Done,
}
internal class QueryRemotePackageHashOperation : AsyncOperationBase
{
private enum ESteps
{
None,
DownloadPackageHash,
Done,
}
private readonly IRemoteServices _remoteServices;
private readonly string _packageName;
private readonly string _packageVersion;
private readonly int _timeout;
private UnityWebDataRequester _downloader;
private ESteps _steps = ESteps.None;
private int _requestCount = 0;
private readonly IRemoteServices _remoteServices;
private readonly string _packageName;
private readonly string _packageVersion;
private readonly int _timeout;
private UnityWebDataRequester _downloader;
private ESteps _steps = ESteps.None;
private int _requestCount = 0;
/// <summary>
/// 包裹哈希值
/// </summary>
public string PackageHash { private set; get; }
/// <summary>
/// 包裹哈希值
/// </summary>
public string PackageHash { private set; get; }
public QueryRemotePackageHashOperation(IRemoteServices remoteServices, string packageName, string packageVersion, int timeout)
{
_remoteServices = remoteServices;
_packageName = packageName;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_requestCount = RequestHelper.GetRequestFailedCount(_packageName, nameof(QueryRemotePackageHashOperation));
_steps = ESteps.DownloadPackageHash;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public QueryRemotePackageHashOperation(IRemoteServices remoteServices, string packageName, string packageVersion, int timeout)
{
_remoteServices = remoteServices;
_packageName = packageName;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_requestCount = RequestHelper.GetRequestFailedCount(_packageName, nameof(QueryRemotePackageHashOperation));
_steps = ESteps.DownloadPackageHash;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.DownloadPackageHash)
{
if (_downloader == null)
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(_packageName, _packageVersion);
string webURL = GetPackageHashRequestURL(fileName);
YooLogger.Log($"Beginning to request package hash : {webURL}");
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(webURL, _timeout);
}
if (_steps == ESteps.DownloadPackageHash)
{
if (_downloader == null)
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(_packageName, _packageVersion);
string webURL = GetPackageHashRequestURL(fileName);
YooLogger.Log($"Beginning to request package hash : {webURL}");
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(webURL, _timeout);
}
Progress = _downloader.Progress();
_downloader.CheckTimeout();
if (_downloader.IsDone() == false)
return;
Progress = _downloader.Progress();
_downloader.CheckTimeout();
if (_downloader.IsDone() == false)
return;
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader.GetError();
RequestHelper.RecordRequestFailed(_packageName, nameof(QueryRemotePackageHashOperation));
}
else
{
PackageHash = _downloader.GetText();
if (string.IsNullOrEmpty(PackageHash))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Remote package hash is empty : {_downloader.URL}";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader.GetError();
RequestHelper.RecordRequestFailed(_packageName, nameof(QueryRemotePackageHashOperation));
}
else
{
PackageHash = _downloader.GetText();
if (string.IsNullOrEmpty(PackageHash))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Remote package hash is empty : {_downloader.URL}";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
_downloader.Dispose();
}
}
_downloader.Dispose();
}
}
private string GetPackageHashRequestURL(string fileName)
{
string url;
private string GetPackageHashRequestURL(string fileName)
{
string url;
// 轮流返回请求地址
if (_requestCount % 2 == 0)
url = _remoteServices.GetRemoteMainURL(fileName);
else
url = _remoteServices.GetRemoteFallbackURL(fileName);
// 轮流返回请求地址
if (_requestCount % 2 == 0)
url = _remoteServices.GetRemoteMainURL(fileName);
else
url = _remoteServices.GetRemoteFallbackURL(fileName);
return url;
}
}
return url;
}
}
}

View File

@ -1,104 +1,104 @@

namespace YooAsset
{
internal class QueryRemotePackageVersionOperation : AsyncOperationBase
{
private enum ESteps
{
None,
DownloadPackageVersion,
Done,
}
internal class QueryRemotePackageVersionOperation : AsyncOperationBase
{
private enum ESteps
{
None,
DownloadPackageVersion,
Done,
}
private readonly IRemoteServices _remoteServices;
private readonly string _packageName;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private UnityWebDataRequester _downloader;
private ESteps _steps = ESteps.None;
private int _requestCount = 0;
private readonly IRemoteServices _remoteServices;
private readonly string _packageName;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private UnityWebDataRequester _downloader;
private ESteps _steps = ESteps.None;
private int _requestCount = 0;
/// <summary>
/// 包裹版本
/// </summary>
public string PackageVersion { private set; get; }
/// <summary>
/// 包裹版本
/// </summary>
public string PackageVersion { private set; get; }
public QueryRemotePackageVersionOperation(IRemoteServices remoteServices, string packageName, bool appendTimeTicks, int timeout)
{
_remoteServices = remoteServices;
_packageName = packageName;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_requestCount = RequestHelper.GetRequestFailedCount(_packageName, nameof(QueryRemotePackageVersionOperation));
_steps = ESteps.DownloadPackageVersion;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public QueryRemotePackageVersionOperation(IRemoteServices remoteServices, string packageName, bool appendTimeTicks, int timeout)
{
_remoteServices = remoteServices;
_packageName = packageName;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_requestCount = RequestHelper.GetRequestFailedCount(_packageName, nameof(QueryRemotePackageVersionOperation));
_steps = ESteps.DownloadPackageVersion;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.DownloadPackageVersion)
{
if (_downloader == null)
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(_packageName);
string webURL = GetPackageVersionRequestURL(fileName);
YooLogger.Log($"Beginning to request package version : {webURL}");
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(webURL, _timeout);
}
if (_steps == ESteps.DownloadPackageVersion)
{
if (_downloader == null)
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(_packageName);
string webURL = GetPackageVersionRequestURL(fileName);
YooLogger.Log($"Beginning to request package version : {webURL}");
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(webURL, _timeout);
}
Progress = _downloader.Progress();
_downloader.CheckTimeout();
if (_downloader.IsDone() == false)
return;
Progress = _downloader.Progress();
_downloader.CheckTimeout();
if (_downloader.IsDone() == false)
return;
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader.GetError();
RequestHelper.RecordRequestFailed(_packageName, nameof(QueryRemotePackageVersionOperation));
}
else
{
PackageVersion = _downloader.GetText();
if (string.IsNullOrEmpty(PackageVersion))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Remote package version is empty : {_downloader.URL}";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader.GetError();
RequestHelper.RecordRequestFailed(_packageName, nameof(QueryRemotePackageVersionOperation));
}
else
{
PackageVersion = _downloader.GetText();
if (string.IsNullOrEmpty(PackageVersion))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Remote package version is empty : {_downloader.URL}";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
_downloader.Dispose();
}
}
_downloader.Dispose();
}
}
private string GetPackageVersionRequestURL(string fileName)
{
string url;
private string GetPackageVersionRequestURL(string fileName)
{
string url;
// 轮流返回请求地址
if (_requestCount % 2 == 0)
url = _remoteServices.GetRemoteMainURL(fileName);
else
url = _remoteServices.GetRemoteFallbackURL(fileName);
// 轮流返回请求地址
if (_requestCount % 2 == 0)
url = _remoteServices.GetRemoteMainURL(fileName);
else
url = _remoteServices.GetRemoteFallbackURL(fileName);
// 在URL末尾添加时间戳
if (_appendTimeTicks)
return $"{url}?{System.DateTime.UtcNow.Ticks}";
else
return url;
}
}
// 在URL末尾添加时间戳
if (_appendTimeTicks)
return $"{url}?{System.DateTime.UtcNow.Ticks}";
else
return url;
}
}
}

View File

@ -1,92 +1,92 @@

namespace YooAsset
{
internal class UnpackBuildinManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
UnpackManifestHashFile,
UnpackManifestFile,
Done,
}
internal class UnpackBuildinManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
UnpackManifestHashFile,
UnpackManifestFile,
Done,
}
private readonly PersistentManager _persistent;
private readonly string _buildinPackageVersion;
private UnityWebFileRequester _downloader1;
private UnityWebFileRequester _downloader2;
private ESteps _steps = ESteps.None;
private readonly PersistentManager _persistent;
private readonly string _buildinPackageVersion;
private UnityWebFileRequester _downloader1;
private UnityWebFileRequester _downloader2;
private ESteps _steps = ESteps.None;
public UnpackBuildinManifestOperation(PersistentManager persistent, string buildinPackageVersion)
{
_persistent = persistent;
_buildinPackageVersion = buildinPackageVersion;
}
internal override void InternalOnStart()
{
_steps = ESteps.UnpackManifestHashFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
public UnpackBuildinManifestOperation(PersistentManager persistent, string buildinPackageVersion)
{
_persistent = persistent;
_buildinPackageVersion = buildinPackageVersion;
}
internal override void InternalOnStart()
{
_steps = ESteps.UnpackManifestHashFile;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.UnpackManifestHashFile)
{
if (_downloader1 == null)
{
string savePath = _persistent.GetSandboxPackageHashFilePath(_buildinPackageVersion);
string filePath = _persistent.GetBuildinPackageHashFilePath(_buildinPackageVersion);
string url = PersistentHelper.ConvertToWWWPath(filePath);
_downloader1 = new UnityWebFileRequester();
_downloader1.SendRequest(url, savePath);
}
if (_steps == ESteps.UnpackManifestHashFile)
{
if (_downloader1 == null)
{
string savePath = _persistent.GetSandboxPackageHashFilePath(_buildinPackageVersion);
string filePath = _persistent.GetBuildinPackageHashFilePath(_buildinPackageVersion);
string url = PersistentHelper.ConvertToWWWPath(filePath);
_downloader1 = new UnityWebFileRequester();
_downloader1.SendRequest(url, savePath);
}
if (_downloader1.IsDone() == false)
return;
if (_downloader1.IsDone() == false)
return;
if (_downloader1.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader1.GetError();
}
else
{
_steps = ESteps.UnpackManifestFile;
}
if (_downloader1.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader1.GetError();
}
else
{
_steps = ESteps.UnpackManifestFile;
}
_downloader1.Dispose();
}
_downloader1.Dispose();
}
if (_steps == ESteps.UnpackManifestFile)
{
if (_downloader2 == null)
{
string savePath = _persistent.GetSandboxPackageManifestFilePath(_buildinPackageVersion);
string filePath = _persistent.GetBuildinPackageManifestFilePath(_buildinPackageVersion);
string url = PersistentHelper.ConvertToWWWPath(filePath);
_downloader2 = new UnityWebFileRequester();
_downloader2.SendRequest(url, savePath);
}
if (_steps == ESteps.UnpackManifestFile)
{
if (_downloader2 == null)
{
string savePath = _persistent.GetSandboxPackageManifestFilePath(_buildinPackageVersion);
string filePath = _persistent.GetBuildinPackageManifestFilePath(_buildinPackageVersion);
string url = PersistentHelper.ConvertToWWWPath(filePath);
_downloader2 = new UnityWebFileRequester();
_downloader2.SendRequest(url, savePath);
}
if (_downloader2.IsDone() == false)
return;
if (_downloader2.IsDone() == false)
return;
if (_downloader2.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader2.GetError();
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
if (_downloader2.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader2.GetError();
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
_downloader2.Dispose();
}
}
}
_downloader2.Dispose();
}
}
}
}

View File

@ -4,360 +4,360 @@ using System.Collections.Generic;
namespace YooAsset
{
public abstract class PreDownloadContentOperation : AsyncOperationBase
{
/// <summary>
/// 创建资源下载器,用于下载当前资源版本所有的资源包文件
/// </summary>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
/// <param name="timeout">超时时间</param>
public abstract ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60);
public abstract class PreDownloadContentOperation : AsyncOperationBase
{
/// <summary>
/// 创建资源下载器,用于下载当前资源版本所有的资源包文件
/// </summary>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
/// <param name="timeout">超时时间</param>
public abstract ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60);
/// <summary>
/// 创建资源下载器,用于下载指定的资源标签关联的资源包文件
/// </summary>
/// <param name="tag">资源标签</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
/// <param name="timeout">超时时间</param>
public abstract ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60);
/// <summary>
/// 创建资源下载器,用于下载指定的资源标签关联的资源包文件
/// </summary>
/// <param name="tag">资源标签</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
/// <param name="timeout">超时时间</param>
public abstract ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60);
/// <summary>
/// 创建资源下载器,用于下载指定的资源标签列表关联的资源包文件
/// </summary>
/// <param name="tags">资源标签列表</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
/// <param name="timeout">超时时间</param>
public abstract ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60);
/// <summary>
/// 创建资源下载器,用于下载指定的资源标签列表关联的资源包文件
/// </summary>
/// <param name="tags">资源标签列表</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
/// <param name="timeout">超时时间</param>
public abstract ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60);
/// <summary>
/// 创建资源下载器,用于下载指定的资源依赖的资源包文件
/// </summary>
/// <param name="location">资源定位地址</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
/// <param name="timeout">超时时间</param>
public abstract ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60);
/// <summary>
/// 创建资源下载器,用于下载指定的资源依赖的资源包文件
/// </summary>
/// <param name="location">资源定位地址</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
/// <param name="timeout">超时时间</param>
public abstract ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60);
/// <summary>
/// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件
/// </summary>
/// <param name="locations">资源定位地址列表</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
/// <param name="timeout">超时时间</param>
public abstract ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60);
}
/// <summary>
/// 创建资源下载器,用于下载指定的资源列表依赖的资源包文件
/// </summary>
/// <param name="locations">资源定位地址列表</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
/// <param name="timeout">超时时间</param>
public abstract ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60);
}
internal class EditorPlayModePreDownloadContentOperation : PreDownloadContentOperation
{
private readonly EditorSimulateModeImpl _impl;
internal class EditorPlayModePreDownloadContentOperation : PreDownloadContentOperation
{
private readonly EditorSimulateModeImpl _impl;
public EditorPlayModePreDownloadContentOperation(EditorSimulateModeImpl impl)
{
_impl = impl;
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
public EditorPlayModePreDownloadContentOperation(EditorSimulateModeImpl impl)
{
_impl = impl;
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
public override ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
}
internal class OfflinePlayModePreDownloadContentOperation : PreDownloadContentOperation
{
private readonly OfflinePlayModeImpl _impl;
public override ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
}
internal class OfflinePlayModePreDownloadContentOperation : PreDownloadContentOperation
{
private readonly OfflinePlayModeImpl _impl;
public OfflinePlayModePreDownloadContentOperation(OfflinePlayModeImpl impl)
{
_impl = impl;
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
public OfflinePlayModePreDownloadContentOperation(OfflinePlayModeImpl impl)
{
_impl = impl;
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
public override ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
}
internal class HostPlayModePreDownloadContentOperation : PreDownloadContentOperation
{
private enum ESteps
{
None,
CheckActiveManifest,
TryLoadCacheManifest,
DownloadManifest,
LoadCacheManifest,
CheckDeserializeManifest,
Done,
}
public override ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
}
internal class HostPlayModePreDownloadContentOperation : PreDownloadContentOperation
{
private enum ESteps
{
None,
CheckActiveManifest,
TryLoadCacheManifest,
DownloadManifest,
LoadCacheManifest,
CheckDeserializeManifest,
Done,
}
private readonly HostPlayModeImpl _impl;
private readonly string _packageVersion;
private readonly int _timeout;
private LoadCacheManifestOperation _tryLoadCacheManifestOp;
private LoadCacheManifestOperation _loadCacheManifestOp;
private DownloadManifestOperation _downloadManifestOp;
private PackageManifest _manifest;
private ESteps _steps = ESteps.None;
private readonly HostPlayModeImpl _impl;
private readonly string _packageVersion;
private readonly int _timeout;
private LoadCacheManifestOperation _tryLoadCacheManifestOp;
private LoadCacheManifestOperation _loadCacheManifestOp;
private DownloadManifestOperation _downloadManifestOp;
private PackageManifest _manifest;
private ESteps _steps = ESteps.None;
internal HostPlayModePreDownloadContentOperation(HostPlayModeImpl impl, string packageVersion, int timeout)
{
_impl = impl;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.CheckActiveManifest;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
internal HostPlayModePreDownloadContentOperation(HostPlayModeImpl impl, string packageVersion, int timeout)
{
_impl = impl;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.CheckActiveManifest;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckActiveManifest)
{
// 检测当前激活的清单对象
if (_impl.ActiveManifest != null)
{
if (_impl.ActiveManifest.PackageVersion == _packageVersion)
{
_manifest = _impl.ActiveManifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
return;
}
}
_steps = ESteps.TryLoadCacheManifest;
}
if (_steps == ESteps.CheckActiveManifest)
{
// 检测当前激活的清单对象
if (_impl.ActiveManifest != null)
{
if (_impl.ActiveManifest.PackageVersion == _packageVersion)
{
_manifest = _impl.ActiveManifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
return;
}
}
_steps = ESteps.TryLoadCacheManifest;
}
if (_steps == ESteps.TryLoadCacheManifest)
{
if (_tryLoadCacheManifestOp == null)
{
_tryLoadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _packageVersion);
OperationSystem.StartOperation(_impl.PackageName, _tryLoadCacheManifestOp);
}
if (_steps == ESteps.TryLoadCacheManifest)
{
if (_tryLoadCacheManifestOp == null)
{
_tryLoadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _packageVersion);
OperationSystem.StartOperation(_impl.PackageName, _tryLoadCacheManifestOp);
}
if (_tryLoadCacheManifestOp.IsDone == false)
return;
if (_tryLoadCacheManifestOp.IsDone == false)
return;
if (_tryLoadCacheManifestOp.Status == EOperationStatus.Succeed)
{
_manifest = _tryLoadCacheManifestOp.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.DownloadManifest;
}
}
if (_tryLoadCacheManifestOp.Status == EOperationStatus.Succeed)
{
_manifest = _tryLoadCacheManifestOp.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.DownloadManifest;
}
}
if (_steps == ESteps.DownloadManifest)
{
if (_downloadManifestOp == null)
{
_downloadManifestOp = new DownloadManifestOperation(_impl.Persistent, _impl.RemoteServices, _packageVersion, _timeout);
OperationSystem.StartOperation(_impl.PackageName, _downloadManifestOp);
}
if (_steps == ESteps.DownloadManifest)
{
if (_downloadManifestOp == null)
{
_downloadManifestOp = new DownloadManifestOperation(_impl.Persistent, _impl.RemoteServices, _packageVersion, _timeout);
OperationSystem.StartOperation(_impl.PackageName, _downloadManifestOp);
}
if (_downloadManifestOp.IsDone == false)
return;
if (_downloadManifestOp.IsDone == false)
return;
if (_downloadManifestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadCacheManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadManifestOp.Error;
}
}
if (_downloadManifestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadCacheManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadManifestOp.Error;
}
}
if (_steps == ESteps.LoadCacheManifest)
{
if (_loadCacheManifestOp == null)
{
_loadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _packageVersion);
OperationSystem.StartOperation(_impl.PackageName, _loadCacheManifestOp);
}
if (_steps == ESteps.LoadCacheManifest)
{
if (_loadCacheManifestOp == null)
{
_loadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _packageVersion);
OperationSystem.StartOperation(_impl.PackageName, _loadCacheManifestOp);
}
if (_loadCacheManifestOp.IsDone == false)
return;
if (_loadCacheManifestOp.IsDone == false)
return;
if (_loadCacheManifestOp.Status == EOperationStatus.Succeed)
{
_manifest = _loadCacheManifestOp.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadCacheManifestOp.Error;
}
}
}
if (_loadCacheManifestOp.Status == EOperationStatus.Succeed)
{
_manifest = _loadCacheManifestOp.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadCacheManifestOp.Error;
}
}
}
public override ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
if (Status != EOperationStatus.Succeed)
{
YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !");
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
if (Status != EOperationStatus.Succeed)
{
YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !");
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
List<BundleInfo> downloadList = _impl.GetDownloadListByAll(_manifest);
var operation = new ResourceDownloaderOperation(_impl.Download, _impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
public override ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
if (Status != EOperationStatus.Succeed)
{
YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !");
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
List<BundleInfo> downloadList = _impl.GetDownloadListByAll(_manifest);
var operation = new ResourceDownloaderOperation(_impl.Download, _impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
public override ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
if (Status != EOperationStatus.Succeed)
{
YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !");
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
List<BundleInfo> downloadList = _impl.GetDownloadListByTags(_manifest, new string[] { tag });
var operation = new ResourceDownloaderOperation(_impl.Download, _impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
public override ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
if (Status != EOperationStatus.Succeed)
{
YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !");
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
List<BundleInfo> downloadList = _impl.GetDownloadListByTags(_manifest, new string[] { tag });
var operation = new ResourceDownloaderOperation(_impl.Download, _impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
public override ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
if (Status != EOperationStatus.Succeed)
{
YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !");
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
List<BundleInfo> downloadList = _impl.GetDownloadListByTags(_manifest, tags);
var operation = new ResourceDownloaderOperation(_impl.Download, _impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
if (Status != EOperationStatus.Succeed)
{
YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !");
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
List<BundleInfo> downloadList = _impl.GetDownloadListByTags(_manifest, tags);
var operation = new ResourceDownloaderOperation(_impl.Download, _impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
if (Status != EOperationStatus.Succeed)
{
YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !");
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
List<AssetInfo> assetInfos = new List<AssetInfo>();
var assetInfo = _manifest.ConvertLocationToAssetInfo(location, null);
assetInfos.Add(assetInfo);
List<AssetInfo> assetInfos = new List<AssetInfo>();
var assetInfo = _manifest.ConvertLocationToAssetInfo(location, null);
assetInfos.Add(assetInfo);
List<BundleInfo> downloadList = _impl.GetDownloadListByPaths(_manifest, assetInfos.ToArray());
var operation = new ResourceDownloaderOperation(_impl.Download, _impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
if (Status != EOperationStatus.Succeed)
{
YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !");
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
List<BundleInfo> downloadList = _impl.GetDownloadListByPaths(_manifest, assetInfos.ToArray());
var operation = new ResourceDownloaderOperation(_impl.Download, _impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
if (Status != EOperationStatus.Succeed)
{
YooLogger.Warning($"{nameof(PreDownloadContentOperation)} status is not succeed !");
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
List<AssetInfo> assetInfos = new List<AssetInfo>(locations.Length);
foreach (var location in locations)
{
var assetInfo = _manifest.ConvertLocationToAssetInfo(location, null);
assetInfos.Add(assetInfo);
}
List<AssetInfo> assetInfos = new List<AssetInfo>(locations.Length);
foreach (var location in locations)
{
var assetInfo = _manifest.ConvertLocationToAssetInfo(location, null);
assetInfos.Add(assetInfo);
}
List<BundleInfo> downloadList = _impl.GetDownloadListByPaths(_manifest, assetInfos.ToArray());
var operation = new ResourceDownloaderOperation(_impl.Download, _impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
}
internal class WebPlayModePreDownloadContentOperation : PreDownloadContentOperation
{
private readonly WebPlayModeImpl _impl;
List<BundleInfo> downloadList = _impl.GetDownloadListByPaths(_manifest, assetInfos.ToArray());
var operation = new ResourceDownloaderOperation(_impl.Download, _impl.PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
}
internal class WebPlayModePreDownloadContentOperation : PreDownloadContentOperation
{
private readonly WebPlayModeImpl _impl;
public WebPlayModePreDownloadContentOperation(WebPlayModeImpl impl)
{
_impl = impl;
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
public WebPlayModePreDownloadContentOperation(WebPlayModeImpl impl)
{
_impl = impl;
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
public override ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
}
public override ResourceDownloaderOperation CreateResourceDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateResourceDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateResourceDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateBundleDownloader(string location, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
public override ResourceDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(_impl.Download, _impl.PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
}
}

View File

@ -4,291 +4,291 @@ using System.Collections.Generic;
namespace YooAsset
{
/// <summary>
/// 向远端请求并更新清单
/// </summary>
public abstract class UpdatePackageManifestOperation : AsyncOperationBase
{
/// <summary>
/// 保存当前清单的版本,用于下次启动时自动加载的版本。
/// </summary>
public virtual void SavePackageVersion() { }
}
/// <summary>
/// 向远端请求并更新清单
/// </summary>
public abstract class UpdatePackageManifestOperation : AsyncOperationBase
{
/// <summary>
/// 保存当前清单的版本,用于下次启动时自动加载的版本。
/// </summary>
public virtual void SavePackageVersion() { }
}
/// <summary>
/// 编辑器下模拟运行的更新清单操作
/// </summary>
internal sealed class EditorPlayModeUpdatePackageManifestOperation : UpdatePackageManifestOperation
{
public EditorPlayModeUpdatePackageManifestOperation()
{
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
}
/// <summary>
/// 编辑器下模拟运行的更新清单操作
/// </summary>
internal sealed class EditorPlayModeUpdatePackageManifestOperation : UpdatePackageManifestOperation
{
public EditorPlayModeUpdatePackageManifestOperation()
{
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
}
/// <summary>
/// 离线模式的更新清单操作
/// </summary>
internal sealed class OfflinePlayModeUpdatePackageManifestOperation : UpdatePackageManifestOperation
{
public OfflinePlayModeUpdatePackageManifestOperation()
{
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
}
/// <summary>
/// 离线模式的更新清单操作
/// </summary>
internal sealed class OfflinePlayModeUpdatePackageManifestOperation : UpdatePackageManifestOperation
{
public OfflinePlayModeUpdatePackageManifestOperation()
{
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
}
/// <summary>
/// 联机模式的更新清单操作
/// 注意:优先加载沙盒里缓存的清单文件,如果缓存没找到就下载远端清单文件,并保存到本地。
/// </summary>
internal sealed class HostPlayModeUpdatePackageManifestOperation : UpdatePackageManifestOperation
{
private enum ESteps
{
None,
CheckParams,
CheckActiveManifest,
TryLoadCacheManifest,
DownloadManifest,
LoadCacheManifest,
CheckDeserializeManifest,
Done,
}
/// <summary>
/// 联机模式的更新清单操作
/// 注意:优先加载沙盒里缓存的清单文件,如果缓存没找到就下载远端清单文件,并保存到本地。
/// </summary>
internal sealed class HostPlayModeUpdatePackageManifestOperation : UpdatePackageManifestOperation
{
private enum ESteps
{
None,
CheckParams,
CheckActiveManifest,
TryLoadCacheManifest,
DownloadManifest,
LoadCacheManifest,
CheckDeserializeManifest,
Done,
}
private readonly HostPlayModeImpl _impl;
private readonly string _packageVersion;
private readonly bool _autoSaveVersion;
private readonly int _timeout;
private LoadCacheManifestOperation _tryLoadCacheManifestOp;
private LoadCacheManifestOperation _loadCacheManifestOp;
private DownloadManifestOperation _downloadManifestOp;
private ESteps _steps = ESteps.None;
private readonly HostPlayModeImpl _impl;
private readonly string _packageVersion;
private readonly bool _autoSaveVersion;
private readonly int _timeout;
private LoadCacheManifestOperation _tryLoadCacheManifestOp;
private LoadCacheManifestOperation _loadCacheManifestOp;
private DownloadManifestOperation _downloadManifestOp;
private ESteps _steps = ESteps.None;
internal HostPlayModeUpdatePackageManifestOperation(HostPlayModeImpl impl, string packageVersion, bool autoSaveVersion, int timeout)
{
_impl = impl;
_packageVersion = packageVersion;
_autoSaveVersion = autoSaveVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.CheckParams;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
internal HostPlayModeUpdatePackageManifestOperation(HostPlayModeImpl impl, string packageVersion, bool autoSaveVersion, int timeout)
{
_impl = impl;
_packageVersion = packageVersion;
_autoSaveVersion = autoSaveVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.CheckParams;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckParams)
{
if (string.IsNullOrEmpty(_packageVersion))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Package version is null or empty.";
return;
}
if (_steps == ESteps.CheckParams)
{
if (string.IsNullOrEmpty(_packageVersion))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Package version is null or empty.";
return;
}
_steps = ESteps.CheckActiveManifest;
}
_steps = ESteps.CheckActiveManifest;
}
if (_steps == ESteps.CheckActiveManifest)
{
// 检测当前激活的清单对象
if (_impl.ActiveManifest != null && _impl.ActiveManifest.PackageVersion == _packageVersion)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.TryLoadCacheManifest;
}
}
if (_steps == ESteps.CheckActiveManifest)
{
// 检测当前激活的清单对象
if (_impl.ActiveManifest != null && _impl.ActiveManifest.PackageVersion == _packageVersion)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.TryLoadCacheManifest;
}
}
if (_steps == ESteps.TryLoadCacheManifest)
{
if (_tryLoadCacheManifestOp == null)
{
_tryLoadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _packageVersion);
OperationSystem.StartOperation(_impl.PackageName, _tryLoadCacheManifestOp);
}
if (_steps == ESteps.TryLoadCacheManifest)
{
if (_tryLoadCacheManifestOp == null)
{
_tryLoadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _packageVersion);
OperationSystem.StartOperation(_impl.PackageName, _tryLoadCacheManifestOp);
}
if (_tryLoadCacheManifestOp.IsDone == false)
return;
if (_tryLoadCacheManifestOp.IsDone == false)
return;
if (_tryLoadCacheManifestOp.Status == EOperationStatus.Succeed)
{
_impl.ActiveManifest = _tryLoadCacheManifestOp.Manifest;
if (_autoSaveVersion)
SavePackageVersion();
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.DownloadManifest;
}
}
if (_tryLoadCacheManifestOp.Status == EOperationStatus.Succeed)
{
_impl.ActiveManifest = _tryLoadCacheManifestOp.Manifest;
if (_autoSaveVersion)
SavePackageVersion();
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.DownloadManifest;
}
}
if (_steps == ESteps.DownloadManifest)
{
if (_downloadManifestOp == null)
{
_downloadManifestOp = new DownloadManifestOperation(_impl.Persistent, _impl.RemoteServices, _packageVersion, _timeout);
OperationSystem.StartOperation(_impl.PackageName, _downloadManifestOp);
}
if (_steps == ESteps.DownloadManifest)
{
if (_downloadManifestOp == null)
{
_downloadManifestOp = new DownloadManifestOperation(_impl.Persistent, _impl.RemoteServices, _packageVersion, _timeout);
OperationSystem.StartOperation(_impl.PackageName, _downloadManifestOp);
}
if (_downloadManifestOp.IsDone == false)
return;
if (_downloadManifestOp.IsDone == false)
return;
if (_downloadManifestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadCacheManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadManifestOp.Error;
}
}
if (_downloadManifestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadCacheManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadManifestOp.Error;
}
}
if (_steps == ESteps.LoadCacheManifest)
{
if (_loadCacheManifestOp == null)
{
_loadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _packageVersion);
OperationSystem.StartOperation(_impl.PackageName, _loadCacheManifestOp);
}
if (_steps == ESteps.LoadCacheManifest)
{
if (_loadCacheManifestOp == null)
{
_loadCacheManifestOp = new LoadCacheManifestOperation(_impl.Persistent, _packageVersion);
OperationSystem.StartOperation(_impl.PackageName, _loadCacheManifestOp);
}
if (_loadCacheManifestOp.IsDone == false)
return;
if (_loadCacheManifestOp.IsDone == false)
return;
if (_loadCacheManifestOp.Status == EOperationStatus.Succeed)
{
_impl.ActiveManifest = _loadCacheManifestOp.Manifest;
if (_autoSaveVersion)
SavePackageVersion();
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadCacheManifestOp.Error;
}
}
}
if (_loadCacheManifestOp.Status == EOperationStatus.Succeed)
{
_impl.ActiveManifest = _loadCacheManifestOp.Manifest;
if (_autoSaveVersion)
SavePackageVersion();
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadCacheManifestOp.Error;
}
}
}
public override void SavePackageVersion()
{
_impl.FlushManifestVersionFile();
}
}
public override void SavePackageVersion()
{
_impl.FlushManifestVersionFile();
}
}
/// <summary>
/// WebGL模式的更新清单操作
/// </summary>
internal sealed class WebPlayModeUpdatePackageManifestOperation : UpdatePackageManifestOperation
{
private enum ESteps
{
None,
CheckParams,
CheckActiveManifest,
LoadRemoteManifest,
Done,
}
/// <summary>
/// WebGL模式的更新清单操作
/// </summary>
internal sealed class WebPlayModeUpdatePackageManifestOperation : UpdatePackageManifestOperation
{
private enum ESteps
{
None,
CheckParams,
CheckActiveManifest,
LoadRemoteManifest,
Done,
}
private readonly WebPlayModeImpl _impl;
private readonly string _packageVersion;
private readonly int _timeout;
private LoadRemoteManifestOperation _loadCacheManifestOp;
private ESteps _steps = ESteps.None;
private readonly WebPlayModeImpl _impl;
private readonly string _packageVersion;
private readonly int _timeout;
private LoadRemoteManifestOperation _loadCacheManifestOp;
private ESteps _steps = ESteps.None;
internal WebPlayModeUpdatePackageManifestOperation(WebPlayModeImpl impl, string packageVersion, int timeout)
{
_impl = impl;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.CheckParams;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
internal WebPlayModeUpdatePackageManifestOperation(WebPlayModeImpl impl, string packageVersion, int timeout)
{
_impl = impl;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.CheckParams;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckParams)
{
if (string.IsNullOrEmpty(_packageVersion))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Package version is null or empty.";
return;
}
if (_steps == ESteps.CheckParams)
{
if (string.IsNullOrEmpty(_packageVersion))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Package version is null or empty.";
return;
}
_steps = ESteps.CheckActiveManifest;
}
_steps = ESteps.CheckActiveManifest;
}
if (_steps == ESteps.CheckActiveManifest)
{
// 检测当前激活的清单对象
if (_impl.ActiveManifest != null && _impl.ActiveManifest.PackageVersion == _packageVersion)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.LoadRemoteManifest;
}
}
if (_steps == ESteps.CheckActiveManifest)
{
// 检测当前激活的清单对象
if (_impl.ActiveManifest != null && _impl.ActiveManifest.PackageVersion == _packageVersion)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.LoadRemoteManifest;
}
}
if (_steps == ESteps.LoadRemoteManifest)
{
if (_loadCacheManifestOp == null)
{
_loadCacheManifestOp = new LoadRemoteManifestOperation(_impl.RemoteServices, _impl.PackageName, _packageVersion, _timeout);
OperationSystem.StartOperation(_impl.PackageName, _loadCacheManifestOp);
}
if (_steps == ESteps.LoadRemoteManifest)
{
if (_loadCacheManifestOp == null)
{
_loadCacheManifestOp = new LoadRemoteManifestOperation(_impl.RemoteServices, _impl.PackageName, _packageVersion, _timeout);
OperationSystem.StartOperation(_impl.PackageName, _loadCacheManifestOp);
}
if (_loadCacheManifestOp.IsDone == false)
return;
if (_loadCacheManifestOp.IsDone == false)
return;
if (_loadCacheManifestOp.Status == EOperationStatus.Succeed)
{
_impl.ActiveManifest = _loadCacheManifestOp.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadCacheManifestOp.Error;
}
}
}
}
if (_loadCacheManifestOp.Status == EOperationStatus.Succeed)
{
_impl.ActiveManifest = _loadCacheManifestOp.Manifest;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadCacheManifestOp.Error;
}
}
}
}
}

View File

@ -4,162 +4,162 @@ using UnityEngine;
namespace YooAsset
{
/// <summary>
/// 请求远端包裹的最新版本
/// </summary>
public abstract class UpdatePackageVersionOperation : AsyncOperationBase
{
/// <summary>
/// 当前最新的包裹版本
/// </summary>
public string PackageVersion { protected set; get; }
}
/// <summary>
/// 请求远端包裹的最新版本
/// </summary>
public abstract class UpdatePackageVersionOperation : AsyncOperationBase
{
/// <summary>
/// 当前最新的包裹版本
/// </summary>
public string PackageVersion { protected set; get; }
}
/// <summary>
/// 编辑器下模拟模式的请求远端包裹的最新版本
/// </summary>
internal sealed class EditorPlayModeUpdatePackageVersionOperation : UpdatePackageVersionOperation
{
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
}
/// <summary>
/// 编辑器下模拟模式的请求远端包裹的最新版本
/// </summary>
internal sealed class EditorPlayModeUpdatePackageVersionOperation : UpdatePackageVersionOperation
{
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
}
/// <summary>
/// 离线模式的请求远端包裹的最新版本
/// </summary>
internal sealed class OfflinePlayModeUpdatePackageVersionOperation : UpdatePackageVersionOperation
{
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
}
/// <summary>
/// 离线模式的请求远端包裹的最新版本
/// </summary>
internal sealed class OfflinePlayModeUpdatePackageVersionOperation : UpdatePackageVersionOperation
{
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
}
/// <summary>
/// 联机模式的请求远端包裹的最新版本
/// </summary>
internal sealed class HostPlayModeUpdatePackageVersionOperation : UpdatePackageVersionOperation
{
private enum ESteps
{
None,
QueryRemotePackageVersion,
Done,
}
/// <summary>
/// 联机模式的请求远端包裹的最新版本
/// </summary>
internal sealed class HostPlayModeUpdatePackageVersionOperation : UpdatePackageVersionOperation
{
private enum ESteps
{
None,
QueryRemotePackageVersion,
Done,
}
private readonly HostPlayModeImpl _impl;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private QueryRemotePackageVersionOperation _queryRemotePackageVersionOp;
private ESteps _steps = ESteps.None;
private readonly HostPlayModeImpl _impl;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private QueryRemotePackageVersionOperation _queryRemotePackageVersionOp;
private ESteps _steps = ESteps.None;
internal HostPlayModeUpdatePackageVersionOperation(HostPlayModeImpl impl, bool appendTimeTicks, int timeout)
{
_impl = impl;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.QueryRemotePackageVersion;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
internal HostPlayModeUpdatePackageVersionOperation(HostPlayModeImpl impl, bool appendTimeTicks, int timeout)
{
_impl = impl;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.QueryRemotePackageVersion;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.QueryRemotePackageVersion)
{
if (_queryRemotePackageVersionOp == null)
{
_queryRemotePackageVersionOp = new QueryRemotePackageVersionOperation(_impl.RemoteServices, _impl.PackageName, _appendTimeTicks, _timeout);
OperationSystem.StartOperation(_impl.PackageName, _queryRemotePackageVersionOp);
}
if (_steps == ESteps.QueryRemotePackageVersion)
{
if (_queryRemotePackageVersionOp == null)
{
_queryRemotePackageVersionOp = new QueryRemotePackageVersionOperation(_impl.RemoteServices, _impl.PackageName, _appendTimeTicks, _timeout);
OperationSystem.StartOperation(_impl.PackageName, _queryRemotePackageVersionOp);
}
if (_queryRemotePackageVersionOp.IsDone == false)
return;
if (_queryRemotePackageVersionOp.IsDone == false)
return;
if (_queryRemotePackageVersionOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _queryRemotePackageVersionOp.PackageVersion;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _queryRemotePackageVersionOp.Error;
}
}
}
}
if (_queryRemotePackageVersionOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _queryRemotePackageVersionOp.PackageVersion;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _queryRemotePackageVersionOp.Error;
}
}
}
}
/// <summary>
/// WebGL模式的请求远端包裹的最新版本
/// </summary>
internal sealed class WebPlayModeUpdatePackageVersionOperation : UpdatePackageVersionOperation
{
private enum ESteps
{
None,
QueryRemotePackageVersion,
Done,
}
/// <summary>
/// WebGL模式的请求远端包裹的最新版本
/// </summary>
internal sealed class WebPlayModeUpdatePackageVersionOperation : UpdatePackageVersionOperation
{
private enum ESteps
{
None,
QueryRemotePackageVersion,
Done,
}
private readonly WebPlayModeImpl _impl;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private QueryRemotePackageVersionOperation _queryRemotePackageVersionOp;
private ESteps _steps = ESteps.None;
private readonly WebPlayModeImpl _impl;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private QueryRemotePackageVersionOperation _queryRemotePackageVersionOp;
private ESteps _steps = ESteps.None;
internal WebPlayModeUpdatePackageVersionOperation(WebPlayModeImpl impl, bool appendTimeTicks, int timeout)
{
_impl = impl;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.QueryRemotePackageVersion;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
internal WebPlayModeUpdatePackageVersionOperation(WebPlayModeImpl impl, bool appendTimeTicks, int timeout)
{
_impl = impl;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalOnStart()
{
_steps = ESteps.QueryRemotePackageVersion;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.QueryRemotePackageVersion)
{
if (_queryRemotePackageVersionOp == null)
{
_queryRemotePackageVersionOp = new QueryRemotePackageVersionOperation(_impl.RemoteServices, _impl.PackageName, _appendTimeTicks, _timeout);
OperationSystem.StartOperation(_impl.PackageName, _queryRemotePackageVersionOp);
}
if (_steps == ESteps.QueryRemotePackageVersion)
{
if (_queryRemotePackageVersionOp == null)
{
_queryRemotePackageVersionOp = new QueryRemotePackageVersionOperation(_impl.RemoteServices, _impl.PackageName, _appendTimeTicks, _timeout);
OperationSystem.StartOperation(_impl.PackageName, _queryRemotePackageVersionOp);
}
if (_queryRemotePackageVersionOp.IsDone == false)
return;
if (_queryRemotePackageVersionOp.IsDone == false)
return;
if (_queryRemotePackageVersionOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _queryRemotePackageVersionOp.PackageVersion;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _queryRemotePackageVersionOp.Error;
}
}
}
}
if (_queryRemotePackageVersionOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _queryRemotePackageVersionOp.PackageVersion;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _queryRemotePackageVersionOp.Error;
}
}
}
}
}

View File

@ -3,50 +3,50 @@ using System.Linq;
namespace YooAsset
{
[Serializable]
internal class PackageAsset
{
/// <summary>
/// 可寻址地址
/// </summary>
public string Address;
[Serializable]
internal class PackageAsset
{
/// <summary>
/// 可寻址地址
/// </summary>
public string Address;
/// <summary>
/// 资源路径
/// </summary>
public string AssetPath;
/// <summary>
/// 资源路径
/// </summary>
public string AssetPath;
/// <summary>
/// 资源GUID
/// </summary>
public string AssetGUID;
/// <summary>
/// 资源GUID
/// </summary>
public string AssetGUID;
/// <summary>
/// 资源的分类标签
/// </summary>
public string[] AssetTags;
/// <summary>
/// 资源的分类标签
/// </summary>
public string[] AssetTags;
/// <summary>
/// 所属资源包ID
/// </summary>
public int BundleID;
/// <summary>
/// 所属资源包ID
/// </summary>
public int BundleID;
/// <summary>
/// 是否包含Tag
/// </summary>
public bool HasTag(string[] tags)
{
if (tags == null || tags.Length == 0)
return false;
if (AssetTags == null || AssetTags.Length == 0)
return false;
/// <summary>
/// 是否包含Tag
/// </summary>
public bool HasTag(string[] tags)
{
if (tags == null || tags.Length == 0)
return false;
if (AssetTags == null || AssetTags.Length == 0)
return false;
foreach (var tag in tags)
{
if (AssetTags.Contains(tag))
return true;
}
return false;
}
}
foreach (var tag in tags)
{
if (AssetTags.Contains(tag))
return true;
}
return false;
}
}
}

View File

@ -3,150 +3,150 @@ using System.Linq;
namespace YooAsset
{
[Serializable]
internal class PackageBundle
{
/// <summary>
/// 资源包名称
/// </summary>
public string BundleName;
[Serializable]
internal class PackageBundle
{
/// <summary>
/// 资源包名称
/// </summary>
public string BundleName;
/// <summary>
/// Unity引擎生成的CRC
/// </summary>
public uint UnityCRC;
/// <summary>
/// Unity引擎生成的CRC
/// </summary>
public uint UnityCRC;
/// <summary>
/// 文件哈希值
/// </summary>
public string FileHash;
/// <summary>
/// 文件哈希值
/// </summary>
public string FileHash;
/// <summary>
/// 文件校验码
/// </summary>
public string FileCRC;
/// <summary>
/// 文件校验码
/// </summary>
public string FileCRC;
/// <summary>
/// 文件大小(字节数)
/// </summary>
public long FileSize;
/// <summary>
/// 文件大小(字节数)
/// </summary>
public long FileSize;
/// <summary>
/// 文件是否加密
/// </summary>
public bool Encrypted;
/// <summary>
/// 文件是否加密
/// </summary>
public bool Encrypted;
/// <summary>
/// 资源包的分类标签
/// </summary>
public string[] Tags;
/// <summary>
/// 资源包的分类标签
/// </summary>
public string[] Tags;
/// <summary>
/// 依赖的资源包ID集合
/// </summary>
public int[] DependIDs;
/// <summary>
/// 依赖的资源包ID集合
/// </summary>
public int[] DependIDs;
/// <summary>
/// 所属的包裹名称
/// </summary>
public string PackageName { private set; get; }
/// <summary>
/// 所属的包裹名称
/// </summary>
public string PackageName { private set; get; }
/// <summary>
/// 所属的构建管线
/// </summary>
public string Buildpipeline { private set; get; }
/// <summary>
/// 所属的构建管线
/// </summary>
public string Buildpipeline { private set; get; }
/// <summary>
/// 缓存GUID
/// </summary>
public string CacheGUID
{
get { return FileHash; }
}
/// <summary>
/// 缓存GUID
/// </summary>
public string CacheGUID
{
get { return FileHash; }
}
/// <summary>
/// 文件名称
/// </summary>
private string _fileName;
public string FileName
{
get
{
if (string.IsNullOrEmpty(_fileName))
throw new Exception("Should never get here !");
return _fileName;
}
}
/// <summary>
/// 文件名称
/// </summary>
private string _fileName;
public string FileName
{
get
{
if (string.IsNullOrEmpty(_fileName))
throw new Exception("Should never get here !");
return _fileName;
}
}
/// <summary>
/// 文件后缀名
/// </summary>
private string _fileExtension;
public string FileExtension
{
get
{
if (string.IsNullOrEmpty(_fileExtension))
throw new Exception("Should never get here !");
return _fileExtension;
}
}
/// <summary>
/// 文件后缀名
/// </summary>
private string _fileExtension;
public string FileExtension
{
get
{
if (string.IsNullOrEmpty(_fileExtension))
throw new Exception("Should never get here !");
return _fileExtension;
}
}
public PackageBundle()
{
}
public PackageBundle()
{
}
/// <summary>
/// 解析资源包
/// </summary>
public void ParseBundle(PackageManifest manifest)
{
PackageName = manifest.PackageName;
Buildpipeline = manifest.BuildPipeline;
_fileExtension = ManifestTools.GetRemoteBundleFileExtension(BundleName);
_fileName = ManifestTools.GetRemoteBundleFileName(manifest.OutputNameStyle, BundleName, _fileExtension, FileHash);
}
/// <summary>
/// 解析资源包
/// </summary>
public void ParseBundle(PackageManifest manifest)
{
PackageName = manifest.PackageName;
Buildpipeline = manifest.BuildPipeline;
_fileExtension = ManifestTools.GetRemoteBundleFileExtension(BundleName);
_fileName = ManifestTools.GetRemoteBundleFileName(manifest.OutputNameStyle, BundleName, _fileExtension, FileHash);
}
/// <summary>
/// 是否包含Tag
/// </summary>
public bool HasTag(string[] tags)
{
if (tags == null || tags.Length == 0)
return false;
if (Tags == null || Tags.Length == 0)
return false;
/// <summary>
/// 是否包含Tag
/// </summary>
public bool HasTag(string[] tags)
{
if (tags == null || tags.Length == 0)
return false;
if (Tags == null || Tags.Length == 0)
return false;
foreach (var tag in tags)
{
if (Tags.Contains(tag))
return true;
}
return false;
}
foreach (var tag in tags)
{
if (Tags.Contains(tag))
return true;
}
return false;
}
/// <summary>
/// 是否包含任意Tags
/// </summary>
public bool HasAnyTags()
{
if (Tags != null && Tags.Length > 0)
return true;
else
return false;
}
/// <summary>
/// 是否包含任意Tags
/// </summary>
public bool HasAnyTags()
{
if (Tags != null && Tags.Length > 0)
return true;
else
return false;
}
/// <summary>
/// 检测资源包文件内容是否相同
/// </summary>
public bool Equals(PackageBundle otherBundle)
{
if (FileHash == otherBundle.FileHash)
return true;
/// <summary>
/// 检测资源包文件内容是否相同
/// </summary>
public bool Equals(PackageBundle otherBundle)
{
if (FileHash == otherBundle.FileHash)
return true;
return false;
}
}
return false;
}
}
}

View File

@ -6,347 +6,347 @@ using System.Collections.Generic;
namespace YooAsset
{
/// <summary>
/// 清单文件
/// </summary>
[Serializable]
internal class PackageManifest
{
/// <summary>
/// 文件版本
/// </summary>
public string FileVersion;
/// <summary>
/// 清单文件
/// </summary>
[Serializable]
internal class PackageManifest
{
/// <summary>
/// 文件版本
/// </summary>
public string FileVersion;
/// <summary>
/// 启用可寻址资源定位
/// </summary>
public bool EnableAddressable;
/// <summary>
/// 启用可寻址资源定位
/// </summary>
public bool EnableAddressable;
/// <summary>
/// 资源定位地址大小写不敏感
/// </summary>
public bool LocationToLower;
/// <summary>
/// 资源定位地址大小写不敏感
/// </summary>
public bool LocationToLower;
/// <summary>
/// 包含资源GUID数据
/// </summary>
public bool IncludeAssetGUID;
/// <summary>
/// 包含资源GUID数据
/// </summary>
public bool IncludeAssetGUID;
/// <summary>
/// 文件名称样式
/// </summary>
public int OutputNameStyle;
/// <summary>
/// 文件名称样式
/// </summary>
public int OutputNameStyle;
/// <summary>
/// 构建管线名称
/// </summary>
public string BuildPipeline;
/// <summary>
/// 构建管线名称
/// </summary>
public string BuildPipeline;
/// <summary>
/// 资源包裹名称
/// </summary>
public string PackageName;
/// <summary>
/// 资源包裹名称
/// </summary>
public string PackageName;
/// <summary>
/// 资源包裹的版本信息
/// </summary>
public string PackageVersion;
/// <summary>
/// 资源包裹的版本信息
/// </summary>
public string PackageVersion;
/// <summary>
/// 资源列表(主动收集的资源列表)
/// </summary>
public List<PackageAsset> AssetList = new List<PackageAsset>();
/// <summary>
/// 资源列表(主动收集的资源列表)
/// </summary>
public List<PackageAsset> AssetList = new List<PackageAsset>();
/// <summary>
/// 资源包列表
/// </summary>
public List<PackageBundle> BundleList = new List<PackageBundle>();
/// <summary>
/// 资源包列表
/// </summary>
public List<PackageBundle> BundleList = new List<PackageBundle>();
/// <summary>
/// 资源包集合提供BundleName获取PackageBundle
/// </summary>
[NonSerialized]
public Dictionary<string, PackageBundle> BundleDic1;
/// <summary>
/// 资源包集合提供BundleName获取PackageBundle
/// </summary>
[NonSerialized]
public Dictionary<string, PackageBundle> BundleDic1;
/// <summary>
/// 资源包集合提供FileName获取PackageBundle
/// </summary>
[NonSerialized]
public Dictionary<string, PackageBundle> BundleDic2;
/// <summary>
/// 资源包集合提供FileName获取PackageBundle
/// </summary>
[NonSerialized]
public Dictionary<string, PackageBundle> BundleDic2;
/// <summary>
/// 资源映射集合提供AssetPath获取PackageAsset
/// </summary>
[NonSerialized]
public Dictionary<string, PackageAsset> AssetDic;
/// <summary>
/// 资源映射集合提供AssetPath获取PackageAsset
/// </summary>
[NonSerialized]
public Dictionary<string, PackageAsset> AssetDic;
/// <summary>
/// 资源路径映射集合提供Location获取AssetPath
/// </summary>
[NonSerialized]
public Dictionary<string, string> AssetPathMapping1;
/// <summary>
/// 资源路径映射集合提供Location获取AssetPath
/// </summary>
[NonSerialized]
public Dictionary<string, string> AssetPathMapping1;
/// <summary>
/// 资源路径映射集合提供AssetGUID获取AssetPath
/// </summary>
[NonSerialized]
public Dictionary<string, string> AssetPathMapping2;
/// <summary>
/// 资源路径映射集合提供AssetGUID获取AssetPath
/// </summary>
[NonSerialized]
public Dictionary<string, string> AssetPathMapping2;
/// <summary>
/// 该资源清单所有文件的缓存GUID集合
/// </summary>
[NonSerialized]
public HashSet<string> CacheGUIDs = new HashSet<string>();
/// <summary>
/// 该资源清单所有文件的缓存GUID集合
/// </summary>
[NonSerialized]
public HashSet<string> CacheGUIDs = new HashSet<string>();
/// <summary>
/// 尝试映射为资源路径
/// </summary>
public string TryMappingToAssetPath(string location)
{
if (string.IsNullOrEmpty(location))
return string.Empty;
/// <summary>
/// 尝试映射为资源路径
/// </summary>
public string TryMappingToAssetPath(string location)
{
if (string.IsNullOrEmpty(location))
return string.Empty;
if (LocationToLower)
location = location.ToLower();
if (LocationToLower)
location = location.ToLower();
if (AssetPathMapping1.TryGetValue(location, out string assetPath))
return assetPath;
else
return string.Empty;
}
if (AssetPathMapping1.TryGetValue(location, out string assetPath))
return assetPath;
else
return string.Empty;
}
/// <summary>
/// 获取主资源包
/// 注意:传入的资源路径一定合法有效!
/// </summary>
public PackageBundle GetMainPackageBundle(string assetPath)
{
if (AssetDic.TryGetValue(assetPath, out PackageAsset packageAsset))
{
int bundleID = packageAsset.BundleID;
if (bundleID >= 0 && bundleID < BundleList.Count)
{
var packageBundle = BundleList[bundleID];
return packageBundle;
}
else
{
throw new Exception($"Invalid bundle id : {bundleID} Asset path : {assetPath}");
}
}
else
{
throw new Exception("Should never get here !");
}
}
/// <summary>
/// 获取主资源包
/// 注意:传入的资源路径一定合法有效!
/// </summary>
public PackageBundle GetMainPackageBundle(string assetPath)
{
if (AssetDic.TryGetValue(assetPath, out PackageAsset packageAsset))
{
int bundleID = packageAsset.BundleID;
if (bundleID >= 0 && bundleID < BundleList.Count)
{
var packageBundle = BundleList[bundleID];
return packageBundle;
}
else
{
throw new Exception($"Invalid bundle id : {bundleID} Asset path : {assetPath}");
}
}
else
{
throw new Exception("Should never get here !");
}
}
/// <summary>
/// 获取资源依赖列表
/// 注意:传入的资源路径一定合法有效!
/// </summary>
public PackageBundle[] GetAllDependencies(string assetPath)
{
var packageBundle = GetMainPackageBundle(assetPath);
List<PackageBundle> result = new List<PackageBundle>(packageBundle.DependIDs.Length);
foreach (var dependID in packageBundle.DependIDs)
{
if (dependID >= 0 && dependID < BundleList.Count)
{
var dependBundle = BundleList[dependID];
result.Add(dependBundle);
}
else
{
throw new Exception($"Invalid bundle id : {dependID} Asset path : {assetPath}");
}
}
return result.ToArray();
}
/// <summary>
/// 获取资源依赖列表
/// 注意:传入的资源路径一定合法有效!
/// </summary>
public PackageBundle[] GetAllDependencies(string assetPath)
{
var packageBundle = GetMainPackageBundle(assetPath);
List<PackageBundle> result = new List<PackageBundle>(packageBundle.DependIDs.Length);
foreach (var dependID in packageBundle.DependIDs)
{
if (dependID >= 0 && dependID < BundleList.Count)
{
var dependBundle = BundleList[dependID];
result.Add(dependBundle);
}
else
{
throw new Exception($"Invalid bundle id : {dependID} Asset path : {assetPath}");
}
}
return result.ToArray();
}
/// <summary>
/// 尝试获取包裹的资源
/// </summary>
public bool TryGetPackageAsset(string assetPath, out PackageAsset result)
{
return AssetDic.TryGetValue(assetPath, out result);
}
/// <summary>
/// 尝试获取包裹的资源
/// </summary>
public bool TryGetPackageAsset(string assetPath, out PackageAsset result)
{
return AssetDic.TryGetValue(assetPath, out result);
}
/// <summary>
/// 尝试获取包裹的资源包
/// </summary>
public bool TryGetPackageBundleByBundleName(string bundleName, out PackageBundle result)
{
return BundleDic1.TryGetValue(bundleName, out result);
}
/// <summary>
/// 尝试获取包裹的资源包
/// </summary>
public bool TryGetPackageBundleByBundleName(string bundleName, out PackageBundle result)
{
return BundleDic1.TryGetValue(bundleName, out result);
}
/// <summary>
/// 尝试获取包裹的资源包
/// </summary>
public bool TryGetPackageBundleByFileName(string fileName, out PackageBundle result)
{
return BundleDic2.TryGetValue(fileName, out result);
}
/// <summary>
/// 尝试获取包裹的资源包
/// </summary>
public bool TryGetPackageBundleByFileName(string fileName, out PackageBundle result)
{
return BundleDic2.TryGetValue(fileName, out result);
}
/// <summary>
/// 是否包含资源文件
/// </summary>
public bool IsIncludeBundleFile(string cacheGUID)
{
return CacheGUIDs.Contains(cacheGUID);
}
/// <summary>
/// 是否包含资源文件
/// </summary>
public bool IsIncludeBundleFile(string cacheGUID)
{
return CacheGUIDs.Contains(cacheGUID);
}
/// <summary>
/// 获取资源信息列表
/// </summary>
public AssetInfo[] GetAssetsInfoByTags(string[] tags)
{
List<AssetInfo> result = new List<AssetInfo>(100);
foreach (var packageAsset in AssetList)
{
if (packageAsset.HasTag(tags))
{
AssetInfo assetInfo = new AssetInfo(PackageName, packageAsset, null);
result.Add(assetInfo);
}
}
return result.ToArray();
}
/// <summary>
/// 获取资源信息列表
/// </summary>
public AssetInfo[] GetAssetsInfoByTags(string[] tags)
{
List<AssetInfo> result = new List<AssetInfo>(100);
foreach (var packageAsset in AssetList)
{
if (packageAsset.HasTag(tags))
{
AssetInfo assetInfo = new AssetInfo(PackageName, packageAsset, null);
result.Add(assetInfo);
}
}
return result.ToArray();
}
/// <summary>
/// 资源定位地址转换为资源信息。
/// </summary>
/// <returns>如果转换失败会返回一个无效的资源信息类</returns>
public AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType)
{
DebugCheckLocation(location);
/// <summary>
/// 资源定位地址转换为资源信息。
/// </summary>
/// <returns>如果转换失败会返回一个无效的资源信息类</returns>
public AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType)
{
DebugCheckLocation(location);
string assetPath = ConvertLocationToAssetInfoMapping(location);
if (TryGetPackageAsset(assetPath, out PackageAsset packageAsset))
{
AssetInfo assetInfo = new AssetInfo(PackageName, packageAsset, assetType);
return assetInfo;
}
else
{
string error;
if (string.IsNullOrEmpty(location))
error = $"The location is null or empty !";
else
error = $"The location is invalid : {location}";
AssetInfo assetInfo = new AssetInfo(PackageName, error);
return assetInfo;
}
}
private string ConvertLocationToAssetInfoMapping(string location)
{
if (string.IsNullOrEmpty(location))
{
YooLogger.Error("Failed to mapping location to asset path, The location is null or empty.");
return string.Empty;
}
string assetPath = ConvertLocationToAssetInfoMapping(location);
if (TryGetPackageAsset(assetPath, out PackageAsset packageAsset))
{
AssetInfo assetInfo = new AssetInfo(PackageName, packageAsset, assetType);
return assetInfo;
}
else
{
string error;
if (string.IsNullOrEmpty(location))
error = $"The location is null or empty !";
else
error = $"The location is invalid : {location}";
AssetInfo assetInfo = new AssetInfo(PackageName, error);
return assetInfo;
}
}
private string ConvertLocationToAssetInfoMapping(string location)
{
if (string.IsNullOrEmpty(location))
{
YooLogger.Error("Failed to mapping location to asset path, The location is null or empty.");
return string.Empty;
}
if (LocationToLower)
location = location.ToLower();
if (LocationToLower)
location = location.ToLower();
if (AssetPathMapping1.TryGetValue(location, out string assetPath))
{
return assetPath;
}
else
{
YooLogger.Warning($"Failed to mapping location to asset path : {location}");
return string.Empty;
}
}
if (AssetPathMapping1.TryGetValue(location, out string assetPath))
{
return assetPath;
}
else
{
YooLogger.Warning($"Failed to mapping location to asset path : {location}");
return string.Empty;
}
}
/// <summary>
/// 资源GUID转换为资源信息。
/// </summary>
/// <returns>如果转换失败会返回一个无效的资源信息类</returns>
public AssetInfo ConvertAssetGUIDToAssetInfo(string assetGUID, System.Type assetType)
{
if (IncludeAssetGUID == false)
{
YooLogger.Warning("Package manifest not include asset guid ! Please check asset bundle collector settings.");
AssetInfo assetInfo = new AssetInfo(PackageName, "AssetGUID data is empty !");
return assetInfo;
}
/// <summary>
/// 资源GUID转换为资源信息。
/// </summary>
/// <returns>如果转换失败会返回一个无效的资源信息类</returns>
public AssetInfo ConvertAssetGUIDToAssetInfo(string assetGUID, System.Type assetType)
{
if (IncludeAssetGUID == false)
{
YooLogger.Warning("Package manifest not include asset guid ! Please check asset bundle collector settings.");
AssetInfo assetInfo = new AssetInfo(PackageName, "AssetGUID data is empty !");
return assetInfo;
}
string assetPath = ConvertAssetGUIDToAssetInfoMapping(assetGUID);
if (TryGetPackageAsset(assetPath, out PackageAsset packageAsset))
{
AssetInfo assetInfo = new AssetInfo(PackageName, packageAsset, assetType);
return assetInfo;
}
else
{
string error;
if (string.IsNullOrEmpty(assetGUID))
error = $"The assetGUID is null or empty !";
else
error = $"The assetGUID is invalid : {assetGUID}";
AssetInfo assetInfo = new AssetInfo(PackageName, error);
return assetInfo;
}
}
private string ConvertAssetGUIDToAssetInfoMapping(string assetGUID)
{
if (string.IsNullOrEmpty(assetGUID))
{
YooLogger.Error("Failed to mapping assetGUID to asset path, The assetGUID is null or empty.");
return string.Empty;
}
string assetPath = ConvertAssetGUIDToAssetInfoMapping(assetGUID);
if (TryGetPackageAsset(assetPath, out PackageAsset packageAsset))
{
AssetInfo assetInfo = new AssetInfo(PackageName, packageAsset, assetType);
return assetInfo;
}
else
{
string error;
if (string.IsNullOrEmpty(assetGUID))
error = $"The assetGUID is null or empty !";
else
error = $"The assetGUID is invalid : {assetGUID}";
AssetInfo assetInfo = new AssetInfo(PackageName, error);
return assetInfo;
}
}
private string ConvertAssetGUIDToAssetInfoMapping(string assetGUID)
{
if (string.IsNullOrEmpty(assetGUID))
{
YooLogger.Error("Failed to mapping assetGUID to asset path, The assetGUID is null or empty.");
return string.Empty;
}
if (AssetPathMapping2.TryGetValue(assetGUID, out string assetPath))
{
return assetPath;
}
else
{
YooLogger.Warning($"Failed to mapping assetGUID to asset path : {assetGUID}");
return string.Empty;
}
}
if (AssetPathMapping2.TryGetValue(assetGUID, out string assetPath))
{
return assetPath;
}
else
{
YooLogger.Warning($"Failed to mapping assetGUID to asset path : {assetGUID}");
return string.Empty;
}
}
/// <summary>
/// 获取资源包内的主资源列表
/// </summary>
public string[] GetBundleIncludeAssets(string assetPath)
{
List<string> assetList = new List<string>();
if (TryGetPackageAsset(assetPath, out PackageAsset result))
{
foreach (var packageAsset in AssetList)
{
if (packageAsset.BundleID == result.BundleID)
{
assetList.Add(packageAsset.AssetPath);
}
}
}
return assetList.ToArray();
}
/// <summary>
/// 获取资源包内的主资源列表
/// </summary>
public string[] GetBundleIncludeAssets(string assetPath)
{
List<string> assetList = new List<string>();
if (TryGetPackageAsset(assetPath, out PackageAsset result))
{
foreach (var packageAsset in AssetList)
{
if (packageAsset.BundleID == result.BundleID)
{
assetList.Add(packageAsset.AssetPath);
}
}
}
return assetList.ToArray();
}
#region 调试方法
[Conditional("DEBUG")]
private void DebugCheckLocation(string location)
{
if (string.IsNullOrEmpty(location) == false)
{
// 检查路径末尾是否有空格
int index = location.LastIndexOf(" ");
if (index != -1)
{
if (location.Length == index + 1)
YooLogger.Warning($"Found blank character in location : \"{location}\"");
}
#region 调试方法
[Conditional("DEBUG")]
private void DebugCheckLocation(string location)
{
if (string.IsNullOrEmpty(location) == false)
{
// 检查路径末尾是否有空格
int index = location.LastIndexOf(" ");
if (index != -1)
{
if (location.Length == index + 1)
YooLogger.Warning($"Found blank character in location : \"{location}\"");
}
if (location.IndexOfAny(System.IO.Path.GetInvalidPathChars()) >= 0)
YooLogger.Warning($"Found illegal character in location : \"{location}\"");
}
}
#endregion
}
if (location.IndexOfAny(System.IO.Path.GetInvalidPathChars()) >= 0)
YooLogger.Warning($"Found illegal character in location : \"{location}\"");
}
}
#endregion
}
}

View File

@ -3,41 +3,41 @@ using System.Reflection;
namespace YooAsset
{
public static class EditorSimulateModeHelper
{
private static System.Type _classType;
public static class EditorSimulateModeHelper
{
private static System.Type _classType;
/// <summary>
/// 编辑器下模拟构建清单
/// </summary>
public static string SimulateBuild(string buildPipelineName, string packageName)
{
if (_classType == null)
_classType = Assembly.Load("YooAsset.Editor").GetType("YooAsset.Editor.AssetBundleSimulateBuilder");
/// <summary>
/// 编辑器下模拟构建清单
/// </summary>
public static string SimulateBuild(string buildPipelineName, string packageName)
{
if (_classType == null)
_classType = Assembly.Load("YooAsset.Editor").GetType("YooAsset.Editor.AssetBundleSimulateBuilder");
string manifestFilePath = (string)InvokePublicStaticMethod(_classType, "SimulateBuild", buildPipelineName, packageName);
return manifestFilePath;
}
string manifestFilePath = (string)InvokePublicStaticMethod(_classType, "SimulateBuild", buildPipelineName, packageName);
return manifestFilePath;
}
/// <summary>
/// 编辑器下模拟构建清单
/// </summary>
public static string SimulateBuild(EDefaultBuildPipeline buildPipeline, string packageName)
{
return SimulateBuild(buildPipeline.ToString(), packageName);
}
/// <summary>
/// 编辑器下模拟构建清单
/// </summary>
public static string SimulateBuild(EDefaultBuildPipeline buildPipeline, string packageName)
{
return SimulateBuild(buildPipeline.ToString(), packageName);
}
private static object InvokePublicStaticMethod(System.Type type, string method, params object[] parameters)
{
var methodInfo = type.GetMethod(method, BindingFlags.Public | BindingFlags.Static);
if (methodInfo == null)
{
UnityEngine.Debug.LogError($"{type.FullName} not found method : {method}");
return null;
}
return methodInfo.Invoke(null, parameters);
}
}
private static object InvokePublicStaticMethod(System.Type type, string method, params object[] parameters)
{
var methodInfo = type.GetMethod(method, BindingFlags.Public | BindingFlags.Static);
if (methodInfo == null)
{
UnityEngine.Debug.LogError($"{type.FullName} not found method : {method}");
return null;
}
return methodInfo.Invoke(null, parameters);
}
}
}
#else
namespace YooAsset

View File

@ -4,158 +4,158 @@ using System.Collections.Generic;
namespace YooAsset
{
internal class EditorSimulateModeImpl : IPlayMode, IBundleQuery
{
private PackageManifest _activeManifest;
private ResourceAssist _assist;
internal class EditorSimulateModeImpl : IPlayMode, IBundleQuery
{
private PackageManifest _activeManifest;
private ResourceAssist _assist;
public readonly string PackageName;
public DownloadManager Download
{
get { return _assist.Download; }
}
public readonly string PackageName;
public DownloadManager Download
{
get { return _assist.Download; }
}
public EditorSimulateModeImpl(string packageName)
{
PackageName = packageName;
}
public EditorSimulateModeImpl(string packageName)
{
PackageName = packageName;
}
/// <summary>
/// 异步初始化
/// </summary>
public InitializationOperation InitializeAsync(ResourceAssist assist, string simulateManifestFilePath)
{
_assist = assist;
/// <summary>
/// 异步初始化
/// </summary>
public InitializationOperation InitializeAsync(ResourceAssist assist, string simulateManifestFilePath)
{
_assist = assist;
var operation = new EditorSimulateModeInitializationOperation(this, simulateManifestFilePath);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
var operation = new EditorSimulateModeInitializationOperation(this, simulateManifestFilePath);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
#region IPlayMode接口
public PackageManifest ActiveManifest
{
set
{
_activeManifest = value;
}
get
{
return _activeManifest;
}
}
public void FlushManifestVersionFile()
{
}
#region IPlayMode接口
public PackageManifest ActiveManifest
{
set
{
_activeManifest = value;
}
get
{
return _activeManifest;
}
}
public void FlushManifestVersionFile()
{
}
UpdatePackageVersionOperation IPlayMode.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout)
{
var operation = new EditorPlayModeUpdatePackageVersionOperation();
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion, int timeout)
{
var operation = new EditorPlayModeUpdatePackageManifestOperation();
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
PreDownloadContentOperation IPlayMode.PreDownloadContentAsync(string packageVersion, int timeout)
{
var operation = new EditorPlayModePreDownloadContentOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
UpdatePackageVersionOperation IPlayMode.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout)
{
var operation = new EditorPlayModeUpdatePackageVersionOperation();
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion, int timeout)
{
var operation = new EditorPlayModeUpdatePackageManifestOperation();
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
PreDownloadContentOperation IPlayMode.PreDownloadContentAsync(string packageVersion, int timeout)
{
var operation = new EditorPlayModePreDownloadContentOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceUnpackerOperation.CreateEmptyUnpacker(Download, PackageName, upackingMaxNumber, failedTryAgain, timeout);
}
ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceUnpackerOperation.CreateEmptyUnpacker(Download, PackageName, upackingMaxNumber, failedTryAgain, timeout);
}
ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceUnpackerOperation.CreateEmptyUnpacker(Download, PackageName, upackingMaxNumber, failedTryAgain, timeout);
}
ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceUnpackerOperation.CreateEmptyUnpacker(Download, PackageName, upackingMaxNumber, failedTryAgain, timeout);
}
ResourceImporterOperation IPlayMode.CreateResourceImporterByFilePaths(string[] filePaths, int importerMaxNumber, int failedTryAgain, int timeout)
{
return ResourceImporterOperation.CreateEmptyImporter(Download, PackageName, importerMaxNumber, failedTryAgain, timeout);
}
#endregion
ResourceImporterOperation IPlayMode.CreateResourceImporterByFilePaths(string[] filePaths, int importerMaxNumber, int failedTryAgain, int timeout)
{
return ResourceImporterOperation.CreateEmptyImporter(Download, PackageName, importerMaxNumber, failedTryAgain, timeout);
}
#endregion
#region IBundleQuery接口
private BundleInfo CreateBundleInfo(PackageBundle packageBundle, AssetInfo assetInfo)
{
if (packageBundle == null)
throw new Exception("Should never get here !");
#region IBundleQuery接口
private BundleInfo CreateBundleInfo(PackageBundle packageBundle, AssetInfo assetInfo)
{
if (packageBundle == null)
throw new Exception("Should never get here !");
BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromEditor);
bundleInfo.IncludeAssetsInEditor = _activeManifest.GetBundleIncludeAssets(assetInfo.AssetPath);
return bundleInfo;
}
BundleInfo IBundleQuery.GetMainBundleInfo(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromEditor);
bundleInfo.IncludeAssetsInEditor = _activeManifest.GetBundleIncludeAssets(assetInfo.AssetPath);
return bundleInfo;
}
BundleInfo IBundleQuery.GetMainBundleInfo(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return CreateBundleInfo(packageBundle, assetInfo);
}
BundleInfo[] IBundleQuery.GetDependBundleInfos(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return CreateBundleInfo(packageBundle, assetInfo);
}
BundleInfo[] IBundleQuery.GetDependBundleInfos(AssetInfo assetInfo)
{
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 IBundleQuery.GetMainBundleName(AssetInfo assetInfo)
{
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 IBundleQuery.GetMainBundleName(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return packageBundle.BundleName;
}
string[] IBundleQuery.GetDependBundleNames(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return packageBundle.BundleName;
}
string[] IBundleQuery.GetDependBundleNames(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath);
List<string> result = new List<string>(depends.Length);
foreach (var packageBundle in depends)
{
result.Add(packageBundle.BundleName);
}
return result.ToArray();
}
bool IBundleQuery.ManifestValid()
{
return _activeManifest != null;
}
#endregion
}
// 注意:如果清单里未找到资源包会抛出异常!
var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath);
List<string> result = new List<string>(depends.Length);
foreach (var packageBundle in depends)
{
result.Add(packageBundle.BundleName);
}
return result.ToArray();
}
bool IBundleQuery.ManifestValid()
{
return _activeManifest != null;
}
#endregion
}
}

View File

@ -4,414 +4,414 @@ using System.Collections.Generic;
namespace YooAsset
{
internal class HostPlayModeImpl : IPlayMode, IBundleQuery
{
private PackageManifest _activeManifest;
private ResourceAssist _assist;
private IBuildinQueryServices _buildinQueryServices;
private IDeliveryQueryServices _deliveryQueryServices;
private IRemoteServices _remoteServices;
internal class HostPlayModeImpl : IPlayMode, IBundleQuery
{
private PackageManifest _activeManifest;
private ResourceAssist _assist;
private IBuildinQueryServices _buildinQueryServices;
private IDeliveryQueryServices _deliveryQueryServices;
private IRemoteServices _remoteServices;
public readonly string PackageName;
public DownloadManager Download
{
get { return _assist.Download; }
}
public PersistentManager Persistent
{
get { return _assist.Persistent; }
}
public CacheManager Cache
{
get { return _assist.Cache; }
}
public IRemoteServices RemoteServices
{
get { return _remoteServices; }
}
public readonly string PackageName;
public DownloadManager Download
{
get { return _assist.Download; }
}
public PersistentManager Persistent
{
get { return _assist.Persistent; }
}
public CacheManager Cache
{
get { return _assist.Cache; }
}
public IRemoteServices RemoteServices
{
get { return _remoteServices; }
}
public HostPlayModeImpl(string packageName)
{
PackageName = packageName;
}
public HostPlayModeImpl(string packageName)
{
PackageName = packageName;
}
/// <summary>
/// 异步初始化
/// </summary>
public InitializationOperation InitializeAsync(ResourceAssist assist, IBuildinQueryServices buildinQueryServices, IDeliveryQueryServices deliveryQueryServices, IRemoteServices remoteServices)
{
_assist = assist;
_buildinQueryServices = buildinQueryServices;
_deliveryQueryServices = deliveryQueryServices;
_remoteServices = remoteServices;
/// <summary>
/// 异步初始化
/// </summary>
public InitializationOperation InitializeAsync(ResourceAssist assist, IBuildinQueryServices buildinQueryServices, IDeliveryQueryServices deliveryQueryServices, IRemoteServices remoteServices)
{
_assist = assist;
_buildinQueryServices = buildinQueryServices;
_deliveryQueryServices = deliveryQueryServices;
_remoteServices = remoteServices;
var operation = new HostPlayModeInitializationOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
var operation = new HostPlayModeInitializationOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
// 下载相关
private List<BundleInfo> ConvertToDownloadList(List<PackageBundle> downloadList)
{
List<BundleInfo> result = new List<BundleInfo>(downloadList.Count);
foreach (var packageBundle in downloadList)
{
var bundleInfo = ConvertToDownloadInfo(packageBundle);
result.Add(bundleInfo);
}
return result;
}
private BundleInfo ConvertToDownloadInfo(PackageBundle packageBundle)
{
string remoteMainURL = _remoteServices.GetRemoteMainURL(packageBundle.FileName);
string remoteFallbackURL = _remoteServices.GetRemoteFallbackURL(packageBundle.FileName);
BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromRemote, remoteMainURL, remoteFallbackURL);
return bundleInfo;
}
// 下载相关
private List<BundleInfo> ConvertToDownloadList(List<PackageBundle> downloadList)
{
List<BundleInfo> result = new List<BundleInfo>(downloadList.Count);
foreach (var packageBundle in downloadList)
{
var bundleInfo = ConvertToDownloadInfo(packageBundle);
result.Add(bundleInfo);
}
return result;
}
private BundleInfo ConvertToDownloadInfo(PackageBundle packageBundle)
{
string remoteMainURL = _remoteServices.GetRemoteMainURL(packageBundle.FileName);
string remoteFallbackURL = _remoteServices.GetRemoteFallbackURL(packageBundle.FileName);
BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromRemote, remoteMainURL, remoteFallbackURL);
return bundleInfo;
}
// 查询相关
private bool IsDeliveryPackageBundle(PackageBundle packageBundle)
{
if (_deliveryQueryServices == null)
return false;
return _deliveryQueryServices.Query(PackageName, packageBundle.FileName, packageBundle.FileCRC);
}
private bool IsCachedPackageBundle(PackageBundle packageBundle)
{
return _assist.Cache.IsCached(packageBundle.CacheGUID);
}
private bool IsBuildinPackageBundle(PackageBundle packageBundle)
{
return _buildinQueryServices.Query(PackageName, packageBundle.FileName, packageBundle.FileCRC);
}
// 查询相关
private bool IsDeliveryPackageBundle(PackageBundle packageBundle)
{
if (_deliveryQueryServices == null)
return false;
return _deliveryQueryServices.Query(PackageName, packageBundle.FileName, packageBundle.FileCRC);
}
private bool IsCachedPackageBundle(PackageBundle packageBundle)
{
return _assist.Cache.IsCached(packageBundle.CacheGUID);
}
private bool IsBuildinPackageBundle(PackageBundle packageBundle)
{
return _buildinQueryServices.Query(PackageName, packageBundle.FileName, packageBundle.FileCRC);
}
#region IPlayMode接口
public PackageManifest ActiveManifest
{
set
{
_activeManifest = value;
}
get
{
return _activeManifest;
}
}
public void FlushManifestVersionFile()
{
if (_activeManifest != null)
{
_assist.Persistent.SaveSandboxPackageVersionFile(_activeManifest.PackageVersion);
}
}
#region IPlayMode接口
public PackageManifest ActiveManifest
{
set
{
_activeManifest = value;
}
get
{
return _activeManifest;
}
}
public void FlushManifestVersionFile()
{
if (_activeManifest != null)
{
_assist.Persistent.SaveSandboxPackageVersionFile(_activeManifest.PackageVersion);
}
}
UpdatePackageVersionOperation IPlayMode.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout)
{
var operation = new HostPlayModeUpdatePackageVersionOperation(this, appendTimeTicks, timeout);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion, int timeout)
{
var operation = new HostPlayModeUpdatePackageManifestOperation(this, packageVersion, autoSaveVersion, timeout);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
PreDownloadContentOperation IPlayMode.PreDownloadContentAsync(string packageVersion, int timeout)
{
var operation = new HostPlayModePreDownloadContentOperation(this, packageVersion, timeout);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
UpdatePackageVersionOperation IPlayMode.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout)
{
var operation = new HostPlayModeUpdatePackageVersionOperation(this, appendTimeTicks, timeout);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion, int timeout)
{
var operation = new HostPlayModeUpdatePackageManifestOperation(this, packageVersion, autoSaveVersion, timeout);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
PreDownloadContentOperation IPlayMode.PreDownloadContentAsync(string packageVersion, int timeout)
{
var operation = new HostPlayModePreDownloadContentOperation(this, packageVersion, timeout);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> downloadList = GetDownloadListByAll(_activeManifest);
var operation = new ResourceDownloaderOperation(Download, PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
public List<BundleInfo> GetDownloadListByAll(PackageManifest manifest)
{
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in manifest.BundleList)
{
// 忽略分发文件
if (IsDeliveryPackageBundle(packageBundle))
continue;
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> downloadList = GetDownloadListByAll(_activeManifest);
var operation = new ResourceDownloaderOperation(Download, PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
public List<BundleInfo> GetDownloadListByAll(PackageManifest manifest)
{
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in manifest.BundleList)
{
// 忽略分发文件
if (IsDeliveryPackageBundle(packageBundle))
continue;
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
// 忽略APP资源
if (IsBuildinPackageBundle(packageBundle))
continue;
// 忽略APP资源
if (IsBuildinPackageBundle(packageBundle))
continue;
downloadList.Add(packageBundle);
}
downloadList.Add(packageBundle);
}
return ConvertToDownloadList(downloadList);
}
return ConvertToDownloadList(downloadList);
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> downloadList = GetDownloadListByTags(_activeManifest, tags);
var operation = new ResourceDownloaderOperation(Download, PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
public List<BundleInfo> GetDownloadListByTags(PackageManifest manifest, string[] tags)
{
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in manifest.BundleList)
{
// 忽略分发文件
if (IsDeliveryPackageBundle(packageBundle))
continue;
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> downloadList = GetDownloadListByTags(_activeManifest, tags);
var operation = new ResourceDownloaderOperation(Download, PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
public List<BundleInfo> GetDownloadListByTags(PackageManifest manifest, string[] tags)
{
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in manifest.BundleList)
{
// 忽略分发文件
if (IsDeliveryPackageBundle(packageBundle))
continue;
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
// 忽略APP资源
if (IsBuildinPackageBundle(packageBundle))
continue;
// 忽略APP资源
if (IsBuildinPackageBundle(packageBundle))
continue;
// 如果未带任何标记,则统一下载
if (packageBundle.HasAnyTags() == false)
{
downloadList.Add(packageBundle);
}
else
{
// 查询DLC资源
if (packageBundle.HasTag(tags))
{
downloadList.Add(packageBundle);
}
}
}
// 如果未带任何标记,则统一下载
if (packageBundle.HasAnyTags() == false)
{
downloadList.Add(packageBundle);
}
else
{
// 查询DLC资源
if (packageBundle.HasTag(tags))
{
downloadList.Add(packageBundle);
}
}
}
return ConvertToDownloadList(downloadList);
}
return ConvertToDownloadList(downloadList);
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> downloadList = GetDownloadListByPaths(_activeManifest, assetInfos);
var operation = new ResourceDownloaderOperation(Download, PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
public List<BundleInfo> GetDownloadListByPaths(PackageManifest manifest, AssetInfo[] assetInfos)
{
// 获取资源对象的资源包和所有依赖资源包
List<PackageBundle> checkList = new List<PackageBundle>();
foreach (var assetInfo in assetInfos)
{
if (assetInfo.IsInvalid)
{
YooLogger.Warning(assetInfo.Error);
continue;
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> downloadList = GetDownloadListByPaths(_activeManifest, assetInfos);
var operation = new ResourceDownloaderOperation(Download, PackageName, downloadList, downloadingMaxNumber, failedTryAgain, timeout);
return operation;
}
public List<BundleInfo> GetDownloadListByPaths(PackageManifest manifest, AssetInfo[] assetInfos)
{
// 获取资源对象的资源包和所有依赖资源包
List<PackageBundle> checkList = new List<PackageBundle>();
foreach (var assetInfo in assetInfos)
{
if (assetInfo.IsInvalid)
{
YooLogger.Warning(assetInfo.Error);
continue;
}
// 注意:如果清单里未找到资源包会抛出异常!
PackageBundle mainBundle = manifest.GetMainPackageBundle(assetInfo.AssetPath);
if (checkList.Contains(mainBundle) == false)
checkList.Add(mainBundle);
// 注意:如果清单里未找到资源包会抛出异常!
PackageBundle mainBundle = manifest.GetMainPackageBundle(assetInfo.AssetPath);
if (checkList.Contains(mainBundle) == false)
checkList.Add(mainBundle);
// 注意:如果清单里未找到资源包会抛出异常!
PackageBundle[] dependBundles = manifest.GetAllDependencies(assetInfo.AssetPath);
foreach (var dependBundle in dependBundles)
{
if (checkList.Contains(dependBundle) == false)
checkList.Add(dependBundle);
}
}
// 注意:如果清单里未找到资源包会抛出异常!
PackageBundle[] dependBundles = manifest.GetAllDependencies(assetInfo.AssetPath);
foreach (var dependBundle in dependBundles)
{
if (checkList.Contains(dependBundle) == false)
checkList.Add(dependBundle);
}
}
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in checkList)
{
// 忽略分发文件
if (IsDeliveryPackageBundle(packageBundle))
continue;
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in checkList)
{
// 忽略分发文件
if (IsDeliveryPackageBundle(packageBundle))
continue;
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
// 忽略APP资源
if (IsBuildinPackageBundle(packageBundle))
continue;
// 忽略APP资源
if (IsBuildinPackageBundle(packageBundle))
continue;
downloadList.Add(packageBundle);
}
downloadList.Add(packageBundle);
}
return ConvertToDownloadList(downloadList);
}
return ConvertToDownloadList(downloadList);
}
ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> unpcakList = GetUnpackListByAll(_activeManifest);
var operation = new ResourceUnpackerOperation(Download, PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout);
return operation;
}
private List<BundleInfo> GetUnpackListByAll(PackageManifest manifest)
{
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in manifest.BundleList)
{
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> unpcakList = GetUnpackListByAll(_activeManifest);
var operation = new ResourceUnpackerOperation(Download, PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout);
return operation;
}
private List<BundleInfo> GetUnpackListByAll(PackageManifest manifest)
{
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in manifest.BundleList)
{
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
if (IsBuildinPackageBundle(packageBundle))
{
downloadList.Add(packageBundle);
}
}
if (IsBuildinPackageBundle(packageBundle))
{
downloadList.Add(packageBundle);
}
}
return BundleInfo.CreateUnpackInfos(_assist, downloadList);
}
return BundleInfo.CreateUnpackInfos(_assist, downloadList);
}
ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> unpcakList = GetUnpackListByTags(_activeManifest, tags);
var operation = new ResourceUnpackerOperation(Download, PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout);
return operation;
}
private List<BundleInfo> GetUnpackListByTags(PackageManifest manifest, string[] tags)
{
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in manifest.BundleList)
{
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> unpcakList = GetUnpackListByTags(_activeManifest, tags);
var operation = new ResourceUnpackerOperation(Download, PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout);
return operation;
}
private List<BundleInfo> GetUnpackListByTags(PackageManifest manifest, string[] tags)
{
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in manifest.BundleList)
{
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
// 查询DLC资源
if (IsBuildinPackageBundle(packageBundle))
{
if (packageBundle.HasTag(tags))
{
downloadList.Add(packageBundle);
}
}
}
// 查询DLC资源
if (IsBuildinPackageBundle(packageBundle))
{
if (packageBundle.HasTag(tags))
{
downloadList.Add(packageBundle);
}
}
}
return BundleInfo.CreateUnpackInfos(_assist, downloadList);
}
return BundleInfo.CreateUnpackInfos(_assist, downloadList);
}
ResourceImporterOperation IPlayMode.CreateResourceImporterByFilePaths(string[] filePaths, int importerMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> importerList = GetImporterListByFilePaths(_activeManifest, filePaths);
var operation = new ResourceImporterOperation(Download, PackageName, importerList, importerMaxNumber, failedTryAgain, timeout);
return operation;
}
private List<BundleInfo> GetImporterListByFilePaths(PackageManifest manifest, string[] filePaths)
{
List<BundleInfo> result = new List<BundleInfo>();
foreach (var filePath in filePaths)
{
string fileName = System.IO.Path.GetFileName(filePath);
if (manifest.TryGetPackageBundleByFileName(fileName, out PackageBundle packageBundle))
{
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
ResourceImporterOperation IPlayMode.CreateResourceImporterByFilePaths(string[] filePaths, int importerMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> importerList = GetImporterListByFilePaths(_activeManifest, filePaths);
var operation = new ResourceImporterOperation(Download, PackageName, importerList, importerMaxNumber, failedTryAgain, timeout);
return operation;
}
private List<BundleInfo> GetImporterListByFilePaths(PackageManifest manifest, string[] filePaths)
{
List<BundleInfo> result = new List<BundleInfo>();
foreach (var filePath in filePaths)
{
string fileName = System.IO.Path.GetFileName(filePath);
if (manifest.TryGetPackageBundleByFileName(fileName, out PackageBundle packageBundle))
{
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
var bundleInfo = BundleInfo.CreateImportInfo(_assist, packageBundle, filePath);
result.Add(bundleInfo);
}
else
{
YooLogger.Warning($"Not found package bundle, importer file path : {filePath}");
}
}
return result;
}
#endregion
var bundleInfo = BundleInfo.CreateImportInfo(_assist, packageBundle, filePath);
result.Add(bundleInfo);
}
else
{
YooLogger.Warning($"Not found package bundle, importer file path : {filePath}");
}
}
return result;
}
#endregion
#region IBundleQuery接口
private BundleInfo CreateBundleInfo(PackageBundle packageBundle)
{
if (packageBundle == null)
throw new Exception("Should never get here !");
#region IBundleQuery接口
private BundleInfo CreateBundleInfo(PackageBundle packageBundle)
{
if (packageBundle == null)
throw new Exception("Should never get here !");
// 查询分发资源
if (IsDeliveryPackageBundle(packageBundle))
{
string deliveryFilePath = _deliveryQueryServices.GetFilePath(PackageName, packageBundle.FileName);
BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromDelivery, deliveryFilePath);
return bundleInfo;
}
// 查询分发资源
if (IsDeliveryPackageBundle(packageBundle))
{
string deliveryFilePath = _deliveryQueryServices.GetFilePath(PackageName, packageBundle.FileName);
BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromDelivery, deliveryFilePath);
return bundleInfo;
}
// 查询沙盒资源
if (IsCachedPackageBundle(packageBundle))
{
BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromCache);
return bundleInfo;
}
// 查询沙盒资源
if (IsCachedPackageBundle(packageBundle))
{
BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromCache);
return bundleInfo;
}
// 查询APP资源
if (IsBuildinPackageBundle(packageBundle))
{
BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromStreaming);
return bundleInfo;
}
// 查询APP资源
if (IsBuildinPackageBundle(packageBundle))
{
BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromStreaming);
return bundleInfo;
}
// 从服务端下载
return ConvertToDownloadInfo(packageBundle);
}
BundleInfo IBundleQuery.GetMainBundleInfo(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 从服务端下载
return ConvertToDownloadInfo(packageBundle);
}
BundleInfo IBundleQuery.GetMainBundleInfo(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return CreateBundleInfo(packageBundle);
}
BundleInfo[] IBundleQuery.GetDependBundleInfos(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return CreateBundleInfo(packageBundle);
}
BundleInfo[] IBundleQuery.GetDependBundleInfos(AssetInfo assetInfo)
{
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);
result.Add(bundleInfo);
}
return result.ToArray();
}
string IBundleQuery.GetMainBundleName(AssetInfo assetInfo)
{
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);
result.Add(bundleInfo);
}
return result.ToArray();
}
string IBundleQuery.GetMainBundleName(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return packageBundle.BundleName;
}
string[] IBundleQuery.GetDependBundleNames(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return packageBundle.BundleName;
}
string[] IBundleQuery.GetDependBundleNames(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath);
List<string> result = new List<string>(depends.Length);
foreach (var packageBundle in depends)
{
result.Add(packageBundle.BundleName);
}
return result.ToArray();
}
bool IBundleQuery.ManifestValid()
{
return _activeManifest != null;
}
#endregion
}
// 注意:如果清单里未找到资源包会抛出异常!
var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath);
List<string> result = new List<string>(depends.Length);
foreach (var packageBundle in depends)
{
result.Add(packageBundle.BundleName);
}
return result.ToArray();
}
bool IBundleQuery.ManifestValid()
{
return _activeManifest != null;
}
#endregion
}
}

View File

@ -4,243 +4,243 @@ using System.Collections.Generic;
namespace YooAsset
{
internal class OfflinePlayModeImpl : IPlayMode, IBundleQuery
{
private PackageManifest _activeManifest;
private ResourceAssist _assist;
internal class OfflinePlayModeImpl : IPlayMode, IBundleQuery
{
private PackageManifest _activeManifest;
private ResourceAssist _assist;
public readonly string PackageName;
public DownloadManager Download
{
get { return _assist.Download; }
}
public PersistentManager Persistent
{
get { return _assist.Persistent; }
}
public CacheManager Cache
{
get { return _assist.Cache; }
}
public readonly string PackageName;
public DownloadManager Download
{
get { return _assist.Download; }
}
public PersistentManager Persistent
{
get { return _assist.Persistent; }
}
public CacheManager Cache
{
get { return _assist.Cache; }
}
public OfflinePlayModeImpl(string packageName)
{
PackageName = packageName;
}
public OfflinePlayModeImpl(string packageName)
{
PackageName = packageName;
}
/// <summary>
/// 异步初始化
/// </summary>
public InitializationOperation InitializeAsync(ResourceAssist assist)
{
_assist = assist;
/// <summary>
/// 异步初始化
/// </summary>
public InitializationOperation InitializeAsync(ResourceAssist assist)
{
_assist = assist;
var operation = new OfflinePlayModeInitializationOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
var operation = new OfflinePlayModeInitializationOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
// 查询相关
private bool IsCachedPackageBundle(PackageBundle packageBundle)
{
return _assist.Cache.IsCached(packageBundle.CacheGUID);
}
// 查询相关
private bool IsCachedPackageBundle(PackageBundle packageBundle)
{
return _assist.Cache.IsCached(packageBundle.CacheGUID);
}
#region IPlayMode接口
public PackageManifest ActiveManifest
{
set
{
_activeManifest = value;
}
get
{
return _activeManifest;
}
}
public void FlushManifestVersionFile()
{
}
#region IPlayMode接口
public PackageManifest ActiveManifest
{
set
{
_activeManifest = value;
}
get
{
return _activeManifest;
}
}
public void FlushManifestVersionFile()
{
}
UpdatePackageVersionOperation IPlayMode.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout)
{
var operation = new OfflinePlayModeUpdatePackageVersionOperation();
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion, int timeout)
{
var operation = new OfflinePlayModeUpdatePackageManifestOperation();
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
PreDownloadContentOperation IPlayMode.PreDownloadContentAsync(string packageVersion, int timeout)
{
var operation = new OfflinePlayModePreDownloadContentOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
UpdatePackageVersionOperation IPlayMode.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout)
{
var operation = new OfflinePlayModeUpdatePackageVersionOperation();
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
UpdatePackageManifestOperation IPlayMode.UpdatePackageManifestAsync(string packageVersion, bool autoSaveVersion, int timeout)
{
var operation = new OfflinePlayModeUpdatePackageManifestOperation();
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
PreDownloadContentOperation IPlayMode.PreDownloadContentAsync(string packageVersion, int timeout)
{
var operation = new OfflinePlayModePreDownloadContentOperation(this);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
ResourceDownloaderOperation IPlayMode.CreateResourceDownloaderByPaths(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout)
{
return ResourceDownloaderOperation.CreateEmptyDownloader(Download, PackageName, downloadingMaxNumber, failedTryAgain, timeout);
}
ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> unpcakList = GetUnpackListByAll(_activeManifest);
var operation = new ResourceUnpackerOperation(Download, PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout);
return operation;
}
private List<BundleInfo> GetUnpackListByAll(PackageManifest manifest)
{
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in manifest.BundleList)
{
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> unpcakList = GetUnpackListByAll(_activeManifest);
var operation = new ResourceUnpackerOperation(Download, PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout);
return operation;
}
private List<BundleInfo> GetUnpackListByAll(PackageManifest manifest)
{
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in manifest.BundleList)
{
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
downloadList.Add(packageBundle);
}
downloadList.Add(packageBundle);
}
return BundleInfo.CreateUnpackInfos(_assist, downloadList);
}
return BundleInfo.CreateUnpackInfos(_assist, downloadList);
}
ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> unpcakList = GetUnpackListByTags(_activeManifest, tags);
var operation = new ResourceUnpackerOperation(Download, PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout);
return operation;
}
private List<BundleInfo> GetUnpackListByTags(PackageManifest manifest, string[] tags)
{
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in manifest.BundleList)
{
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
ResourceUnpackerOperation IPlayMode.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> unpcakList = GetUnpackListByTags(_activeManifest, tags);
var operation = new ResourceUnpackerOperation(Download, PackageName, unpcakList, upackingMaxNumber, failedTryAgain, timeout);
return operation;
}
private List<BundleInfo> GetUnpackListByTags(PackageManifest manifest, string[] tags)
{
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in manifest.BundleList)
{
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
// 查询DLC资源
if (packageBundle.HasTag(tags))
{
downloadList.Add(packageBundle);
}
}
// 查询DLC资源
if (packageBundle.HasTag(tags))
{
downloadList.Add(packageBundle);
}
}
return BundleInfo.CreateUnpackInfos(_assist, downloadList);
}
return BundleInfo.CreateUnpackInfos(_assist, downloadList);
}
ResourceImporterOperation IPlayMode.CreateResourceImporterByFilePaths(string[] filePaths, int importerMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> importerList = GetImporterListByFilePaths(_activeManifest, filePaths);
var operation = new ResourceImporterOperation(Download, PackageName, importerList, importerMaxNumber, failedTryAgain, timeout);
return operation;
}
private List<BundleInfo> GetImporterListByFilePaths(PackageManifest manifest, string[] filePaths)
{
List<BundleInfo> result = new List<BundleInfo>();
foreach (var filePath in filePaths)
{
string fileName = System.IO.Path.GetFileName(filePath);
if (manifest.TryGetPackageBundleByFileName(fileName, out PackageBundle packageBundle))
{
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
ResourceImporterOperation IPlayMode.CreateResourceImporterByFilePaths(string[] filePaths, int importerMaxNumber, int failedTryAgain, int timeout)
{
List<BundleInfo> importerList = GetImporterListByFilePaths(_activeManifest, filePaths);
var operation = new ResourceImporterOperation(Download, PackageName, importerList, importerMaxNumber, failedTryAgain, timeout);
return operation;
}
private List<BundleInfo> GetImporterListByFilePaths(PackageManifest manifest, string[] filePaths)
{
List<BundleInfo> result = new List<BundleInfo>();
foreach (var filePath in filePaths)
{
string fileName = System.IO.Path.GetFileName(filePath);
if (manifest.TryGetPackageBundleByFileName(fileName, out PackageBundle packageBundle))
{
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
var bundleInfo = BundleInfo.CreateImportInfo(_assist, packageBundle, filePath);
result.Add(bundleInfo);
}
else
{
YooLogger.Warning($"Not found package bundle, importer file path : {filePath}");
}
}
return result;
}
#endregion
var bundleInfo = BundleInfo.CreateImportInfo(_assist, packageBundle, filePath);
result.Add(bundleInfo);
}
else
{
YooLogger.Warning($"Not found package bundle, importer file path : {filePath}");
}
}
return result;
}
#endregion
#region IBundleQuery接口
private BundleInfo CreateBundleInfo(PackageBundle packageBundle)
{
if (packageBundle == null)
throw new Exception("Should never get here !");
#region IBundleQuery接口
private BundleInfo CreateBundleInfo(PackageBundle packageBundle)
{
if (packageBundle == null)
throw new Exception("Should never get here !");
// 查询沙盒资源
if (IsCachedPackageBundle(packageBundle))
{
BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromCache);
return bundleInfo;
}
// 查询沙盒资源
if (IsCachedPackageBundle(packageBundle))
{
BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromCache);
return bundleInfo;
}
// 查询APP资源
{
BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromStreaming);
return bundleInfo;
}
}
BundleInfo IBundleQuery.GetMainBundleInfo(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 查询APP资源
{
BundleInfo bundleInfo = new BundleInfo(_assist, packageBundle, BundleInfo.ELoadMode.LoadFromStreaming);
return bundleInfo;
}
}
BundleInfo IBundleQuery.GetMainBundleInfo(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return CreateBundleInfo(packageBundle);
}
BundleInfo[] IBundleQuery.GetDependBundleInfos(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return CreateBundleInfo(packageBundle);
}
BundleInfo[] IBundleQuery.GetDependBundleInfos(AssetInfo assetInfo)
{
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);
result.Add(bundleInfo);
}
return result.ToArray();
}
string IBundleQuery.GetMainBundleName(AssetInfo assetInfo)
{
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);
result.Add(bundleInfo);
}
return result.ToArray();
}
string IBundleQuery.GetMainBundleName(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return packageBundle.BundleName;
}
string[] IBundleQuery.GetDependBundleNames(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = _activeManifest.GetMainPackageBundle(assetInfo.AssetPath);
return packageBundle.BundleName;
}
string[] IBundleQuery.GetDependBundleNames(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
throw new Exception("Should never get here !");
// 注意:如果清单里未找到资源包会抛出异常!
var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath);
List<string> result = new List<string>(depends.Length);
foreach (var packageBundle in depends)
{
result.Add(packageBundle.BundleName);
}
return result.ToArray();
}
bool IBundleQuery.ManifestValid()
{
return _activeManifest != null;
}
#endregion
}
// 注意:如果清单里未找到资源包会抛出异常!
var depends = _activeManifest.GetAllDependencies(assetInfo.AssetPath);
List<string> result = new List<string>(depends.Length);
foreach (var packageBundle in depends)
{
result.Add(packageBundle.BundleName);
}
return result.ToArray();
}
bool IBundleQuery.ManifestValid()
{
return _activeManifest != null;
}
#endregion
}
}

Some files were not shown because too many files have changed in this diff Show More