void OnDownloadFinished(LoaderResult result)
        {
            if (isDestroyed)
            {
                return;
            }

            downloadingCount--;

            if (result.ErrorType.HasValue)
            {
                OnErrorReceived(result);
                return;
            }

            string       assetBundleName = result.AssetBundleRecord.AssetBundleName;
            DownloadTask task;

            if (!taskDictionary.TryGetValue(assetBundleName, out task))
            {
                errorReceiver.OnError(AssetBundleErrorCode.MissingTaskDownloadFinished, $"cannot find task: {assetBundleName}");
                return;
            }

            taskDictionary.Remove(assetBundleName);
            task.OnFinished.Invoke(result);
        }
Пример #2
0
        bool TryLoadFromLocalStorage(AssetBundleRecord assetBundleRecord, Action <LoaderResult> onFinished)
        {
            var localPath = AssetBundleUtility.GetLocalStoragePath(assetBundleRecord.AssetBundleName);

            if (!File.Exists(localPath))
            {
                return(false);
            }

            Debug.Log($"load from local storage: {localPath}");

            byte[] bytes;
            try
            {
                using (FileStream fileStream = new FileStream(localPath, FileMode.Open, FileAccess.Read))
                {
                    bytes = new byte[fileStream.Length];
                    fileStream.Read(bytes, 0, bytes.Length);
                    fileStream.Close();
                }
            }
            catch (Exception e)
            {
                Debug.LogError(e);
                return(false);
            }

            var result = new LoaderResult(assetBundleRecord, bytes, null);

            onFinished.Invoke(result);
            return(true);
        }
        void EnqueueTaskToRetry(LoaderResult result, DownloadTask task, int newTriedCount)
        {
            var assetBundleName = result.AssetBundleRecord.AssetBundleName;

            Debug.LogWarning($"asset bundle download retry: AssetBundleName={assetBundleName} TriedCount={newTriedCount}");

            var newTask = new DownloadTask(result.AssetBundleRecord, task.OnFinished, newTriedCount);

            taskDictionary[assetBundleName] = newTask;
            assetBundleRecordQueue.Enqueue(result.AssetBundleRecord);
        }
Пример #4
0
        public IEnumerator LoadAsync(AssetBundleRecord assetBundleRecord, Action <LoaderResult> onFinished)
        {
            string path = $"{url}{assetBundleRecord.AssetBundleName}";

            Debug.Log($"download from web: {path}");

            var request = UnityWebRequest.Get(path);

            request.downloadHandler = new DownloadHandlerBuffer();
            request.SendWebRequest();
            yield return(null);

            while (!request.isDone)
            {
                yield return(null);
            }

            if (request.isHttpError || request.isNetworkError)
            {
                var errorResult = new LoaderResult(assetBundleRecord, null, AssetBundleDownloadErrorType.Network);
                onFinished.Invoke(errorResult);
                yield break;
            }

            byte[] bytes     = request.downloadHandler.data;
            var    localPath = AssetBundleUtility.GetLocalStoragePath(assetBundleRecord.AssetBundleName);

            try
            {
                var dirPath = Path.GetDirectoryName(localPath);
                if (!Directory.Exists(dirPath))
                {
                    Directory.CreateDirectory(dirPath);
                }

                using (FileStream fileStream = new FileStream(localPath, FileMode.OpenOrCreate, FileAccess.Write))
                {
                    fileStream.Write(bytes, 0, bytes.Length);
                    fileStream.Close();
                }
            }
            catch (Exception e)
            {
                Debug.LogError(e);
                var errorResult = new LoaderResult(assetBundleRecord, bytes, AssetBundleDownloadErrorType.IO);
                onFinished.Invoke(errorResult);
                yield break;
            }

            var successResult = new LoaderResult(assetBundleRecord, bytes, null);

            onFinished.Invoke(successResult);
        }
        void RetryDueToIo(LoaderResult result)
        {
            var          assetBundleName = result.AssetBundleRecord.AssetBundleName;
            DownloadTask task;

            if (!taskDictionary.TryGetValue(assetBundleName, out task))
            {
                errorReceiver.OnError(AssetBundleErrorCode.MissingTaskRetryIo, $"cannot find task: {assetBundleName}");
                return;
            }

            EnqueueTaskToRetry(result, task, task.TriedCount);
        }
Пример #6
0
        void OnDownloadFinished(LoaderResult result)
        {
            var assetBundleName = result.AssetBundleRecord.AssetBundleName;
            Action <LoaderResult> onFinished;

            if (!actionDictionary.TryGetValue(assetBundleName, out onFinished))
            {
                errorReceiver.OnError(AssetBundleErrorCode.MissingFinishedAction, $"cannot find finished action: {assetBundleName}");
                return;
            }

            // release load async coroutine
            actionDictionary.Remove(assetBundleName);
            onFinished.Invoke(result);
        }
        void OnErrorReceived(LoaderResult result)
        {
            var errorType = result.ErrorType.Value;

            switch (errorType)
            {
            case AssetBundleDownloadErrorType.Network:
                Retry(result);
                break;

            case AssetBundleDownloadErrorType.IO:
                errorReceiver.OnRetriableError(result, retryActionDueToIo);
                break;

            default:
                errorReceiver.OnError(AssetBundleErrorCode.UnknownErrorType, $"unknown download error type: {errorType}");
                break;
            }
        }
        void Retry(LoaderResult result)
        {
            var          assetBundleName = result.AssetBundleRecord.AssetBundleName;
            DownloadTask task;

            if (!taskDictionary.TryGetValue(assetBundleName, out task))
            {
                errorReceiver.OnError(AssetBundleErrorCode.MissingTaskRetry, $"cannot find task: {assetBundleName}");
                return;
            }

            if (task.TriedCount + 1 >= RetryCount)
            {
                Debug.LogError($"cannot download asset bundle: {assetBundleName}");
                errorReceiver.OnRetriableError(result, retryActionDueToNetwork);
                return;
            }

            EnqueueTaskToRetry(result, task, task.TriedCount + 1);
        }
Пример #9
0
        IEnumerator OnAssetBundleLoadedAsync(LoaderResult result)
        {
            string            assetBundleName = result.AssetBundleRecord.AssetBundleName;
            AssetBundleRecord assetBundleRecord;

            if (!loadingAssetBundleRecords.TryGetValue(assetBundleName, out assetBundleRecord))
            {
                errorReceiver.OnError(AssetBundleErrorCode.MissingLoadingAssetBundleRecord, $"cannot find loading asset bundle record: {assetBundleName}");
                yield break;
            }

            byte[] bytes = Decrypt(result.Bytes);
            if (bytes == null)
            {
                errorReceiver.OnError(AssetBundleErrorCode.FailureToDecrypt, $"cannot decrypt asset bundle: {assetBundleName}");
                yield break;
            }

            uint crc = assetBundleRecord.Crc;
            var  assetBundleRequest = AssetBundle.LoadFromMemoryAsync(bytes, crc);

            while (!assetBundleRequest.isDone)
            {
                yield return(null);
            }

            AssetBundle assetBundle = assetBundleRequest.assetBundle;

            if (assetBundle == null)
            {
                errorReceiver.OnError(AssetBundleErrorCode.FailureToGetAssetBundle, $"cannot get asset bundle: {assetBundleName}");
                yield break;
            }

            loadedAssetBundles.Add(assetBundleName, assetBundle);

            if (!loadingAssetBundleRecords.TryRemove(assetBundleName))
            {
                errorReceiver.OnError(AssetBundleErrorCode.FailureToRemoveLoadingAssetBundleRecord, $"cannot remove loading asset bundle record: {assetBundleName}");
                yield break;
            }

            HashSet <int> taskIds;

            if (!loadingTaskIdSets.TryGetValue(assetBundleName, out taskIds))
            {
                errorReceiver.OnError(AssetBundleErrorCode.MissingTaskIdSetInCheckingCompletion, $"cannot get task id set: {assetBundleName}");
                yield break;
            }

            List <IEnumerator> enumeratorsToGetAsset = ListPool <IEnumerator> .Pool.Get();

            foreach (int taskId in taskIds)
            {
                LoadingTask?nullableLoadingTask = loadingTasks.GetNullableValue(taskId);
                if (!nullableLoadingTask.HasValue)
                {
                    errorReceiver.OnError(AssetBundleErrorCode.MissingLoadingTask, $"cannot get loading task: {assetBundleName}");
                    yield break;
                }

                LoadingTask loadingTask = nullableLoadingTask.Value;
                if (loadingTask.NecessaryAssetBundleRecords.All(r => loadedAssetBundles.ContainsKey(r.AssetBundleName)))
                {
                    enumeratorsToGetAsset.Add(loadingTask.EnumeratorToGetAsset);
                }
            }

            foreach (IEnumerator enumerator in enumeratorsToGetAsset)
            {
                coroutineOwner.Run(enumerator);
            }

            ListPool <IEnumerator> .Pool.Put(ref enumeratorsToGetAsset);
        }
Пример #10
0
 void OnAssetBundleLoaded(LoaderResult result)
 {
     coroutineOwner.Run(OnAssetBundleLoadedAsync(result));
 }