| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 | 
							- using System.Collections;
 
- using System.Collections.Generic;
 
- namespace YooAsset
 
- {
 
- 	public abstract class DownloaderOperation : AsyncOperationBase
 
- 	{
 
- 		private enum ESteps
 
- 		{
 
- 			None,
 
- 			Check,
 
- 			Loading,
 
- 			Done,
 
- 		}
 
- 		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);
 
- 		private readonly int _downloadingMaxNumber;
 
- 		private readonly int _failedTryAgain;
 
- 		private readonly int _timeout;
 
- 		private readonly List<BundleInfo> _downloadList;
 
- 		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;
 
- 		
 
- 		/// <summary>
 
- 		/// 统计的下载文件总数量
 
- 		/// </summary>
 
- 		public int TotalDownloadCount { private set; get; }
 
- 		
 
- 		/// <summary>
 
- 		/// 统计的下载文件的总大小
 
- 		/// </summary>
 
- 		public long TotalDownloadBytes { private set; get; }
 
- 		
 
- 		/// <summary>
 
- 		/// 当前已经完成的下载总数量
 
- 		/// </summary>
 
- 		public int CurrentDownloadCount 
 
- 		{
 
- 			get { return _lastDownloadCount; }
 
- 		}
 
- 		/// <summary>
 
- 		/// 当前已经完成的下载总大小
 
- 		/// </summary>
 
- 		public long CurrentDownloadBytes
 
- 		{
 
- 			get { return _lastDownloadBytes; }
 
- 		}
 
- 		/// <summary>
 
- 		/// 当下载器结束(无论成功或失败)
 
- 		/// </summary>
 
- 		public OnDownloadOver OnDownloadOverCallback { set; get; }
 
- 		/// <summary>
 
- 		/// 当下载进度发生变化
 
- 		/// </summary>
 
- 		public OnDownloadProgress OnDownloadProgressCallback { set; get; }
 
- 		/// <summary>
 
- 		/// 当某个文件下载失败
 
- 		/// </summary>
 
- 		public OnDownloadError OnDownloadErrorCallback { set; get; }
 
- 		/// <summary>
 
- 		/// 当开始下载某个文件
 
- 		/// </summary>
 
- 		public OnStartDownloadFile OnStartDownloadFileCallback { set; get; }
 
- 		internal DownloaderOperation(List<BundleInfo> downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout)
 
- 		{
 
- 			_downloadList = downloadList;
 
- 			_downloadingMaxNumber = UnityEngine.Mathf.Clamp(downloadingMaxNumber, 1, MAX_LOADER_COUNT); ;
 
- 			_failedTryAgain = failedTryAgain;
 
- 			_timeout = timeout;
 
- 			if (downloadList != null)
 
- 			{
 
- 				TotalDownloadCount = downloadList.Count;
 
- 				foreach (var packageBundle in downloadList)
 
- 				{
 
- 					TotalDownloadBytes += packageBundle.Bundle.FileSize;
 
- 				}
 
- 			}
 
- 		}
 
- 		internal override void Start()
 
- 		{
 
- 			YooLogger.Log($"Begine to download : {TotalDownloadCount} files and {TotalDownloadBytes} bytes");
 
- 			_steps = ESteps.Check;
 
- 		}
 
- 		internal override void Update()
 
- 		{
 
- 			if (_steps == ESteps.None || _steps == ESteps.Done)
 
- 				return;
 
- 			if (_steps == ESteps.Check)
 
- 			{
 
- 				if (_downloadList == 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;
 
- 					BundleInfo bundleInfo = downloader.GetBundleInfo();
 
- 					// 检测是否下载失败
 
- 					if (downloader.HasError())
 
- 					{
 
- 						_removeList.Add(downloader);
 
- 						_failedList.Add(downloader);
 
- 						continue;
 
- 					}
 
- 					// 下载成功
 
- 					_removeList.Add(downloader);
 
- 					_cachedDownloadCount++;
 
- 					_cachedDownloadBytes += bundleInfo.Bundle.FileSize;
 
- 				}
 
- 				// 移除已经完成的下载器(无论成功或失败)
 
- 				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 (_downloadList.Count > 0 && _failedList.Count == 0)
 
- 				{
 
- 					if (_isPause)
 
- 						return;
 
- 					if (_downloaders.Count < _downloadingMaxNumber)
 
- 					{
 
- 						int index = _downloadList.Count - 1;
 
- 						var bundleInfo = _downloadList[index];
 
- 						var operation = DownloadSystem.BeginDownload(bundleInfo, _failedTryAgain, _timeout);
 
- 						_downloaders.Add(operation);
 
- 						_downloadList.RemoveAt(index);
 
- 						OnStartDownloadFileCallback?.Invoke(bundleInfo.Bundle.BundleName, bundleInfo.Bundle.FileSize);
 
- 					}
 
- 				}
 
- 				// 下载结算
 
- 				if (_downloaders.Count == 0)
 
- 				{
 
- 					if (_failedList.Count > 0)
 
- 					{
 
- 						var failedDownloader = _failedList[0];
 
- 						string fileName = failedDownloader.GetBundleInfo().Bundle.BundleName;
 
- 						_steps = ESteps.Done;
 
- 						Status = EOperationStatus.Failed;
 
- 						Error = $"Failed to download file : {fileName}";
 
- 						OnDownloadErrorCallback?.Invoke(fileName, failedDownloader.GetLastError());
 
- 						OnDownloadOverCallback?.Invoke(false);
 
- 					}
 
- 					else
 
- 					{
 
- 						// 结算成功
 
- 						_steps = ESteps.Done;
 
- 						Status = EOperationStatus.Succeed;
 
- 						OnDownloadOverCallback?.Invoke(true);
 
- 					}
 
- 				}
 
- 			}
 
- 		}
 
- 		/// <summary>
 
- 		/// 开始下载
 
- 		/// </summary>
 
- 		public void BeginDownload()
 
- 		{
 
- 			if (_steps == ESteps.None)
 
- 			{
 
- 				OperationSystem.StartOperation(this);
 
- 			}
 
- 		}
 
- 		/// <summary>
 
- 		/// 暂停下载
 
- 		/// </summary>
 
- 		public void PauseDownload()
 
- 		{
 
- 			_isPause = true;
 
- 		}
 
- 		/// <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.";
 
- 			}
 
- 		}
 
- 	}
 
- 	public sealed class ResourceDownloaderOperation : DownloaderOperation
 
- 	{
 
- 		internal ResourceDownloaderOperation(List<BundleInfo> downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout)
 
- 			: base(downloadList, downloadingMaxNumber, failedTryAgain, timeout)
 
- 		{
 
- 		}
 
- 		/// <summary>
 
- 		/// 创建空的下载器
 
- 		/// </summary>
 
- 		internal static ResourceDownloaderOperation CreateEmptyDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout)
 
- 		{
 
- 			List<BundleInfo> downloadList = new List<BundleInfo>();
 
- 			var operation = new ResourceDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout);
 
- 			return operation;
 
- 		}
 
- 	}
 
- 	public sealed class ResourceUnpackerOperation : DownloaderOperation
 
- 	{
 
- 		internal ResourceUnpackerOperation(List<BundleInfo> downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout)
 
- 			: base(downloadList, downloadingMaxNumber, failedTryAgain, timeout)
 
- 		{
 
- 		}
 
- 		/// <summary>
 
- 		/// 创建空的解压器
 
- 		/// </summary>
 
- 		internal static ResourceUnpackerOperation CreateEmptyUnpacker(int upackingMaxNumber, int failedTryAgain, int timeout)
 
- 		{
 
- 			List<BundleInfo> downloadList = new List<BundleInfo>();
 
- 			var operation = new ResourceUnpackerOperation(downloadList, upackingMaxNumber, failedTryAgain, int.MaxValue);
 
- 			return operation;
 
- 		}
 
- 	}
 
- }
 
 
  |