From 0cdcfe7f522506530bf90f10f5f2eddd383e63b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=BD=95=E5=86=A0=E5=B3=B0?= <hevinci@hotmail.com>
Date: Wed, 26 Feb 2025 19:31:06 +0800
Subject: [PATCH] update file system

---
 .../DefaultCacheFileSystem.cs                 |  5 +-
 .../Operation/DCFSLoadBundleOperation.cs      | 10 +--
 .../internal/DownloadNormalFileOperation.cs   |  6 --
 .../internal/DownloadResumeFileOperation.cs   |  9 +--
 .../Operation/FSDownloadFileOperation.cs      | 12 +++-
 .../Internal/DownloadAssetBundleOperation.cs  |  1 -
 .../Operation/Internal/DownloadFileWrapper.cs | 71 +++++++++++++++++++
 .../Internal/DownloadFileWrapper.cs.meta      | 11 +++
 .../OperationSystem/AsyncOperationBase.cs     |  8 ++-
 .../Operation/DownloaderOperation.cs          |  5 +-
 10 files changed, 114 insertions(+), 24 deletions(-)
 create mode 100644 Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DownloadFileWrapper.cs
 create mode 100644 Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DownloadFileWrapper.cs.meta

diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs
index ddf93e3e..dee8068b 100644
--- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/DefaultCacheFileSystem.cs
@@ -153,7 +153,10 @@ namespace YooAsset
         {
             var downloader = DownloadCenter.DownloadFileAsync(bundle, param);
             downloader.Reference(); //增加下载器的引用计数
-            return downloader;
+
+            // 注意:将下载器进行包裹,可以避免父类任务终止的时候,连带子任务里的下载器也一起被终止!
+            var wrapper = new DownloadFileWrapper(downloader);
+            return wrapper;
         }
         public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle)
         {
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs
index f4651558..b588e0aa 100644
--- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/DCFSLoadBundleOperation.cs
@@ -54,18 +54,19 @@ namespace YooAsset
 
             if (_steps == ESteps.DownloadFile)
             {
-                // 注意:下载的异步任务由管理器驱动
-                // 注意:不加到子任务列表里,防止Abort的时候将下载器直接关闭!
                 // 注意:边玩边下下载器引用计数没有Release
                 if (_downloadFileOp == null)
                 {
                     DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
                     _downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, downloadParam);
+                    _downloadFileOp.StartOperation();
+                    AddChildOperation(_downloadFileOp);
                 }
 
                 if (IsWaitForAsyncComplete)
                     _downloadFileOp.WaitForAsyncComplete();
 
+                _downloadFileOp.UpdateOperation();
                 DownloadProgress = _downloadFileOp.DownloadProgress;
                 DownloadedBytes = _downloadFileOp.DownloadedBytes;
                 if (_downloadFileOp.IsDone == false)
@@ -271,18 +272,19 @@ namespace YooAsset
 
             if (_steps == ESteps.DownloadFile)
             {
-                // 注意:下载的异步任务由管理器驱动
-                // 注意:不加到子任务列表里,防止Abort的时候将下载器直接关闭!
                 // 注意:边玩边下下载器引用计数没有Release
                 if (_downloadFileOp == null)
                 {
                     DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
                     _downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, downloadParam);
+                    _downloadFileOp.StartOperation();
+                    AddChildOperation(_downloadFileOp);
                 }
 
                 if (IsWaitForAsyncComplete)
                     _downloadFileOp.WaitForAsyncComplete();
 
+                _downloadFileOp.UpdateOperation();
                 DownloadProgress = _downloadFileOp.DownloadProgress;
                 DownloadedBytes = _downloadFileOp.DownloadedBytes;
                 if (_downloadFileOp.IsDone == false)
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadNormalFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadNormalFileOperation.cs
index 890ce178..e50210ed 100644
--- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadNormalFileOperation.cs
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadNormalFileOperation.cs
@@ -166,12 +166,6 @@ namespace YooAsset
         }
         internal override void InternalWaitForAsyncComplete()
         {
-            //TODO 防止下载器挂起陷入无限死循环!
-            if (_steps == ESteps.None)
-            {
-                InternalStart();
-            }
-
             while (true)
             {
                 //TODO 如果是导入或解压本地文件,执行等待完毕
diff --git a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadResumeFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadResumeFileOperation.cs
index 2cca18c2..9fab65dc 100644
--- a/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadResumeFileOperation.cs
+++ b/Assets/YooAsset/Runtime/FileSystem/DefaultCacheFileSystem/Operation/internal/DownloadResumeFileOperation.cs
@@ -1,5 +1,4 @@
-using System.Collections.Generic;
-using System.IO;
+using System.IO;
 using UnityEngine;
 using UnityEngine.Networking;
 
@@ -186,12 +185,6 @@ namespace YooAsset
         }
         internal override void InternalWaitForAsyncComplete()
         {
-            //TODO 防止下载器挂起陷入无限死循环!
-            if (_steps == ESteps.None)
-            {
-                InternalStart();
-            }
-
             while (true)
             {
                 //TODO 如果是导入或解压本地文件,执行等待完毕
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/FSDownloadFileOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/FSDownloadFileOperation.cs
index f9fa7e26..b7dad8c6 100644
--- a/Assets/YooAsset/Runtime/FileSystem/Operation/FSDownloadFileOperation.cs
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/FSDownloadFileOperation.cs
@@ -34,11 +34,19 @@ namespace YooAsset
             DownloadedBytes = 0;
             DownloadProgress = 0;
         }
-        public void Release()
+
+        /// <summary>
+        /// 减少引用计数
+        /// </summary>
+        public virtual void Release()
         {
             RefCount--;
         }
-        public void Reference()
+
+        /// <summary>
+        /// 增加引用计数
+        /// </summary>
+        public virtual void Reference()
         {
             RefCount++;
         }
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DownloadAssetBundleOperation.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DownloadAssetBundleOperation.cs
index d5178c12..8c261f79 100644
--- a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DownloadAssetBundleOperation.cs
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DownloadAssetBundleOperation.cs
@@ -1,5 +1,4 @@
 using UnityEngine;
-using UnityEngine.Networking;
 
 namespace YooAsset
 {
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DownloadFileWrapper.cs b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DownloadFileWrapper.cs
new file mode 100644
index 00000000..1df1ab0e
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DownloadFileWrapper.cs
@@ -0,0 +1,71 @@
+
+namespace YooAsset
+{
+    internal class DownloadFileWrapper : FSDownloadFileOperation
+    {
+        private enum ESteps
+        {
+            None,
+            Download,
+            Done,
+        }
+
+        private readonly FSDownloadFileOperation _downloadFileOp;
+        private ESteps _steps = ESteps.None;
+
+        internal DownloadFileWrapper(FSDownloadFileOperation downloadFileOp) : base(downloadFileOp.Bundle)
+        {
+            _downloadFileOp = downloadFileOp;
+        }
+        internal override void InternalStart()
+        {
+            _steps = ESteps.Download;
+        }
+        internal override void InternalUpdate()
+        {
+            if (_steps == ESteps.None || _steps == ESteps.Done)
+                return;
+
+            if (_steps == ESteps.Download)
+            {
+                if (IsWaitForAsyncComplete)
+                    _downloadFileOp.WaitForAsyncComplete();
+
+                if (_downloadFileOp.Status == EOperationStatus.None)
+                    return;
+
+                _downloadFileOp.UpdateOperation();
+                Progress = _downloadFileOp.Progress;
+                DownloadedBytes = _downloadFileOp.DownloadedBytes;
+                DownloadProgress = _downloadFileOp.DownloadProgress;
+                if (_downloadFileOp.IsDone == false)
+                    return;
+
+                _steps = ESteps.Done;
+                Status = _downloadFileOp.Status;
+                Error = _downloadFileOp.Error;
+                HttpCode = _downloadFileOp.HttpCode;
+            }
+        }
+        internal override void InternalWaitForAsyncComplete()
+        {
+            while (true)
+            {
+                if (ExecuteWhileDone())
+                {
+                    _steps = ESteps.Done;
+                    break;
+                }
+            }
+        }
+
+        public override void Release()
+        {
+            _downloadFileOp.Release();
+        }
+        public override void Reference()
+        {
+            _downloadFileOp.Reference();
+        }
+    }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DownloadFileWrapper.cs.meta b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DownloadFileWrapper.cs.meta
new file mode 100644
index 00000000..0964e08d
--- /dev/null
+++ b/Assets/YooAsset/Runtime/FileSystem/Operation/Internal/DownloadFileWrapper.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8088863fc7dfbd441bc897380cd7b97f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs b/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs
index 6456c80e..be1b4706 100644
--- a/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs
+++ b/Assets/YooAsset/Runtime/OperationSystem/AsyncOperationBase.cs
@@ -113,7 +113,6 @@ namespace YooAsset
         /// <summary>
         /// 设置包裹名称
         /// </summary>
-        /// <param name="packageName"></param>
         internal void SetPackageName(string packageName)
         {
             _packageName = packageName;
@@ -224,6 +223,13 @@ namespace YooAsset
             if (IsDone)
                 return;
 
+            //TODO 防止异步操作被挂起陷入无限死循环!
+            // 例如:文件解压任务或者文件导入任务!
+            if (Status == EOperationStatus.None)
+            {
+                StartOperation();
+            }
+
             IsWaitForAsyncComplete = true;
             InternalWaitForAsyncComplete();
         }
diff --git a/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOperation.cs b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOperation.cs
index 9078cb67..3433c7f6 100644
--- a/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOperation.cs
+++ b/Assets/YooAsset/Runtime/ResourcePackage/Operation/DownloaderOperation.cs
@@ -100,7 +100,7 @@ namespace YooAsset
         /// 当开始下载某个文件
         /// </summary>
         public DownloadFileBegin DownloadFileBeginCallback { set; get; }
-        
+
 
         internal DownloaderOperation(string packageName, List<BundleInfo> downloadList, int downloadingMaxNumber, int failedTryAgain, int timeout)
         {
@@ -204,6 +204,9 @@ namespace YooAsset
                         int index = _bundleInfoList.Count - 1;
                         var bundleInfo = _bundleInfoList[index];
                         var downloader = bundleInfo.CreateDownloader(_failedTryAgain, _timeout);
+                        downloader.StartOperation();
+                        this.AddChildOperation(downloader);
+
                         _downloaders.Add(downloader);
                         _bundleInfoList.RemoveAt(index);