Exemplo n.º 1
0
        public AssetBundleInfo(AssetBundleInfo baseAssetBundleInfo)
        {
            this.bundleName = baseAssetBundleInfo.bundleName;
            this.assetNames = new string[baseAssetBundleInfo.assetNames.Length];
            for (var i = 0; i < assetNames.Length; i++)
            {
                assetNames[i] = baseAssetBundleInfo.assetNames[i];
            }

            this.dependsBundleNames = new string[baseAssetBundleInfo.dependsBundleNames.Length];
            for (var i = 0; i < dependsBundleNames.Length; i++)
            {
                dependsBundleNames[i] = baseAssetBundleInfo.dependsBundleNames[i];
            }

            this.crc  = baseAssetBundleInfo.crc;
            this.hash = baseAssetBundleInfo.hash;
        }
Exemplo n.º 2
0
        /**
         *              load assetBundle on memory.
         */
        private IEnumerator LoadAssetBundleOnMemory <T>(
            string bundleName,
            string assetName,
            uint crc,
            Hash128 hash,
            Action <string, T> loadSucceeded,
            Action <string, AssetBundleLoadError, string, AutoyaStatus> loadFailed,
            long timeoutTick,
            bool isDependency = false,
            List <string> loadingDependentBundleNames = null
            ) where T : UnityEngine.Object
        {
            while (!Caching.ready)
            {
                yield return(null);
            }

            var assetBundleInfo = bundleListStorage.AssetBundleInfoFromBundleName(bundleName);


            if (AssetBundleInfo.IsEmpty(assetBundleInfo))
            {
                // no assetBundleInfo found.
                loadFailed(assetName, AssetBundleLoadError.NoAssetBundleFoundInList, "no assetBundle found:" + bundleName + " in list.", new AutoyaStatus());
                yield break;
            }

            var dependentBundleNames = assetBundleInfo.dependsBundleNames;

            var dependentBundleLoadErrors = new List <DependentBundleError>();

            /*
             *                  resolve dependencies.
             */
            {
                if (dependentBundleNames.Any())
                {
                    var coroutines = new Dictionary <string, IEnumerator>();

                    foreach (var dependentBundleName in dependentBundleNames)
                    {
                        if (loadingDependentBundleNames != null)
                        {
                            if (loadingDependentBundleNames.Contains(dependentBundleName))
                            {
                                continue;
                            }
                        }

                        // skip if assetBundle is already loaded on memory.
                        if (onMemoryCache.ContainsKey(dependentBundleName) && onMemoryCache[dependentBundleName] != null)
                        {
                            continue;
                        }

                        var dependedBundleInfo = bundleListStorage.AssetBundleInfoFromBundleName(dependentBundleName);
                        if (AssetBundleInfo.IsEmpty(dependedBundleInfo))
                        {
                            // skip empty info.
                            continue;
                        }

                        var dependentBundleCrc  = dependedBundleInfo.crc;
                        var dependentBundleHash = Hash128.Parse(dependedBundleInfo.hash);

                        // set UnityEngine.Object for request. this asset will never use directory.
                        var loadCoroutine = LoadAssetBundleOnMemory <UnityEngine.Object>(
                            dependentBundleName,
                            string.Empty,// bundleName not required.
                            dependentBundleCrc,
                            dependentBundleHash,
                            (depBundleName, depObj) =>
                        {
                            // do nothing. this bundle is currently on memory.
                        },
                            (depBundleName, depErr, depReason, autoyaStatus) =>
                        {
                            // collect error for this dependent bundle loading.
                            dependentBundleLoadErrors.Add(new DependentBundleError(depBundleName, depErr, depReason, autoyaStatus));
                        },
                            timeoutTick,
                            true, // this loading is for resolve dependency of root asset. no need to return any instances.
                            loadingDependentBundleNames
                            );

                        if (loadingDependentBundleNames != null)
                        {
                            loadingDependentBundleNames.Add(dependentBundleName);
                        }
                        coroutines[dependentBundleName] = loadCoroutine;
                    }

                    if (coroutines.Count != 0)
                    {
                        while (true)
                        {
                            if (!coroutines.Where(c => c.Value != null).Any())
                            {
                                // load done.
                                break;
                            }

                            for (var i = 0; i < coroutines.Count; i++)
                            {
                                var loadingAssetBundleName = coroutines.Keys.ToArray()[i];
                                var coroutine = coroutines[loadingAssetBundleName];
                                if (coroutine == null)
                                {
                                    continue;
                                }

                                if (!coroutine.MoveNext())
                                {
                                    coroutines[loadingAssetBundleName] = null;
                                }
                            }
                            yield return(null);
                        }

                        // all dependencies are loaded on memory.
                    }
                }
            }

            var url = GetAssetBundleDownloadUrl(bundleName);

            // check now loading or not. if same bundle is already under loading, wait it here.
            if (loadingAssetBundleNames.Contains(bundleName))
            {
                while (loadingAssetBundleNames.Contains(bundleName))
                {
                    yield return(null);
                }

                // check downloaded bundle is correctly cached or not.
                var isCached = Caching.IsVersionCached(url, hash);
                if (!isCached)
                {
                    loadFailed(assetName, AssetBundleLoadError.DownloadFailed, "caching failed.", new AutoyaStatus());
                    yield break;
                }
            }

            // assetBundle is already allocated on memory.
            if (onMemoryCache.ContainsKey(bundleName))
            {
                var isCached = Caching.IsVersionCached(url, hash);

                if (isCached)
                {
                    // if current target is dependency, dependent assetBundle is already on memory. and no need to load it.
                    if (isDependency)
                    {
                        yield break;
                    }

                    // start loading assetBundle on memory.
                    var loadOnMemoryCachedAssetCoroutine = LoadOnMemoryAssetAsync(bundleName, assetName, loadSucceeded, loadFailed);
                    while (loadOnMemoryCachedAssetCoroutine.MoveNext())
                    {
                        yield return(null);
                    }

                    // loading asset from on memory cache is done.
                    yield break;
                }

                // assetBundle is cached on memory but it's not target hashed bundle. need to download other one.
                var oldOnMemoryAssetBundle = onMemoryCache[bundleName];

                // remove from on memory cache.
                UnloadOnMemoryAssetBundle(bundleName);
            }

            /*
             *                  assetBundle is..
             *                          not yet cached (or) already cached.
             *                          not allocated on memory.
             *
             *                  assetBundle is not on memory yet. start downloading.
             */

            // binded block.
            using (var loadingConstraint = new AssetBundleLoadingConstraint(bundleName, loadingAssetBundleNames))
            {
                /*
                 *                      download bundle or load donwloaded bundle from cache.
                 *                      load to memory.
                 */
                {
                    var downloadCoroutine = DownloadAssetThenCacheAndLoadToMemory(bundleName, assetName, url, crc, hash, loadFailed, timeoutTick);
                    while (downloadCoroutine.MoveNext())
                    {
                        yield return(null);
                    }

                    if (!onMemoryCache.ContainsKey(bundleName))
                    {
                        // error is already fired in above.
                        yield break;
                    }

                    if (!isDependency)
                    {
                        /*
                         *                              break if dependent bundle has load error.
                         */
                        if (dependentBundleLoadErrors.Any())
                        {
                            var loadErrorBundleMessages = new StringBuilder();
                            loadErrorBundleMessages.Append("failed to load/download dependent bundle:");
                            foreach (var dependentBundleLoadError in dependentBundleLoadErrors)
                            {
                                loadErrorBundleMessages.Append("bundleName:");
                                loadErrorBundleMessages.Append(dependentBundleLoadError.bundleName);
                                loadErrorBundleMessages.Append(" error:");
                                loadErrorBundleMessages.Append(dependentBundleLoadError.err);
                                loadErrorBundleMessages.Append(" reason:");
                                loadErrorBundleMessages.Append(dependentBundleLoadError.reason);
                                loadErrorBundleMessages.Append(" autoyaStatus:");
                                loadErrorBundleMessages.Append("  inMaintenance:" + dependentBundleLoadError.status.inMaintenance);
                                loadErrorBundleMessages.Append("  isAuthFailed:" + dependentBundleLoadError.status.isAuthFailed);
                            }
                            loadFailed(assetName, AssetBundleLoadError.FailedToLoadDependentBundles, loadErrorBundleMessages.ToString(), new AutoyaStatus());

                            yield break;
                        }

                        /*
                         *                              load asset from on memory AssetBundle.
                         */
                        var loadAssetCoroutine = LoadOnMemoryAssetAsync(bundleName, assetName, loadSucceeded, loadFailed);
                        while (loadAssetCoroutine.MoveNext())
                        {
                            yield return(null);
                        }
                    }
                }
            }
        }
Exemplo n.º 3
0
 public static bool IsEmpty(AssetBundleInfo target)
 {
     return(target.size == 0 || target.assetNames.Length == 0 || string.IsNullOrEmpty(target.bundleName));
 }