internal override void Update()
        {
            if (_steps == ESteps.None || _steps == ESteps.Done)
            {
                return;
            }

            if (_steps == ESteps.InitCache)
            {
                // 每次启动时比对APP版本号是否一致
                CacheData cacheData = CacheData.LoadCache();
                if (cacheData.CacheAppVersion != Application.version)
                {
                    YooLogger.Warning($"Cache is dirty ! Cache application version is {cacheData.CacheAppVersion}, Current application version is {Application.version}");

                    // 注意:在覆盖安装的时候,会保留APP沙盒目录,可以选择清空缓存目录
                    if (_impl.ClearCacheWhenDirty)
                    {
                        YooLogger.Warning("Clear cache files.");
                        SandboxHelper.DeleteCacheFolder();
                    }

                    // 更新缓存文件
                    CacheData.UpdateCache();
                }
                _steps = ESteps.Update;
            }

            if (_steps == ESteps.Update)
            {
                _appManifestLoader.Update();
                Progress = _appManifestLoader.Progress();
                if (_appManifestLoader.IsDone() == false)
                {
                    return;
                }

                if (_appManifestLoader.Result == null)
                {
                    _steps = ESteps.Done;
                    Status = EOperationStatus.Failed;
                    Error  = _appManifestLoader.Error;
                }
                else
                {
                    _steps = ESteps.Done;
                    Status = EOperationStatus.Succeed;
                    _impl.SetAppPatchManifest(_appManifestLoader.Result);
                    _impl.SetLocalPatchManifest(_appManifestLoader.Result);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// 等待异步执行完毕
        /// </summary>
        public void WaitForAsyncComplete()
        {
            IsWaitForAsyncComplete = true;

            // 注意:主动轮询更新完成同步加载
            Update();

            // 验证结果
            if (IsDone == false)
            {
                YooLogger.Warning($"WaitForAsyncComplete failed to loading : {MainAssetInfo.AssetPath}");
            }
        }
Beispiel #3
0
        /// <summary>
        /// 释放操作句柄
        /// </summary>
        public void ReleaseHandle(OperationHandleBase handle)
        {
            if (RefCount <= 0)
            {
                YooLogger.Warning("Asset provider reference count is already zero. There may be resource leaks !");
            }

            if (_handles.Remove(handle) == false)
            {
                throw new System.Exception("Should never get here !");
            }

            // 引用计数减少
            RefCount--;
        }
Beispiel #4
0
        private void VerifyCallback(object obj)
        {
            ThreadInfo info = (ThreadInfo)obj;

            if (info.Result)
            {
                _verifySuccessCount++;
                DownloadSystem.CacheVerifyFile(info.Bundle.Hash, info.Bundle.BundleName);
            }
            else
            {
                _verifyFailCount++;
                YooLogger.Warning($"Failed to verify file : {info.FilePath}");
                if (File.Exists(info.FilePath))
                {
                    File.Delete(info.FilePath);
                }
            }
            _verifyingList.Remove(info.Bundle);
        }
Beispiel #5
0
        private bool UpdateVerifyingCache()
        {
            _syncContext.Update();

            if (_waitingList.Count == 0 && _verifyingList.Count == 0)
            {
                return(true);
            }

            if (_verifyingList.Count >= _verifyMaxNum)
            {
                return(false);
            }

            for (int i = _waitingList.Count - 1; i >= 0; i--)
            {
                if (_verifyingList.Count >= _verifyMaxNum)
                {
                    break;
                }

                var patchBundle = _waitingList[i];
                if (RunThread(patchBundle))
                {
                    _waitingList.RemoveAt(i);
                    _verifyingList.Add(patchBundle);
                }
                else
                {
                    YooLogger.Warning("The thread pool is failed queued.");
                    break;
                }
            }

            return(false);
        }
        public override void Update()
        {
            if (IsDone)
            {
                return;
            }

            if (Status == EStatus.None)
            {
                Status = EStatus.CheckBundle;
            }

            // 1. 检测资源包
            if (Status == EStatus.CheckBundle)
            {
                if (IsWaitForAsyncComplete)
                {
                    DependBundleGroup.WaitForAsyncComplete();
                    OwnerBundle.WaitForAsyncComplete();
                }

                if (DependBundleGroup.IsDone() == false)
                {
                    return;
                }
                if (OwnerBundle.IsDone() == false)
                {
                    return;
                }

                if (DependBundleGroup.IsSucceed() == false)
                {
                    Status    = EStatus.Fail;
                    LastError = DependBundleGroup.GetLastError();
                    InvokeCompletion();
                    return;
                }

                if (OwnerBundle.Status != AssetBundleLoaderBase.EStatus.Succeed)
                {
                    Status    = EStatus.Fail;
                    LastError = OwnerBundle.LastError;
                    InvokeCompletion();
                    return;
                }

                Status = EStatus.Loading;
            }

            // 2. 加载资源对象
            if (Status == EStatus.Loading)
            {
                if (IsWaitForAsyncComplete)
                {
                    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);
                    }
                }
                Status = EStatus.Checking;
            }

            // 3. 检测加载结果
            if (Status == EStatus.Checking)
            {
                if (_cacheRequest != null)
                {
                    if (IsWaitForAsyncComplete)
                    {
                        // 强制挂起主线程(注意:该操作会很耗时)
                        YooLogger.Warning("Suspend the main thread to load unity asset.");
                        AssetObject = _cacheRequest.asset;
                    }
                    else
                    {
                        if (_cacheRequest.isDone == false)
                        {
                            return;
                        }
                        AssetObject = _cacheRequest.asset;
                    }
                }

                Status = AssetObject == null ? EStatus.Fail : EStatus.Success;
                if (Status == EStatus.Fail)
                {
                    if (MainAssetInfo.AssetType == null)
                    {
                        LastError = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.BundleName}";
                    }
                    else
                    {
                        LastError = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.BundleName}";
                    }
                    YooLogger.Error(LastError);
                }
                InvokeCompletion();
            }
        }
Beispiel #7
0
        public override void Update()
        {
            if (_steps == ESteps.None)
            {
                return;
            }
            if (IsDone())
            {
                return;
            }

            if (_steps == ESteps.CreateDownload)
            {
                // 重置变量
                _downloadProgress = 0f;
                _downloadedBytes  = 0;
                _tryAgainTimer    = 0f;

                _requestURL       = GetRequestURL();
                _threadDownloader = new ThreadDownloader();
                _threadDownloader.Run(_requestURL, _bundleInfo.GetCacheLoadPath(), _bundleInfo.Hash, _bundleInfo.CRC, _bundleInfo.SizeBytes, _timeout);
                _steps = ESteps.CheckDownload;
            }

            if (_steps == ESteps.CheckDownload)
            {
                _downloadProgress = _threadDownloader.DownloadProgress;
                _downloadedBytes  = _threadDownloader.DownloadedBytes;
                if (_threadDownloader.IsDone == false)
                {
                    return;
                }

                if (_threadDownloader.HasError())
                {
                    _lastError = _threadDownloader.Error;

                    // 失败后重新尝试
                    if (_failedTryAgain > 0)
                    {
                        ReportWarning();
                        _steps = ESteps.TryAgain;
                    }
                    else
                    {
                        ReportError();
                        _steps = ESteps.Failed;
                    }
                }
                else
                {
                    DownloadSystem.CacheVerifyFile(_bundleInfo.Hash, _bundleInfo.BundleName);
                    _steps = ESteps.Succeed;
                }
            }

            // 重新尝试下载
            if (_steps == ESteps.TryAgain)
            {
                _tryAgainTimer += UnityEngine.Time.unscaledDeltaTime;
                if (_tryAgainTimer > 1f)
                {
                    _failedTryAgain--;
                    _steps = ESteps.CreateDownload;
                    YooLogger.Warning($"Try again download : {_requestURL}");
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// 轮询更新
        /// </summary>
        public override void Update()
        {
            if (_steps == ESteps.Done)
            {
                return;
            }

            if (_steps == ESteps.None)
            {
                if (MainBundleInfo.IsInvalid)
                {
                    _steps    = ESteps.Done;
                    Status    = EStatus.Failed;
                    LastError = $"The bundle info is invalid : {MainBundleInfo.BundleName}";
                    YooLogger.Error(LastError);
                    return;
                }

                if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
                {
                    _steps        = ESteps.Download;
                    _fileLoadPath = MainBundleInfo.GetCacheLoadPath();
                }
                else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
                {
                    _steps        = ESteps.LoadFile;
                    _fileLoadPath = MainBundleInfo.GetStreamingLoadPath();
                }
                else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
                {
                    _steps        = ESteps.LoadFile;
                    _fileLoadPath = MainBundleInfo.GetCacheLoadPath();
                }
                else
                {
                    throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
                }
            }

            // 1. 从服务器下载
            if (_steps == ESteps.Download)
            {
                int failedTryAgain = int.MaxValue;
                _downloader = DownloadSystem.BeginDownload(MainBundleInfo, failedTryAgain);
                _steps      = ESteps.CheckDownload;
            }

            // 2. 检测服务器下载结果
            if (_steps == ESteps.CheckDownload)
            {
                if (_downloader.IsDone() == false)
                {
                    return;
                }

                if (_downloader.HasError())
                {
                    _steps    = ESteps.Done;
                    Status    = EStatus.Failed;
                    LastError = _downloader.GetLastError();
                }
                else
                {
                    _steps = ESteps.LoadFile;
                }
            }

            // 3. 加载AssetBundle
            if (_steps == ESteps.LoadFile)
            {
#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;
                }
#endif

                // Load assetBundle file
                if (MainBundleInfo.IsEncrypted)
                {
                    if (AssetSystem.DecryptionServices == null)
                    {
                        throw new Exception($"{nameof(AssetBundleFileLoader)} need {nameof(IDecryptionServices)} : {MainBundleInfo.BundleName}");
                    }

                    ulong offset = AssetSystem.DecryptionServices.GetFileOffset();
                    if (_isWaitForAsyncComplete)
                    {
                        CacheBundle = AssetBundle.LoadFromFile(_fileLoadPath, 0, offset);
                    }
                    else
                    {
                        _cacheRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath, 0, offset);
                    }
                }
                else
                {
                    if (_isWaitForAsyncComplete)
                    {
                        CacheBundle = AssetBundle.LoadFromFile(_fileLoadPath);
                    }
                    else
                    {
                        _cacheRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath);
                    }
                }
                _steps = ESteps.CheckFile;
            }

            // 4. 检测AssetBundle加载结果
            if (_steps == ESteps.CheckFile)
            {
                if (_cacheRequest != null)
                {
                    if (_isWaitForAsyncComplete)
                    {
                        // 强制挂起主线程(注意:该操作会很耗时)
                        YooLogger.Warning("Suspend the main thread to load unity bundle.");
                        CacheBundle = _cacheRequest.assetBundle;
                    }
                    else
                    {
                        if (_cacheRequest.isDone == false)
                        {
                            return;
                        }
                        CacheBundle = _cacheRequest.assetBundle;
                    }
                }

                // Check error
                if (CacheBundle == null)
                {
                    _steps    = ESteps.Done;
                    Status    = EStatus.Failed;
                    LastError = $"Failed to load assetBundle : {MainBundleInfo.BundleName}";
                    YooLogger.Error(LastError);
                }
                else
                {
                    _steps = ESteps.Done;
                    Status = EStatus.Succeed;
                }
            }
        }