public IEnumerator Preload(AssetBundleLoader loader, PreloadList preloadList, Action <string[], Action, Action> onBeforePreloading, Action <double> progress, Action done, Action <int, string, AutoyaStatus> preloadFailed, Action <string, AssetBundleLoadError, string, AutoyaStatus> bundlePreloadFailed, int maxParallelCount = 1) { if (0 < maxParallelCount) { // pass. } else { yield return(null); preloadFailed(-1, "maxParallelCount is negative or 0. unable to start preload.", new AutoyaStatus()); yield break; } if (loader != null) { // pass. } else { yield return(null); preloadFailed(-1, "attached AssetBundleLoader is null. unable to start preload.", new AutoyaStatus()); yield break; } if (preloadList != null) { // pass. } else { yield return(null); preloadFailed(-1, "preloadList is null. unable to start preload.", new AutoyaStatus()); yield break; } /* * check if preloadList's assetBundleNames are contained by assetBundleList. */ var targetAssetBundleNames = preloadList.bundleNames; var assetBundleListContainedAssetBundleNames = loader.GetWholeBundleNames(); // start preload assetBundles. var loadingCoroutines = new Queue <IEnumerator>(); var currentDownloadCount = 0; // define. var totalLoadingCoroutinesCount = 0; /* * assetBundle downloaded actions. */ Action <string> bundlePreloadSucceededAct = (bundleName) => { currentDownloadCount++; // Debug.Log("bundleName:" + bundleName); var count = ((currentDownloadCount * 100.0) / totalLoadingCoroutinesCount) * 0.01; progress(count); }; Action <string, AssetBundleLoadError, string, AutoyaStatus> bundlePreloadFailedAct = (bundleName, error, reason, autoyaStatus) => { bundlePreloadFailed(bundleName, error, reason, autoyaStatus); }; var wholeDownloadableAssetBundleNames = new List <string>(); foreach (var targetAssetBundleName in targetAssetBundleNames) { // skip not contained bundle. if (!assetBundleListContainedAssetBundleNames.Contains(targetAssetBundleName)) { continue; } // reserve this assetBundle name. wholeDownloadableAssetBundleNames.Add(targetAssetBundleName); // add only 1st level dependent AsstBundle Names. var dependentBundleNames = loader.AssetBundleInfoFromBundleName(targetAssetBundleName).dependsBundleNames; wholeDownloadableAssetBundleNames.AddRange(dependentBundleNames); } var shouldDownloadAssetBundleNamesCandidate = wholeDownloadableAssetBundleNames.Distinct().ToArray(); var shouldDownloadAssetBundleNames = new List <string>(); foreach (var shouldDownloadAssetBundleName in shouldDownloadAssetBundleNamesCandidate) { var bundleUrl = loader.GetAssetBundleDownloadUrl(shouldDownloadAssetBundleName); var targetBundleInfo = loader.AssetBundleInfoFromBundleName(shouldDownloadAssetBundleName); var hash = Hash128.Parse(targetBundleInfo.hash); // ignore cached one. if (Caching.IsVersionCached(bundleUrl, hash)) { continue; } // ignore loaded one. if (loader.IsAssetBundleCachedOnMemory(shouldDownloadAssetBundleName)) { continue; } shouldDownloadAssetBundleNames.Add(shouldDownloadAssetBundleName); } // ここまでで、DLする対象のAssetBundleと、そのAssetBundleが依存しているAssetBundleまでが確保できている。 /* * ask should continue or not before downloading target assetBundles. * estimation is not considered about duplication of download same AssetBundle at same time. * this is max case. */ var shouldContinueCor = shouldContinuePreloading(shouldDownloadAssetBundleNames.ToArray(), onBeforePreloading); while (shouldContinueCor.MoveNext()) { yield return(null); } var shouldContinue = shouldContinueCor.Current; if (!shouldContinue) { done(); yield break; } /* * bundles are not cached on storage. should start download. */ foreach (var shouldDownloadAssetBundleName in shouldDownloadAssetBundleNames) { var bundleLoadConId = AssetBundlesSettings.ASSETBUNDLES_PRELOADBUNDLE_PREFIX + Guid.NewGuid().ToString(); var bundleUrl = loader.GetAssetBundleDownloadUrl(shouldDownloadAssetBundleName); var targetBundleInfo = loader.AssetBundleInfoFromBundleName(shouldDownloadAssetBundleName); var crc = targetBundleInfo.crc; var hash = Hash128.Parse(targetBundleInfo.hash); if (loader.IsAssetBundleCachedOnMemory(shouldDownloadAssetBundleName)) { // bundle is not cached on storage, but old bundle is no memory. need to unload it. loader.UnloadOnMemoryAssetBundle(shouldDownloadAssetBundleName); } var bundlePreloadTimeoutTick = 0;// preloader does not have limit now. /* * AssetBundleのダウンロードを行う。 * 依存取得はoffで、ハンドリングはAssetBundleLoaderのものを使用する。 */ var cor = loader.LoadAssetBundleThenNotUse( shouldDownloadAssetBundleName, crc, hash, false,// not download more dependency. downloadedBundleName => { bundlePreloadSucceededAct(downloadedBundleName); }, (downloadedBundleName, error, reason, autoyaStatus) => { bundlePreloadFailedAct(downloadedBundleName, error, reason, autoyaStatus); }, bundlePreloadTimeoutTick ); loadingCoroutines.Enqueue(cor); } // update total count to actual. totalLoadingCoroutinesCount = loadingCoroutines.Count; /* * execute loading. */ var currentLoadingCoroutines = new IEnumerator[maxParallelCount]; while (true) { for (var j = 0; j < currentLoadingCoroutines.Length; j++) { var currentLoadingCoroutine = currentLoadingCoroutines[j]; if (currentLoadingCoroutine == null) { // set next coroutine to currentLoadingCoroutines. if (0 < loadingCoroutines.Count) { var next = loadingCoroutines.Dequeue(); currentLoadingCoroutines[j] = next; } else { // no coroutine exists. continue; } } } var loading = false; for (var j = 0; j < currentLoadingCoroutines.Length; j++) { var cor = currentLoadingCoroutines[j]; if (cor == null) { continue; } var result = cor.MoveNext(); // just finished. if (!result) { currentLoadingCoroutines[j] = null; } else { loading = true; } } if (0 < loadingCoroutines.Count) { loading = true; } if (loading) { yield return(null); } else { // nothing loading. break; } } // every bundle downloading is done. done(); }
/** * preload assetBundle from list url. */ public IEnumerator Preload(AssetBundleLoader loader, string listUrl, Action <string[], Action, Action> onBeforePreloading, Action <double> progress, Action done, Action <int, string, AutoyaStatus> preloadFailed, Action <string, AssetBundleLoadError, string, AutoyaStatus> bundlePreloadFailed, int maxParallelCount = 1, double timeoutSec = 0) { if (0 < maxParallelCount) { // pass. } else { yield return(null); preloadFailed(-1, "maxParallelCount is negative or 0. unable to start preload.", new AutoyaStatus()); yield break; } if (loader != null) { // pass. } else { yield return(null); preloadFailed(-1, "attached AssetBundleLoader is null. unable to start preload.", new AutoyaStatus()); yield break; } var connectionId = AssetBundlesSettings.ASSETBUNDLES_PRELOADLIST_PREFIX + Guid.NewGuid().ToString(); var reqHeader = preloadListGetRequestHeaderDelegate(listUrl, new Dictionary <string, string>()); PreloadList list = null; Action <string, object> listDonwloadSucceeded = (conId, listData) => { var listStr = listData as string; list = JsonUtility.FromJson <PreloadList>(listStr); }; Action <string, int, string, AutoyaStatus> listDownloadFailedAct = (conId, code, reason, autoyaStatus) => { preloadFailed(code, reason, autoyaStatus); }; var downloadCoroutine = DownloadPreloadList( connectionId, reqHeader, listUrl, (conId, code, responseHeaders, listData) => { httpResponseHandlingDelegate(connectionId, responseHeaders, code, listData, string.Empty, listDonwloadSucceeded, listDownloadFailedAct); }, (conId, code, reason, responseHeaders) => { httpResponseHandlingDelegate(connectionId, responseHeaders, code, string.Empty, reason, listDonwloadSucceeded, listDownloadFailedAct); }, timeoutSec ); while (downloadCoroutine.MoveNext()) { yield return(null); } // check if the list download is done. if (list != null) { // pass. } else { yield break; } var bundleDownloadCor = Preload(loader, list, onBeforePreloading, progress, done, preloadFailed, bundlePreloadFailed, maxParallelCount); while (bundleDownloadCor.MoveNext()) { yield return(null); } }
public IEnumerator Preload(AssetBundleLoader loader, PreloadList preloadList, Action <string[], Action, Action> onBeforePreloading, Action <double> progress, Action done, Action <int, string, AutoyaStatus> preloadFailed, Action <string, int, string, AutoyaStatus> bundlePreloadFailed, int maxParallelCount = 1) { if (0 < maxParallelCount) { // pass. } else { yield return(null); preloadFailed(-1, "maxParallelCount is negative or 0. unable to start preload.", new AutoyaStatus()); yield break; } if (loader != null) { // pass. } else { yield return(null); preloadFailed(-1, "attached AssetBundleLoader is null. unable to start preload.", new AutoyaStatus()); yield break; } if (preloadList != null) { // pass. } else { yield return(null); preloadFailed(-1, "preloadList is null. unable to start preload.", new AutoyaStatus()); yield break; } /* * check if preloadList's assetBundleNames are contained by assetBundleList. */ var targetAssetBundleNames = preloadList.bundleNames; var assetBundleListContainedAssetBundleNames = loader.GetWholeBundleNames(); // start preload assetBundles. var loadingCoroutines = new Queue <IEnumerator>(); var currentDownloadCount = 0; // define. var totalLoadingCoroutinesCount = 0; /* * assetBundle downloaded actions. */ Action <string, object> bundlePreloadSucceededAct = (conId, obj) => { // unload assetBundle anyway. // downloaded assetBundle is cached on storage. var bundle = obj as AssetBundle; bundle.Unload(true); currentDownloadCount++; var count = ((currentDownloadCount * 100.0) / totalLoadingCoroutinesCount) * 0.01; progress(count); }; Action <string, int, string, AutoyaStatus> bundlePreloadFailedAct = (bundleName, code, reason, autoyaStatus) => { bundlePreloadFailed(bundleName, code, reason, autoyaStatus); }; var wholeDownloadableAssetBundleNames = new List <string>(); foreach (var targetAssetBundleName in targetAssetBundleNames) { // skip not contained bundle. if (!assetBundleListContainedAssetBundleNames.Contains(targetAssetBundleName)) { continue; } // reserve this assetBundle and dependencies as "should be download". wholeDownloadableAssetBundleNames.Add(targetAssetBundleName); var dependentBundleNames = loader.AssetBundleInfoFromBundleName(targetAssetBundleName).dependsBundleNames; wholeDownloadableAssetBundleNames.AddRange(dependentBundleNames); } var shouldDownloadAssetBundleNamesCandidate = wholeDownloadableAssetBundleNames.Distinct().ToArray(); var shouldDownloadAssetBundleNames = new List <string>(); foreach (var shouldDownloadAssetBundleName in shouldDownloadAssetBundleNamesCandidate) { var bundleUrl = loader.GetAssetBundleDownloadUrl(shouldDownloadAssetBundleName); var targetBundleInfo = loader.AssetBundleInfoFromBundleName(shouldDownloadAssetBundleName); var hash = Hash128.Parse(targetBundleInfo.hash); // ignore cached one. if (Caching.IsVersionCached(bundleUrl, hash)) { continue; } // ignore loaded one. if (loader.IsAssetBundleCachedOnMemory(shouldDownloadAssetBundleName)) { continue; } shouldDownloadAssetBundleNames.Add(shouldDownloadAssetBundleName); } /* * ask should continue or not before downloading target assetBundles. */ var shouldContinueCor = shouldContinuePreloading(shouldDownloadAssetBundleNames.ToArray(), onBeforePreloading); while (shouldContinueCor.MoveNext()) { yield return(null); } var shouldContinue = shouldContinueCor.Current; if (!shouldContinue) { done(); yield break; } /* * bundles are not cached on storage. should start download. */ foreach (var shouldDownloadAssetBundleName in shouldDownloadAssetBundleNames) { var bundleLoadConId = AssetBundlesSettings.ASSETBUNDLES_PRELOADBUNDLE_PREFIX + Guid.NewGuid().ToString(); var bundleUrl = loader.GetAssetBundleDownloadUrl(shouldDownloadAssetBundleName); var bundleReqHeader = assetBundleGetRequestHeaderDelegate(bundleUrl, new Dictionary <string, string>()); var targetBundleInfo = loader.AssetBundleInfoFromBundleName(shouldDownloadAssetBundleName); var crc = targetBundleInfo.crc; var hash = Hash128.Parse(targetBundleInfo.hash); if (loader.IsAssetBundleCachedOnMemory(shouldDownloadAssetBundleName)) { // bundle is not cached on storage, but old bundle is no memory. need to unload it. loader.UnloadOnMemoryAssetBundle(shouldDownloadAssetBundleName); } var bundlePreloadTimeoutTick = 0;// preloader does not have limit now. var cor = loader.DownloadAssetBundle( shouldDownloadAssetBundleName, bundleLoadConId, bundleReqHeader, bundleUrl, crc, hash, (conId, code, responseHeaders, bundle) => { httpResponseHandlingDelegate(conId, responseHeaders, code, bundle, string.Empty, bundlePreloadSucceededAct, bundlePreloadFailedAct); }, (conId, code, reason, responseHeaders) => { httpResponseHandlingDelegate(conId, responseHeaders, code, string.Empty, reason, bundlePreloadSucceededAct, bundlePreloadFailedAct); }, bundlePreloadTimeoutTick ); loadingCoroutines.Enqueue(cor); } // update total count to actual. totalLoadingCoroutinesCount = loadingCoroutines.Count; /* * execute loading. */ var currentLoadingCoroutines = new IEnumerator[maxParallelCount]; while (true) { for (var j = 0; j < currentLoadingCoroutines.Length; j++) { var currentLoadingCoroutine = currentLoadingCoroutines[j]; if (currentLoadingCoroutine == null) { // set next coroutine to currentLoadingCoroutines. if (0 < loadingCoroutines.Count) { var next = loadingCoroutines.Dequeue(); currentLoadingCoroutines[j] = next; } else { // no coroutine exists. continue; } } } var loading = false; for (var j = 0; j < currentLoadingCoroutines.Length; j++) { var cor = currentLoadingCoroutines[j]; if (cor == null) { continue; } var result = cor.MoveNext(); // just finished. if (!result) { currentLoadingCoroutines[j] = null; } else { loading = true; } } if (0 < loadingCoroutines.Count) { loading = true; } if (loading) { yield return(null); } else { // nothing loading. break; } } // every bundle downloading is done. done(); }