コード例 #1
0
        protected virtual IEnumerator DoDownloadFileAsync(string path, FileInfo fileInfo,
                                                          IProgressPromise <ProgressInfo> promise, float overtimeTime)
        {
            if (fileInfo.Directory != null && !fileInfo.Directory.Exists)
            {
                fileInfo.Directory.Create();
            }
            ProgressInfo progressInfo = new ProgressInfo {
                TotalCount = 1
            };

            using (UnityWebRequest www = new UnityWebRequest(path))
            {
                var downloadFileHandler = new DownloadFileHandler(fileInfo);
                www.downloadHandler = downloadFileHandler;
                www.SendWebRequest();
                float timer = 0;
                while (!www.isDone)
                {
                    if (www.downloadProgress >= 0)
                    {
                        if (progressInfo.TotalSize <= 0)
                        {
                            progressInfo.TotalSize = (long)(www.downloadedBytes / www.downloadProgress);
                        }
                        progressInfo.CompletedSize = (long)www.downloadedBytes;
                        promise.UpdateProgress(progressInfo);
                    }
                    timer += Time.deltaTime;
                    if (timer > overtimeTime)
                    {
                        promise.SetException(new TimeoutException());
                        break;
                    }
                    yield return(null);
                }

                while (!downloadFileHandler.WriteFinish)
                {
                    timer += Time.deltaTime;
                    if (timer > overtimeTime)
                    {
                        promise.SetException(new TimeoutException());
                        break;
                    }
                    yield return(null);
                }

                if (www.isNetworkError || www.isHttpError)
                {
                    promise.SetException(www.error);
                    yield break;
                }

                progressInfo.CompletedCount = 1;
                progressInfo.CompletedSize  = progressInfo.TotalSize;
                promise.UpdateProgress(progressInfo);
                promise.SetResult(fileInfo);
            }
        }
コード例 #2
0
        static IEnumerator Download(IProgressPromise <float> promise, AsyncOperationHandle handle)
        {
            while (!handle.IsDone)
            {
                promise.UpdateProgress(handle.PercentComplete);
                yield return(null);

                if (handle.OperationException != null)
                {
                    promise.SetException(handle.OperationException);
                }
            }
            promise.SetException(handle.OperationException);
            promise.SetResult();
        }
コード例 #3
0
        protected virtual IEnumerator DoLoadAssetAsync <T>(IProgressPromise <float, T> promise, string name) where T : Object
        {
            string             key = Key(name, typeof(T));
            AssetBundleRequest request;

            if (!this.requestCache.TryGetValue(key, out request))
            {
                var fullName = GetFullName(name);
                request = this.AssetBundle.LoadAssetAsync <T>(fullName);
                this.requestCache.Add(key, request);
            }

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

            this.requestCache.Remove(key);

            Object asset = request.asset;

            if (asset == null)
            {
                promise.SetException(new System.Exception(string.Format("Not found the asset '{0}'.", name)));
                yield break;
            }

            promise.UpdateProgress(1f);
            promise.SetResult(asset);
        }
コード例 #4
0
        private IEnumerator CreateViewGo <T>(IProgressPromise <float, T> promise, View view, string path, ViewModel viewModel)
            where T : View
        {
            var request = _res.LoadAssetAsync <GameObject>(path);

            while (!request.IsDone)
            {
                promise.UpdateProgress(request.Progress);
                yield return(null);
            }
            GameObject viewTemplateGo = request.Result;

            if (viewTemplateGo == null)
            {
                promise.UpdateProgress(1f);
                Log.Error($"Not found the window path = \"{path}\".");
                promise.SetException(new FileNotFoundException(path));
                yield break;
            }
            GameObject go = Object.Instantiate(viewTemplateGo);

            view.SetGameObject(go);
            go.name = viewTemplateGo.name;
            promise.UpdateProgress(1f);
            promise.SetResult(view);
            view.SetVm(viewModel);
        }
コード例 #5
0
        /// <summary>
        /// Simulate a task.
        /// </summary>
        /// <returns>The task.</returns>
        /// <param name="promise">Promise.</param>
        protected void DoTask(IProgressPromise <float, string> promise)
        {
            try
            {
                int           n        = 50;
                float         progress = 0f;
                StringBuilder buf      = new StringBuilder();
                for (int i = 0; i < n; i++)
                {
                    /* If the task is cancelled, then stop the task */
                    if (promise.IsCancellationRequested)
                    {
                        promise.SetCancelled();
                        break;
                    }

                    progress = i / (float)n;
                    buf.Append(" ").Append(i);
                    promise.UpdateProgress(progress);/* update the progress of task. */
#if NETFX_CORE
                    Task.Delay(200).Wait();
#else
                    Thread.Sleep(200);
#endif
                }
                promise.UpdateProgress(1f);
                promise.SetResult(buf.ToString()); /* update the result. */
            }
            catch (System.Exception e)
            {
                promise.SetException(e);
            }
        }
コード例 #6
0
        protected virtual IEnumerator DoLoad <T>(IProgressPromise <float, T> promise, string name)
        {
            name = Normalize(name);
            WeakReference weakRef;
            GameObject    viewTemplateGo = null;

            try
            {
                if (this.templates.TryGetValue(name, out weakRef) && weakRef.IsAlive)
                {
                    viewTemplateGo = (GameObject)weakRef.Target;

                    //Check if the object is valid because it may have been destroyed.
                    //Unmanaged objects,the weak caches do not accurately track the validity of objects.
                    if (viewTemplateGo != null)
                    {
                        string goName = viewTemplateGo.name;
                    }
                }
            }
            catch (Exception)
            {
                viewTemplateGo = null;
            }

            if (viewTemplateGo == null)
            {
                ResourceRequest request = Resources.LoadAsync <GameObject>(name);
                while (!request.isDone)
                {
                    promise.UpdateProgress(request.progress);
                    yield return(null);
                }

                viewTemplateGo = (GameObject)request.asset;
                if (viewTemplateGo != null)
                {
                    viewTemplateGo.SetActive(false);
                    this.templates[name] = new WeakReference(viewTemplateGo);
                }
            }

            if (viewTemplateGo == null || viewTemplateGo.GetComponent <T>() == null)
            {
                promise.UpdateProgress(1f);
                promise.SetException(new NotFoundException(name));
                yield break;
            }

            GameObject go = GameObject.Instantiate(viewTemplateGo);

            go.name = viewTemplateGo.name;
            promise.UpdateProgress(1f);
            promise.SetResult(go.GetComponent <T>());
        }
コード例 #7
0
        protected virtual async void DoLoad <T>(IProgressPromise <float, T> promise, string name, IWindowManager windowManager = null)
        {
            try
            {
                promise.UpdateProgress(0f);
                var result = Addressables.InstantiateAsync(name);
                while (!result.IsDone)
                {
                    await new WaitForSecondsRealtime(0.05f);
                    promise.UpdateProgress(result.PercentComplete);
                }

                if (result.OperationException != null)
                {
                    promise.SetException(result.OperationException);
                    return;
                }

                GameObject go = result.Result;
                go.SetActive(false);

                T view = go.GetComponent <T>();
                if (view == null)
                {
                    //GameObject.Destroy(go);
                    Addressables.ReleaseInstance(go);
                    promise.SetException(new NotFoundException(name));
                }

                if (windowManager != null && view is IWindow)
                {
                    (view as IWindow).WindowManager = windowManager;
                }

                promise.UpdateProgress(1f);
                promise.SetResult(view);
            }
            catch (Exception e)
            {
                promise.SetException(e);
            }
        }
コード例 #8
0
 protected virtual IEnumerator DoLoadAllAssetsAsync(IProgressPromise <float, Object[]> promise, System.Type type)
 {
     try
     {
         Object[] assets = Resources.LoadAll(this.Root);
         promise.UpdateProgress(1f);
         promise.SetResult(assets);
     }
     catch (System.Exception e)
     {
         promise.UpdateProgress(0f);
         promise.SetException(e);
     }
     yield break;
 }
コード例 #9
0
 protected virtual IEnumerator DoLoadAllAssetsAsync <T>(IProgressPromise <float, T[]> promise) where T : Object
 {
     try
     {
         T[] assets = Resources.LoadAll <T>(this.Root);
         promise.UpdateProgress(1f);
         promise.SetResult(assets);
     }
     catch (System.Exception e)
     {
         promise.UpdateProgress(0f);
         promise.SetException(e);
     }
     yield break;
 }
コード例 #10
0
        protected override IEnumerator DoLoadAssetBundle(IProgressPromise <float, AssetBundle> promise)
        {
            if (this.BundleInfo.IsEncrypted)
            {
                promise.UpdateProgress(0f);
                promise.SetException(new NotSupportedException(string.Format("The data of the AssetBundle named '{0}' is encrypted,use the CryptographBundleLoader to load,please.", this.BundleInfo.Name)));
                yield break;
            }

            string path = this.GetAbsolutePath();

#if UNITY_ANDROID && !UNITY_5_4_OR_NEWER
            if (this.Uri.Scheme.Equals("jar", StringComparison.OrdinalIgnoreCase))
            {
                promise.UpdateProgress(0f);
                promise.SetException(new NotSupportedException(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.It is not supported before the Unity3d 5.4.0 version.", this.BundleInfo.Name, path)));
                yield break;
            }
#endif
            AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(path);
            while (!request.isDone)
            {
                promise.UpdateProgress(request.progress);
                yield return(null);
            }

            var assetBundle = request.assetBundle;
            if (assetBundle == null)
            {
                promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.", this.BundleInfo.Name, path)));
                yield break;
            }

            promise.UpdateProgress(1f);
            promise.SetResult(assetBundle);
        }
コード例 #11
0
        protected virtual IEnumerator DoDownloadFileAsync(Uri path, FileInfo fileInfo, IProgressPromise <ProgressInfo> promise)
        {
            if (!fileInfo.Directory.Exists)
            {
                fileInfo.Directory.Create();
            }

            ProgressInfo progressInfo = new ProgressInfo();

            progressInfo.TotalCount = 1;
            using (UnityWebRequest www = new UnityWebRequest(this.GetAbsoluteUri(path).AbsoluteUri))
            {
                www.downloadHandler = new DownloadFileHandler(fileInfo);
#if UNITY_2018_1_OR_NEWER
                www.SendWebRequest();
#else
                www.Send();
#endif
                while (!www.isDone)
                {
                    if (www.downloadProgress >= 0)
                    {
                        if (progressInfo.TotalSize <= 0)
                        {
                            progressInfo.TotalSize = (long)(www.downloadedBytes / www.downloadProgress);
                        }
                        progressInfo.CompletedSize = (long)www.downloadedBytes;
                        promise.UpdateProgress(progressInfo);
                    }
                    yield return(null);
                }

#if UNITY_2018_1_OR_NEWER
                if (www.isNetworkError)
#else
                if (www.isError)
#endif
                {
                    promise.SetException(www.error);
                    yield break;
                }

                progressInfo.CompletedCount = 1;
                progressInfo.CompletedSize  = progressInfo.TotalSize;
                promise.UpdateProgress(progressInfo);
                promise.SetResult(fileInfo);
            }
        }
コード例 #12
0
        protected virtual IEnumerator DoLoad <T>(IProgressPromise <float, T> promise, string name)
        {
            name = Normalize(name);

            WeakReference weakRef;
            GameObject    viewTemplateGo;

            if (this.templates.TryGetValue(name, out weakRef) && weakRef.IsAlive)
            {
                viewTemplateGo = (GameObject)weakRef.Target;
            }
            else
            {
                ResourceRequest request = Resources.LoadAsync <GameObject>(name);
                while (!request.isDone)
                {
                    promise.UpdateProgress(request.progress);
                    yield return(null);
                }

                viewTemplateGo = (GameObject)request.asset;
                if (viewTemplateGo != null)
                {
                    viewTemplateGo.SetActive(false);
                    this.templates[name] = new WeakReference(viewTemplateGo);
                }
            }

            if (viewTemplateGo == null || viewTemplateGo.GetComponent <T>() == null)
            {
                promise.UpdateProgress(1f);
                promise.SetException(new NotFoundException(name));
                yield break;
            }

            GameObject go = GameObject.Instantiate(viewTemplateGo);

            go.name = viewTemplateGo.name;
            promise.UpdateProgress(1f);
            promise.SetResult(go.GetComponent <T>());
        }
コード例 #13
0
        protected virtual IEnumerator DoLoadAssetAsync(IProgressPromise <float, Object> promise, string name, System.Type type)
        {
            var             fullName = this.GetFilePathWithoutExtension(name);
            ResourceRequest request  = Resources.LoadAsync(fullName, type);

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

            promise.UpdateProgress(1f);
            Object asset = request.asset;

            if (asset != null)
            {
                promise.SetResult(request.asset);
            }
            else
            {
                promise.SetException(new System.Exception(string.Format("Not found the asset[{0}].", fullName)));
            }
        }
コード例 #14
0
        private IEnumerator CreateView <T>(IProgressPromise <float, T> promise, Type type, ViewModel viewModel)
            where T : View
        {
            if (_openedViews.TryGetValue(type, out var view))
            {
                promise.UpdateProgress(1f);
                promise.SetResult(view);
                yield break;
            }
            view = ReflectionHelper.CreateInstance(type) as View;
            var path    = (GetClassData(type).Attribute as UIAttribute).Path;
            var request = _res.LoadAssetAsync <GameObject>(path);

            while (!request.IsDone)
            {
                promise.UpdateProgress(request.Progress);
                yield return(null);
            }
            GameObject viewTemplateGo = request.Result;

            if (viewTemplateGo == null)
            {
                promise.UpdateProgress(1f);
                Log.Error($"Not found the window path = \"{path}\".");
                promise.SetException(new FileNotFoundException(path));
                yield break;
            }
            GameObject go = Object.Instantiate(viewTemplateGo);

            go.name = viewTemplateGo.name;
            view.SetGameObject(go);
            view.SetVm(viewModel);
            view.Visible(false);
            promise.UpdateProgress(1f);
            promise.SetResult(view);
        }
コード例 #15
0
        protected virtual IEnumerator DoLoadBundleAndDependencies(IProgressPromise <float, IBundle> promise)
        {
            this.startTime = Time.realtimeSinceStartup;
            List <IProgressResult <float, AssetBundle> > results = new List <IProgressResult <float, AssetBundle> >();

            BundleLoader currLoader = manager.GetOrCreateBundleLoader(this.BundleInfo, this.Priority);

            currLoader.Retain();
            loaders.Add(currLoader);

            IProgressResult <float, AssetBundle> currResult = currLoader.LoadAssetBundle();

            if (!currResult.IsDone)
            {
                results.Add(currResult);
            }

            var dependencies = manager.GetOrCreateDependencies(this.BundleInfo, true, this.Priority);

            for (int i = 0; i < dependencies.Count; i++)
            {
                var dependency = dependencies[i];
                dependency.Retain();
                this.loaders.Add(dependency);

                var result = dependency.LoadAssetBundle();
                if (!result.IsDone)
                {
                    results.Add(result);
                }
            }

            bool  finished     = false;
            float progress     = 0f;
            float timeProgress = 0f;
            int   count        = results.Count;

            while (!finished && count > 0)
            {
                yield return(null);

                progress = 0f;
                finished = true;
                for (int i = 0; i < count; i++)
                {
                    var result = results[i];
                    if (!result.IsDone)
                    {
                        finished = false;
                    }

                    progress += result.Progress;
                }

                timeProgress = TIME_PROGRESS_WEIGHT * Mathf.Atan(Time.realtimeSinceStartup - this.startTime) * 2 / Mathf.PI;
                promise.UpdateProgress(timeProgress + (1.0f - TIME_PROGRESS_WEIGHT) * progress / count);
            }

            promise.UpdateProgress(1f);

            yield return(null);

            if (currResult.Exception != null)
            {
                promise.SetException(currResult.Exception);
            }
            else
            {
                this.assetBundle = currResult.Result;
                promise.SetResult(this);
            }
        }
コード例 #16
0
        protected override IEnumerator DoDownloadBundles(IProgressPromise <Progress, bool> promise, List <BundleInfo> bundles)
        {
            long              totalSize      = 0;
            long              downloadedSize = 0;
            Progress          progress       = new Progress();
            List <BundleInfo> list           = new List <BundleInfo>();

            for (int i = 0; i < bundles.Count; i++)
            {
                var info = bundles[i];
                totalSize += info.FileSize;
                if (BundleUtil.Exists(info, module))
                {
                    downloadedSize += info.FileSize;
                    continue;
                }
                list.Add(info);
            }

            progress.TotalCount     = bundles.Count;
            progress.CompletedCount = bundles.Count - list.Count;
            progress.TotalSize      = totalSize;
            progress.CompletedSize  = downloadedSize;
            yield return(null);

            List <KeyValuePair <BundleInfo, UnityWebRequest> > tasks = new List <KeyValuePair <BundleInfo, UnityWebRequest> >();

            for (int i = 0; i < list.Count; i++)
            {
                BundleInfo      bundleInfo = list[i];
                string          fullname   = GetFullSavePath(bundleInfo.Filename);
                UnityWebRequest www        = new UnityWebRequest(GetAbsoluteUri(bundleInfo.Filename));
                www.downloadHandler = new DownloadFileHandler(fullname);

#if UNITY_2018_1_OR_NEWER
                www.SendWebRequest();
#else
                www.Send();
#endif
                tasks.Add(new KeyValuePair <BundleInfo, UnityWebRequest>(bundleInfo, www));

                while (tasks.Count >= this.MaxTaskCount || (i == list.Count - 1 && tasks.Count > 0))
                {
                    long tmpSize = 0;
                    for (int j = tasks.Count - 1; j >= 0; j--)
                    {
                        var             task        = tasks[j];
                        BundleInfo      _bundleInfo = task.Key;
                        UnityWebRequest _www        = task.Value;

                        if (!_www.isDone)
                        {
                            tmpSize += (long)Math.Max(0, _www.downloadedBytes);//the UnityWebRequest.downloadedProgress has a bug in android platform
                            continue;
                        }

                        progress.CompletedCount += 1;
                        tasks.RemoveAt(j);
                        downloadedSize += _bundleInfo.FileSize;
#if UNITY_2018_1_OR_NEWER
                        if (_www.isNetworkError)
#else
                        if (_www.isNetworkError)
#endif
                        {
                            promise.SetException(new Exception(_www.error));
                            if (log.IsErrorEnabled)
                            {
                                log.ErrorFormat("Downloads AssetBundle '{0}' failure from the address '{1}'.Reason:{2}", _bundleInfo.FullName, GetAbsoluteUri(_bundleInfo.Filename), _www.error);
                            }
                            _www.Dispose();

                            try
                            {
                                foreach (var kv in tasks)
                                {
                                    kv.Value.Dispose();
                                }
                            }
                            catch (Exception) { }
                            yield break;
                        }
                        _www.Dispose();
                    }

                    progress.CompletedSize = downloadedSize + tmpSize;
                    promise.UpdateProgress(progress);

                    yield return(null);
                }
            }
            promise.SetResult(true);
        }
コード例 #17
0
        protected override IEnumerator DoLoadAssetBundle(IProgressPromise <float, AssetBundle> promise)
        {
            if (!this.decryptor.AlgorithmName.Equals(this.BundleInfo.Encoding))
            {
                promise.UpdateProgress(0f);
                promise.SetException(new Exception(string.Format("The encryption algorithm '{0}' and decryption algorithm '{1}' does not match when decrypts Assetbundle {2}. ", this.BundleInfo.Encoding, this.decryptor.AlgorithmName, this.BundleInfo.Name)));
                yield break;
            }

            byte[] chiperData = null;
            string path       = this.GetAbsoluteUri();

#if UNITY_2017_1_OR_NEWER
            using (UnityWebRequest www = new UnityWebRequest(path))
            {
                www.downloadHandler = new DownloadHandlerBuffer();
#if UNITY_2018_1_OR_NEWER
                www.SendWebRequest();
#else
                www.Send();
#endif
                while (!www.isDone)
                {
                    if (www.downloadProgress >= 0)
                    {
                        promise.UpdateProgress(www.downloadProgress * WEIGHT);
                    }
                    yield return(null);
                }

                if (!string.IsNullOrEmpty(www.error))
                {
                    promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.Error:{2}", this.BundleInfo.Name, path, www.error)));
                    yield break;
                }

                chiperData = www.downloadHandler.data;
            }
#elif UNITY_5_4_OR_NEWER
            if (this.Uri.Scheme.Equals("jar", StringComparison.OrdinalIgnoreCase))
            {
                using (WWW www = new WWW(path))
                {
                    while (!www.isDone)
                    {
                        if (www.progress >= 0)
                        {
                            promise.UpdateProgress(www.progress * WEIGHT);
                        }
                        yield return(null);
                    }

                    if (!string.IsNullOrEmpty(www.error))
                    {
                        promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.Error:{2}", this.BundleInfo.Name, path, www.error)));
                        yield break;
                    }

                    chiperData = www.bytes;
                }
            }
            else
            {
                using (UnityWebRequest www = new UnityWebRequest(path))
                {
                    www.downloadHandler = new DownloadHandlerBuffer();
                    www.Send();
                    while (!www.isDone)
                    {
                        if (www.downloadProgress >= 0)
                        {
                            promise.UpdateProgress(www.downloadProgress * WEIGHT);
                        }
                        yield return(null);
                    }

                    if (!string.IsNullOrEmpty(www.error))
                    {
                        promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.Error:{2}", this.BundleInfo.Name, path, www.error)));
                        yield break;
                    }

                    chiperData = www.downloadHandler.data;
                }
            }
#else
            using (WWW www = new WWW(path))
            {
                while (!www.isDone)
                {
                    if (www.progress >= 0)
                    {
                        promise.UpdateProgress(www.progress * WEIGHT);
                    }
                    yield return(null);
                }

                if (!string.IsNullOrEmpty(www.error))
                {
                    promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.Error:{2}", this.BundleInfo.Name, path, www.error)));
                    yield break;
                }

                chiperData = www.bytes;
            }
#endif

            if (this.IsRemoteUri())
            {
                string fullname = BundleUtil.GetStorableDirectory() + this.BundleInfo.Filename;
                try
                {
                    FileInfo info = new FileInfo(fullname);
                    if (info.Exists)
                    {
                        info.Delete();
                    }

                    if (!info.Directory.Exists)
                    {
                        info.Directory.Create();
                    }

                    File.WriteAllBytes(info.FullName, chiperData);
                }
                catch (Exception e)
                {
                    if (log.IsWarnEnabled)
                    {
                        log.WarnFormat("Save AssetBundle '{0}' to the directory '{1}' failed.Reason:{2}", this.BundleInfo.FullName, fullname, e);
                    }
                }
            }

            byte[] textData = null;
            try
            {
                textData = this.decryptor.Decrypt(chiperData);
            }
            catch (Exception e)
            {
                promise.SetException(new Exception(string.Format("Failed to decrypt the AssetBundle '{0}' at the address '{1}'.Error:{2}", this.BundleInfo.Name, path, e)));
                yield break;
            }

            AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(textData);
            while (!request.isDone)
            {
                promise.UpdateProgress(WEIGHT + (1 - WEIGHT) * request.progress);
                yield return(null);
            }

            var assetBundle = request.assetBundle;
            if (assetBundle == null)
            {
                promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.", this.BundleInfo.Name, path)));
                yield break;
            }

            promise.UpdateProgress(1f);
            promise.SetResult(assetBundle);
        }
コード例 #18
0
        protected override IEnumerator DoLoadAssetBundle(IProgressPromise <float, AssetBundle> promise)
        {
            if (this.BundleInfo.IsEncrypted)
            {
                promise.UpdateProgress(0f);
                promise.SetException(new NotSupportedException(string.Format("The data of the AssetBundle named '{0}' is encrypted,use the CryptographBundleLoader to load,please.", this.BundleInfo.Name)));
                yield break;
            }

            string path = this.GetAbsolutePath();

#if UNITY_ANDROID && !UNITY_5_4_OR_NEWER
            if (this.Uri.Scheme.Equals("jar", StringComparison.OrdinalIgnoreCase))
            {
                promise.UpdateProgress(0f);
                promise.SetException(new NotSupportedException(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.It is not supported before the Unity3d 5.4.0 version.", this.BundleInfo.Name, path)));
                yield break;
            }
#endif
            float weight    = 0;
            long  totalSize = this.BundleInfo.FileSize;
            if (this.IsRemoteUri())
            {
                weight = WEIGHT;
                string fullname = BundleUtil.GetStorableDirectory() + this.BundleInfo.Filename;
                using (UnityWebRequest www = new UnityWebRequest(path))
                {
                    www.downloadHandler = new DownloadFileHandler(fullname);
#if UNITY_2018_1_OR_NEWER
                    www.SendWebRequest();
#else
                    www.Send();
#endif
                    while (!www.isDone)
                    {
                        if (www.downloadedBytes >= 0 && totalSize > 0)
                        {
                            promise.UpdateProgress(weight * (float)www.downloadedBytes / totalSize);
                        }
                        yield return(null);
                    }

                    if (!string.IsNullOrEmpty(www.error))
                    {
                        promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.Error:{2}", this.BundleInfo.Name, path, www.error)));
                        yield break;
                    }
                    path = fullname;
                }
            }

            AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(path);
            while (!request.isDone)
            {
                promise.UpdateProgress(weight + (1 - weight) * request.progress);
                yield return(null);
            }

            var assetBundle = request.assetBundle;
            if (assetBundle == null)
            {
                promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.", this.BundleInfo.Name, path)));
                yield break;
            }

            promise.UpdateProgress(1f);
            promise.SetResult(assetBundle);
        }
コード例 #19
0
        protected override IEnumerator DoDownloadBundles(IProgressPromise <Progress, bool> promise, List <BundleInfo> bundles)
        {
            long              totalSize      = 0;
            long              downloadedSize = 0;
            Progress          progress       = new Progress();
            List <BundleInfo> list           = new List <BundleInfo>();

            for (int i = 0; i < bundles.Count; i++)
            {
                var info = bundles[i];
                totalSize += info.FileSize;
                if (BundleUtil.Exists(info))
                {
                    downloadedSize += info.FileSize;
                    continue;
                }
                list.Add(info);
            }

            progress.TotalCount     = bundles.Count;
            progress.CompletedCount = bundles.Count - list.Count;
            progress.TotalSize      = totalSize;
            progress.CompletedSize  = downloadedSize;
            yield return(null);

            List <KeyValuePair <BundleInfo, UnityWebRequest> > tasks = new List <KeyValuePair <BundleInfo, UnityWebRequest> >();

            for (int i = 0; i < list.Count; i++)
            {
                BundleInfo bundleInfo = list[i];

                UnityWebRequest www;
                if (useCache && !bundleInfo.IsEncrypted)
                {
#if UNITY_2018_1_OR_NEWER
                    www = UnityWebRequestAssetBundle.GetAssetBundle(GetAbsoluteUri(bundleInfo.Filename), bundleInfo.Hash, 0);
#else
                    www = UnityWebRequest.GetAssetBundle(GetAbsoluteUri(bundleInfo.Filename), bundleInfo.Hash, 0);
#endif
                }
                else
                {
                    www = new UnityWebRequest(GetAbsoluteUri(bundleInfo.Filename));
                    www.downloadHandler = new DownloadHandlerBuffer();
                }

#if UNITY_2018_1_OR_NEWER
                www.SendWebRequest();
#else
                www.Send();
#endif
                tasks.Add(new KeyValuePair <BundleInfo, UnityWebRequest>(bundleInfo, www));

                while (tasks.Count >= this.MaxTaskCount || (i == list.Count - 1 && tasks.Count > 0))
                {
                    long tmpSize = 0;
                    for (int j = tasks.Count - 1; j >= 0; j--)
                    {
                        var             task        = tasks[j];
                        BundleInfo      _bundleInfo = task.Key;
                        UnityWebRequest _www        = task.Value;

                        if (!_www.isDone)
                        {
                            tmpSize += (long)Math.Max(0, _www.downloadedBytes);//the UnityWebRequest.downloadedProgress has a bug in android platform
                            continue;
                        }

                        progress.CompletedCount += 1;
                        tasks.RemoveAt(j);
                        downloadedSize += _bundleInfo.FileSize;
                        if (!string.IsNullOrEmpty(_www.error))
                        {
                            promise.SetException(new Exception(_www.error));
                            if (log.IsErrorEnabled)
                            {
                                log.ErrorFormat("Downloads AssetBundle '{0}' failure from the address '{1}'.Reason:{2}", _bundleInfo.FullName, GetAbsoluteUri(_bundleInfo.Filename), _www.error);
                            }
                            yield break;
                        }

                        try
                        {
                            if (useCache && !bundleInfo.IsEncrypted)
                            {
                                AssetBundle bundle = ((DownloadHandlerAssetBundle)_www.downloadHandler).assetBundle;
                                if (bundle != null)
                                {
                                    bundle.Unload(true);
                                }
                            }
                            else
                            {
                                string   fullname = BundleUtil.GetStorableDirectory() + _bundleInfo.Filename;
                                FileInfo info     = new FileInfo(fullname);
                                if (info.Exists)
                                {
                                    info.Delete();
                                }

                                if (!info.Directory.Exists)
                                {
                                    info.Directory.Create();
                                }

                                File.WriteAllBytes(info.FullName, _www.downloadHandler.data);
                            }
                        }
                        catch (Exception e)
                        {
                            promise.SetException(e);
                            if (log.IsErrorEnabled)
                            {
                                log.ErrorFormat("Downloads AssetBundle '{0}' failure from the address '{1}'.Reason:{2}", _bundleInfo.FullName, GetAbsoluteUri(_bundleInfo.Filename), e);
                            }
                            yield break;
                        }
                    }

                    progress.CompletedSize = downloadedSize + tmpSize;
                    promise.UpdateProgress(progress);

                    yield return(null);
                }
            }
            promise.SetResult(true);
        }
コード例 #20
0
        protected virtual IEnumerator DoLoadBundleAndDependencies(IProgressPromise <float, IBundle> promise)
        {
            this.startTime = Time.realtimeSinceStartup;
            List <IProgressResult <float, AssetBundle> > results    = new List <IProgressResult <float, AssetBundle> >();
            IProgressResult <float, AssetBundle>         currResult = this.LoadAssetBundle();

            if (!currResult.IsDone)
            {
                results.Add(currResult);
            }

            var all = this.GetDependencies(true);

            for (int i = 0; i < all.Count; i++)
            {
                var result = all[i].LoadAssetBundle();
                if (!result.IsDone)
                {
                    results.Add(result);
                }
            }

            bool  finished     = false;
            float progress     = 0f;
            float timeProgress = 0f;
            int   count        = results.Count;

            while (!finished && count > 0)
            {
                yield return(null);

                progress = 0f;
                finished = true;
                for (int i = 0; i < count; i++)
                {
                    var result = results[i];
                    if (!result.IsDone)
                    {
                        finished = false;
                    }

                    progress += result.Progress;
                }

                timeProgress = TIME_PROGRESS_WEIGHT * Mathf.Atan(Time.realtimeSinceStartup - this.startTime) * 2 / Mathf.PI;
                promise.UpdateProgress(timeProgress + (1.0f - TIME_PROGRESS_WEIGHT) * progress / count);
            }

            promise.UpdateProgress(1f);

            yield return(null);

            if (currResult.Exception != null)
            {
                promise.SetException(currResult.Exception);
            }
            else
            {
                promise.SetResult(this);
            }
        }
コード例 #21
0
        protected override IEnumerator DoLoadAssetBundle(IProgressPromise <float, AssetBundle> promise)
        {
            if (this.BundleInfo.IsEncrypted)
            {
                promise.UpdateProgress(0f);
                promise.SetException(new NotSupportedException(string.Format("The data of the AssetBundle named '{0}' is encrypted,use the CryptographBundleLoader to load,please.", this.BundleInfo.Name)));
                yield break;
            }

            AssetBundle assetBundle;
            string      path      = this.GetAbsoluteUri();
            long        totalSize = this.BundleInfo.FileSize;

            if (this.IsRemoteUri())
            {
                string fullname = BundleUtil.GetStorableDirectory() + this.BundleInfo.Filename;
                using (UnityWebRequest www = new UnityWebRequest(path))
                {
                    www.downloadHandler = new DownloadHandlerBuffer();
#if UNITY_2018_1_OR_NEWER
                    www.SendWebRequest();
#else
                    www.Send();
#endif
                    while (!www.isDone)
                    {
                        //if (www.downloadProgress >= 0)
                        //    promise.UpdateProgress(www.downloadProgress);
                        if (www.downloadedBytes >= 0 && totalSize > 0)
                        {
                            promise.UpdateProgress((float)www.downloadedBytes / totalSize);
                        }
                        yield return(null);
                    }

                    if (!string.IsNullOrEmpty(www.error))
                    {
                        promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.Error:{2}", this.BundleInfo.Name, path, www.error)));
                        yield break;
                    }

                    var data = www.downloadHandler.data;

                    try
                    {
                        FileInfo info = new FileInfo(fullname);
                        if (info.Exists)
                        {
                            info.Delete();
                        }

                        if (!info.Directory.Exists)
                        {
                            info.Directory.Create();
                        }

                        File.WriteAllBytes(info.FullName, data);
                    }
                    catch (Exception e)
                    {
                        if (log.IsWarnEnabled)
                        {
                            log.WarnFormat("Save AssetBundle '{0}' to the directory '{1}' failed.Reason:{2}", this.BundleInfo.FullName, fullname, e);
                        }
                    }
                }

                AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(fullname);
                while (!request.isDone)
                {
                    promise.UpdateProgress(request.progress);
                    yield return(null);
                }

                assetBundle = request.assetBundle;
                if (assetBundle == null)
                {
                    promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.", this.BundleInfo.Name, path)));
                    yield break;
                }

                promise.UpdateProgress(1f);
                promise.SetResult(assetBundle);
                yield break;
            }

#if UNITY_ANDROID && !UNITY_2017_1_OR_NEWER
            if (this.Uri.Scheme.Equals("jar", StringComparison.OrdinalIgnoreCase))
            {
                using (WWW www = useCache ? WWW.LoadFromCacheOrDownload(path, this.BundleInfo.Hash) : new WWW(path))
                {
                    while (!www.isDone)
                    {
                        if (www.progress >= 0)
                        {
                            promise.UpdateProgress(www.progress);
                        }
                        yield return(null);
                    }

                    if (!string.IsNullOrEmpty(www.error))
                    {
                        promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.Error:{2}", this.BundleInfo.Name, path, www.error)));
                        yield break;
                    }

                    assetBundle = www.assetBundle;
                }
            }
            else
#endif
            {
#if UNITY_2018_1_OR_NEWER
                using (UnityWebRequest www = useCache ? UnityWebRequestAssetBundle.GetAssetBundle(path, this.BundleInfo.Hash, 0) : UnityWebRequestAssetBundle.GetAssetBundle(path))
                {
                    www.SendWebRequest();
#else
                using (UnityWebRequest www = useCache ? UnityWebRequest.GetAssetBundle(path, this.BundleInfo.Hash, 0) : UnityWebRequest.GetAssetBundle(path))
                {
                    www.Send();
#endif
                    while (!www.isDone)
                    {
                        //if (www.downloadProgress >= 0)
                        //    promise.UpdateProgress(www.downloadProgress);
                        if (www.downloadedBytes >= 0 && totalSize > 0)
                        {
                            promise.UpdateProgress((float)www.downloadedBytes / totalSize);
                        }
                        yield return(null);
                    }

                    if (!string.IsNullOrEmpty(www.error))
                    {
                        promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.Error:{2}", this.BundleInfo.Name, path, www.error)));
                        yield break;
                    }

                    DownloadHandlerAssetBundle handler = (DownloadHandlerAssetBundle)www.downloadHandler;
                    assetBundle = handler.assetBundle;
                }
            }

            if (assetBundle == null)
            {
                promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.", this.BundleInfo.Name, path)));
                yield break;
            }

            promise.UpdateProgress(1f);
            promise.SetResult(assetBundle);
        }
    }
コード例 #22
0
        protected virtual IEnumerator DoLoadBundle(IProgressPromise <float, IBundle[]> promise, BundleInfo[] bundleInfos, int priority)
        {
            List <IBundle> bundles   = new List <IBundle>();
            Exception      exception = new Exception("unkown");
            List <IProgressResult <float, IBundle> > bundleResults = new List <IProgressResult <float, IBundle> >();

            for (int i = 0; i < bundleInfos.Length; i++)
            {
                try
                {
                    DefaultBundle bundle = this.GetOrCreateBundle(bundleInfos[i], priority);
                    IProgressResult <float, IBundle> bundleResult = bundle.Load();
                    bundleResult.Callbackable().OnCallback(r =>
                    {
                        if (r.Exception != null)
                        {
                            exception = r.Exception;
                            if (log.IsWarnEnabled)
                            {
                                log.WarnFormat("Loads Bundle failure! Error:{0}", r.Exception);
                            }
                        }
                        else
                        {
                            bundles.Add(new InternalBundleWrapper((DefaultBundle)r.Result));
                        }
                    });

                    if (!bundleResult.IsDone)
                    {
                        bundleResults.Add(bundleResult);
                    }
                }
                catch (Exception e)
                {
                    exception = e;
                    if (log.IsWarnEnabled)
                    {
                        log.WarnFormat("Loads Bundle '{0}' failure! Error:{1}", bundleInfos[i], e);
                    }
                }
            }

            bool  finished = false;
            float progress = 0f;
            int   count    = bundleResults.Count;

            while (!finished && count > 0)
            {
                yield return(null);

                progress = 0f;
                finished = true;
                for (int i = 0; i < count; i++)
                {
                    var result = bundleResults[i];
                    if (!result.IsDone)
                    {
                        finished = false;
                    }

                    progress += result.Progress;
                }
                promise.UpdateProgress(progress / count);
            }

            promise.UpdateProgress(1f);
            if (bundles.Count > 0)
            {
                promise.SetResult(bundles.ToArray());
            }
            else
            {
                promise.SetException(exception);
            }
        }
コード例 #23
0
        protected virtual IEnumerator DoDownloadManifest(string relativePath, IProgressPromise <Progress, BundleManifest> promise)
        {
            Progress progress = new Progress();

            promise.UpdateProgress(progress);
            byte[] data;
            string path = this.GetAbsoluteUri(relativePath);

#if UNITY_2017_1_OR_NEWER
            using (UnityWebRequest www = new UnityWebRequest(path))
            {
                www.downloadHandler = new DownloadHandlerBuffer();
#if UNITY_2018_1_OR_NEWER
                www.SendWebRequest();
#else
                www.Send();
#endif
                while (!www.isDone)
                {
                    if (www.downloadProgress >= 0)
                    {
                        if (progress.TotalSize <= 0)
                        {
                            progress.TotalSize = (long)(www.downloadedBytes / www.downloadProgress);
                        }
                        progress.CompletedSize = (long)www.downloadedBytes;
                        promise.UpdateProgress(progress);
                    }
                    yield return(null);
                }

                if (!string.IsNullOrEmpty(www.error))
                {
                    promise.SetException(new Exception(www.error));
                    yield break;
                }

                data = www.downloadHandler.data;
            }
#else
            using (WWW www = new WWW(path))
            {
                while (!www.isDone)
                {
                    if (www.bytesDownloaded > 0f)
                    {
                        if (progress.TotalSize <= 0)
                        {
                            progress.TotalSize = (long)(www.bytesDownloaded / www.progress);
                        }
                        progress.CompletedSize = www.bytesDownloaded;
                        promise.UpdateProgress(progress);
                    }
                    yield return(null);
                }

                progress.CompletedSize = www.bytesDownloaded;
                promise.UpdateProgress(progress);

                if (!string.IsNullOrEmpty(www.error))
                {
                    promise.SetException(new Exception(www.error));
                    yield break;
                }

                data = www.bytes;
            }
#endif

            try
            {
                BundleManifest manifest = BundleManifest.Parse(Encoding.UTF8.GetString(data));

                FileInfo file = new FileInfo(BundleUtil.GetReadOnlyDirectory() + relativePath);
                if (file.Exists)
                {
                    FileInfo bakFile = new FileInfo(BundleUtil.GetReadOnlyDirectory() + relativePath + ".bak");
                    if (bakFile.Exists)
                    {
                        bakFile.Delete();
                    }

                    file.CopyTo(bakFile.FullName);
                }

                if (!file.Directory.Exists)
                {
                    file.Directory.Create();
                }

                File.WriteAllBytes(file.FullName, data);
                promise.SetResult(manifest);
            }
            catch (IOException e)
            {
                promise.SetException(e);
            }
        }
コード例 #24
0
        protected override IEnumerator DoLoadAssetBundle(IProgressPromise <float, AssetBundle> promise)
        {
            if (this.BundleInfo.IsEncrypted)
            {
                promise.UpdateProgress(0f);
                promise.SetException(new NotSupportedException(string.Format("The data of the AssetBundle named '{0}' is encrypted,use the CryptographBundleLoader to load,please.", this.BundleInfo.Name)));
                yield break;
            }

            AssetBundle assetBundle;
            string      path = this.GetAbsoluteUri();

#if UNITY_ANDROID && !UNITY_2017_1_OR_NEWER
            if (this.Uri.Scheme.Equals("jar", StringComparison.OrdinalIgnoreCase))
            {
                using (WWW www = useCache ? WWW.LoadFromCacheOrDownload(path, this.BundleInfo.Hash) : new WWW(path))
                {
                    while (!www.isDone)
                    {
                        if (www.progress >= 0)
                        {
                            promise.UpdateProgress(www.progress);
                        }
                        yield return(null);
                    }

                    if (!string.IsNullOrEmpty(www.error))
                    {
                        promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.Error:{2}", this.BundleInfo.Name, path, www.error)));
                        yield break;
                    }

                    assetBundle = www.assetBundle;
                }
            }
            else
#endif
            {
#if UNITY_2018_1_OR_NEWER
                using (UnityWebRequest www = useCache ? UnityWebRequestAssetBundle.GetAssetBundle(path, this.BundleInfo.Hash, 0) : UnityWebRequestAssetBundle.GetAssetBundle(path))
                {
                    www.SendWebRequest();
#else
                using (UnityWebRequest www = useCache ? UnityWebRequest.GetAssetBundle(path, this.BundleInfo.Hash, 0) : UnityWebRequest.GetAssetBundle(path))
                {
                    www.Send();
#endif
                    while (!www.isDone)
                    {
                        if (www.downloadProgress >= 0)
                        {
                            promise.UpdateProgress(www.downloadProgress);
                        }
                        yield return(null);
                    }

                    if (!string.IsNullOrEmpty(www.error))
                    {
                        promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.Error:{2}", this.BundleInfo.Name, path, www.error)));
                        yield break;
                    }

                    DownloadHandlerAssetBundle handler = (DownloadHandlerAssetBundle)www.downloadHandler;
                    assetBundle = handler.assetBundle;
                }
            }

            if (assetBundle == null)
            {
                promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.", this.BundleInfo.Name, path)));
                yield break;
            }

            promise.UpdateProgress(1f);
            promise.SetResult(assetBundle);
        }
    }
コード例 #25
0
        protected virtual IEnumerator DoDownloadFileAsync(ResourceInfo[] infos, IProgressPromise <ProgressInfo> promise)
        {
            long totalSize      = 0;
            long downloadedSize = 0;
            List <ResourceInfo> downloadList = new List <ResourceInfo>();

            for (int i = 0; i < infos.Length; i++)
            {
                var info     = infos[i];
                var fileInfo = info.FileInfo;

                if (info.FileSize < 0)
                {
                    if (fileInfo.Exists)
                    {
                        info.FileSize = fileInfo.Length;
                    }
                    else
                    {
                        using (UnityWebRequest www = UnityWebRequest.Head(this.GetAbsoluteUri(info.Path).AbsoluteUri))
                        {
#if UNITY_2018_1_OR_NEWER
                            yield return(www.SendWebRequest());
#else
                            yield return(www.Send());
#endif
                            string contentLength = www.GetResponseHeader("Content-Length");
                            info.FileSize = long.Parse(contentLength);
                        }
                    }
                }

                totalSize += info.FileSize;
                if (fileInfo.Exists)
                {
                    downloadedSize += info.FileSize;
                }
                else
                {
                    downloadList.Add(info);
                }
            }

            ProgressInfo progressInfo = new ProgressInfo();
            progressInfo.TotalCount     = infos.Length;
            progressInfo.CompletedCount = infos.Length - downloadList.Count;
            progressInfo.TotalSize      = totalSize;
            progressInfo.CompletedSize  = downloadedSize;

            yield return(null);

            List <KeyValuePair <ResourceInfo, UnityWebRequest> > tasks = new List <KeyValuePair <ResourceInfo, UnityWebRequest> >();
            for (int i = 0; i < downloadList.Count; i++)
            {
                ResourceInfo info     = downloadList[i];
                Uri          path     = info.Path;
                FileInfo     fileInfo = info.FileInfo;
                if (!fileInfo.Directory.Exists)
                {
                    fileInfo.Directory.Create();
                }

                UnityWebRequest www = new UnityWebRequest(this.GetAbsoluteUri(path).AbsoluteUri);
                www.downloadHandler = new DownloadFileHandler(fileInfo);

#if UNITY_2018_1_OR_NEWER
                www.SendWebRequest();
#else
                www.Send();
#endif
                tasks.Add(new KeyValuePair <ResourceInfo, UnityWebRequest>(info, www));

                while (tasks.Count >= this.MaxTaskCount || (i == downloadList.Count - 1 && tasks.Count > 0))
                {
                    long tmpSize = 0;
                    for (int j = tasks.Count - 1; j >= 0; j--)
                    {
                        var             task  = tasks[j];
                        ResourceInfo    _info = task.Key;
                        UnityWebRequest _www  = task.Value;

                        if (!_www.isDone)
                        {
                            tmpSize += (long)Math.Max(0, _www.downloadedBytes);//the UnityWebRequest.downloadedProgress has a bug in android platform
                            continue;
                        }

                        progressInfo.CompletedCount += 1;
                        tasks.RemoveAt(j);
                        downloadedSize += _info.FileSize;
#if UNITY_2018_1_OR_NEWER
                        if (_www.isNetworkError)
#else
                        if (_www.isError)
#endif
                        {
                            promise.SetException(new Exception(_www.error));
                            if (log.IsErrorEnabled)
                            {
                                log.ErrorFormat("Downloads file '{0}' failure from the address '{1}'.Reason:{2}", _info.FileInfo.FullName, GetAbsoluteUri(_info.Path), _www.error);
                            }
                            _www.Dispose();

                            try
                            {
                                foreach (var kv in tasks)
                                {
                                    kv.Value.Dispose();
                                }
                            }
                            catch (Exception) { }
                            yield break;
                        }
                        _www.Dispose();
                    }

                    progressInfo.CompletedSize = downloadedSize + tmpSize;
                    promise.UpdateProgress(progressInfo);
                    yield return(null);
                }
            }
            promise.SetResult(infos);
        }
コード例 #26
0
        protected virtual IEnumerator DoLoadAssetsToMapAsync <T>(IProgressPromise <float, Dictionary <string, T> > promise, params string[] paths) where T : Object
        {
            Dictionary <string, T> results             = new Dictionary <string, T>();
            Dictionary <string, List <string> > groups = new Dictionary <string, List <string> >();
            Dictionary <string, string>         assetNameAndPathMapping = new Dictionary <string, string>();
            List <string> bundleNames = new List <string>();

            for (int i = 0; i < paths.Length; i++)
            {
                var           path     = paths[i];
                AssetPathInfo pathInfo = this.pathInfoParser.Parse(path);
                if (pathInfo == null || pathInfo.BundleName == null)
                {
                    if (log.IsWarnEnabled)
                    {
                        log.WarnFormat("Not found the AssetBundle or parses the path info '{0}' failure.", path);
                    }
                    continue;
                }

                var asset = this.GetCache <T>(path);
                if (asset != null)
                {
                    if (!results.ContainsKey(path))
                    {
                        results.Add(path, asset);
                    }
                    continue;
                }

                List <string> list = null;
                if (!groups.TryGetValue(pathInfo.BundleName, out list))
                {
                    list = new List <string>();
                    groups.Add(pathInfo.BundleName, list);
                    bundleNames.Add(pathInfo.BundleName);
                }

                if (!list.Contains(pathInfo.AssetName))
                {
                    list.Add(pathInfo.AssetName);
                    assetNameAndPathMapping[pathInfo.AssetName] = path;
                }
            }

            if (bundleNames.Count <= 0)
            {
                promise.UpdateProgress(1f);
                promise.SetResult(results);
                yield break;
            }

            IProgressResult <float, IBundle[]> bundleResult = this.LoadBundle(bundleNames.ToArray(), 0);
            float weight = bundleResult.IsDone ? 0f : DEFAULT_WEIGHT;

            bundleResult.Callbackable().OnProgressCallback(p => promise.UpdateProgress(weight * p));

            yield return(bundleResult.WaitForDone());

            if (bundleResult.Exception != null)
            {
                promise.SetException(bundleResult.Exception);
                yield break;
            }

            Dictionary <string, IProgressResult <float, Dictionary <string, T> > > assetResults = new Dictionary <string, IProgressResult <float, Dictionary <string, T> > >();

            IBundle[] bundles = bundleResult.Result;
            for (int i = 0; i < bundles.Length; i++)
            {
                using (IBundle bundle = bundles[i])
                {
                    if (!groups.ContainsKey(bundle.Name))
                    {
                        continue;
                    }

                    List <string> assetNames = groups[bundle.Name];
                    if (assetNames == null || assetNames.Count < 0)
                    {
                        continue;
                    }

                    IProgressResult <float, Dictionary <string, T> > assetResult = bundle.LoadAssetsToMapAsync <T>(assetNames.ToArray());
                    assetResult.Callbackable().OnCallback(ar =>
                    {
                        if (ar.Exception != null)
                        {
                            return;
                        }

                        foreach (var kv in ar.Result)
                        {
                            string key = assetNameAndPathMapping[kv.Key];
                            var value  = kv.Value;
                            if (!results.ContainsKey(key))
                            {
                                results.Add(key, value);
                            }
                        }
                    });
                    assetResults.Add(bundle.Name, assetResult);
                }
            }

            if (assetResults.Count < 0)
            {
                promise.UpdateProgress(1f);
                promise.SetResult(results);
                yield break;
            }

            bool  finished   = false;
            float progress   = 0f;
            int   assetCount = assetResults.Count;

            do
            {
                yield return(waitForSeconds);

                finished = true;
                progress = 0f;

                var assetEnumerator = assetResults.GetEnumerator();
                while (assetEnumerator.MoveNext())
                {
                    var kv          = assetEnumerator.Current;
                    var assetResult = kv.Value;
                    if (!assetResult.IsDone)
                    {
                        finished = false;
                    }

                    progress += (1f - weight) * assetResult.Progress / assetCount;
                }

                promise.UpdateProgress(weight + progress);
            } while (!finished);

            promise.UpdateProgress(1f);
            promise.SetResult(results);
        }
コード例 #27
0
        protected override IEnumerator DoDownloadBundles(IProgressPromise <Progress, bool> promise, List <BundleInfo> bundles)
        {
            long              totalSize      = 0;
            long              downloadedSize = 0;
            Progress          progress       = new Progress();
            List <BundleInfo> list           = new List <BundleInfo>();

            for (int i = 0; i < bundles.Count; i++)
            {
                var info = bundles[i];
                totalSize += info.FileSize;
                if (BundleUtil.Exists(info))
                {
                    downloadedSize += info.FileSize;
                    continue;
                }
                list.Add(info);
            }

            progress.TotalCount     = bundles.Count;
            progress.CompletedCount = bundles.Count - list.Count;
            progress.TotalSize      = totalSize;
            progress.CompletedSize  = downloadedSize;
            yield return(null);

            List <KeyValuePair <BundleInfo, WWW> > tasks = new List <KeyValuePair <BundleInfo, WWW> >();

            for (int i = 0; i < list.Count; i++)
            {
                BundleInfo bundleInfo = list[i];
                WWW        www        = (useCache && !bundleInfo.IsEncrypted) ? WWW.LoadFromCacheOrDownload(GetAbsoluteUri(bundleInfo.Filename), bundleInfo.Hash) : new WWW(GetAbsoluteUri(bundleInfo.Filename));
                tasks.Add(new KeyValuePair <BundleInfo, WWW>(bundleInfo, www));

                while (tasks.Count >= this.MaxTaskCount || (i == list.Count - 1 && tasks.Count > 0))
                {
                    long tmpSize = 0;
                    for (int j = tasks.Count - 1; j >= 0; j--)
                    {
                        var        task        = tasks[j];
                        BundleInfo _bundleInfo = task.Key;
                        WWW        _www        = task.Value;

                        if (!_www.isDone)
                        {
                            tmpSize += Math.Max(0, (long)(_www.progress * _bundleInfo.FileSize));
                            continue;
                        }

                        progress.CompletedCount += 1;
                        tasks.RemoveAt(j);
                        downloadedSize += _bundleInfo.FileSize;
                        if (!string.IsNullOrEmpty(_www.error))
                        {
                            promise.SetException(new Exception(_www.error));
                            if (log.IsErrorEnabled)
                            {
                                log.ErrorFormat("Downloads AssetBundle '{0}' failure from the address '{1}'.Reason:{2}", _bundleInfo.FullName, GetAbsoluteUri(_bundleInfo.Filename), _www.error);
                            }
                            yield break;
                        }

                        try
                        {
                            if (useCache && !_bundleInfo.IsEncrypted)
                            {
                                AssetBundle bundle = _www.assetBundle;
                                if (bundle != null)
                                {
                                    bundle.Unload(true);
                                }
                            }
                            else
                            {
                                string   fullname = BundleUtil.GetStorableDirectory() + _bundleInfo.Filename;
                                FileInfo info     = new FileInfo(fullname);
                                if (info.Exists)
                                {
                                    info.Delete();
                                }

                                if (!info.Directory.Exists)
                                {
                                    info.Directory.Create();
                                }

                                File.WriteAllBytes(info.FullName, _www.bytes);
                            }
                        }
                        catch (Exception e)
                        {
                            promise.SetException(e);
                            if (log.IsErrorEnabled)
                            {
                                log.ErrorFormat("Downloads AssetBundle '{0}' failure from the address '{1}'.Reason:{2}", _bundleInfo.FullName, GetAbsoluteUri(_bundleInfo.Filename), e);
                            }
                            yield break;
                        }
                    }

                    progress.CompletedSize = downloadedSize + tmpSize;
                    promise.UpdateProgress(progress);

                    yield return(null);
                }
            }
            promise.SetResult(true);
        }
コード例 #28
0
        protected override IEnumerator DoLoadAssetBundle(IProgressPromise <float, AssetBundle> promise)
        {
            if (this.BundleInfo.IsEncrypted)
            {
                promise.UpdateProgress(0f);
                promise.SetException(new NotSupportedException(string.Format("The data of the AssetBundle named '{0}' is encrypted,use the CryptographBundleLoader to load,please.", this.BundleInfo.Name)));
                yield break;
            }

            string path = this.GetAbsoluteUri();

            using (WWW www = useCache ? WWW.LoadFromCacheOrDownload(path, this.BundleInfo.Hash) : new WWW(path))
            {
                while (!www.isDone)
                {
                    if (www.progress >= 0)
                    {
                        promise.UpdateProgress(www.progress);
                    }
                    yield return(null);
                }

                if (!string.IsNullOrEmpty(www.error))
                {
                    promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.Error:{2}", this.BundleInfo.Name, path, www.error)));
                    yield break;
                }

                var assetBundle = www.assetBundle;
                if (assetBundle == null)
                {
                    promise.SetException(new Exception(string.Format("Failed to load the AssetBundle '{0}' at the address '{1}'.", this.BundleInfo.Name, path)));
                    yield break;
                }

                if (!useCache && this.IsRemoteUri())
                {
                    string fullname = BundleUtil.GetStorableDirectory() + this.BundleInfo.Filename;
                    try
                    {
                        FileInfo info = new FileInfo(fullname);
                        if (info.Exists)
                        {
                            info.Delete();
                        }

                        if (!info.Directory.Exists)
                        {
                            info.Directory.Create();
                        }

                        File.WriteAllBytes(info.FullName, www.bytes);
                    }
                    catch (Exception e)
                    {
                        if (log.IsWarnEnabled)
                        {
                            log.WarnFormat("Save AssetBundle '{0}' to the directory '{1}' failed.Reason:{2}", this.BundleInfo.FullName, fullname, e);
                        }
                    }
                }
                promise.UpdateProgress(1f);
                promise.SetResult(assetBundle);
            }
        }
コード例 #29
0
        protected virtual IEnumerator DoDownloadManifest(string relativePath, IProgressPromise <Progress, BundleManifest> promise)
        {
            Progress progress = new Progress();

            promise.UpdateProgress(progress);
            using (WWW www = new WWW(this.GetAbsoluteUri(relativePath)))
            {
                while (!www.isDone)
                {
                    if (www.bytesDownloaded > 0f)
                    {
                        if (progress.TotalSize <= 0)
                        {
                            progress.TotalSize = www.size;
                        }
                        progress.CompletedSize = www.bytesDownloaded;
                        promise.UpdateProgress(progress);
                    }
                    yield return(null);
                }

                progress.CompletedSize = www.bytesDownloaded;
                promise.UpdateProgress(progress);

                if (!string.IsNullOrEmpty(www.error))
                {
                    promise.SetException(new Exception(www.error));
                    yield break;
                }

                try
                {
                    byte[]         data     = www.bytes;
                    BundleManifest manifest = BundleManifest.Parse(Encoding.UTF8.GetString(data));

                    FileInfo file = new FileInfo(BundleUtil.GetStorableDirectory() + relativePath);
                    if (file.Exists)
                    {
                        FileInfo bakFile = new FileInfo(BundleUtil.GetStorableDirectory() + relativePath + ".bak");
                        if (bakFile.Exists)
                        {
                            bakFile.Delete();
                        }

                        file.CopyTo(bakFile.FullName);
                    }

                    if (!file.Directory.Exists)
                    {
                        file.Directory.Create();
                    }

                    File.WriteAllBytes(file.FullName, data);
                    promise.SetResult(manifest);
                }
                catch (IOException e)
                {
                    promise.SetException(e);
                }
            }
        }
コード例 #30
0
        protected virtual IEnumerator DoDownloadFileAsync(ResourceInfo[] infos, IProgressPromise <ProgressInfo> promise)
        {
            long totalSize      = 0;
            long downloadedSize = 0;
            List <ResourceInfo> downloadList = new List <ResourceInfo>();

            foreach (var info in infos)
            {
                var fileInfo = info.FileInfo;

                if (info.FileSize < 0)
                {
                    if (fileInfo.Exists)
                    {
                        info.FileSize = fileInfo.Length;
                    }
                    else
                    {
                        using (UnityWebRequest www = UnityWebRequest.Head(info.Path))
                        {
                            yield return(www.SendWebRequest());

                            string contentLength = www.GetResponseHeader("Content-Length");
                            if (!string.IsNullOrEmpty(contentLength))
                            {
                                info.FileSize = long.Parse(contentLength);
                            }
                        }
                    }
                }

                totalSize += info.FileSize;
                if (fileInfo.Exists)
                {
                    downloadedSize += info.FileSize;
                }
                else
                {
                    downloadList.Add(info);
                }
            }

            ProgressInfo progressInfo = new ProgressInfo
            {
                TotalCount     = infos.Length,
                CompletedCount = infos.Length - downloadList.Count,
                TotalSize      = totalSize,
                CompletedSize  = downloadedSize
            };

            yield return(null);

            List <KeyValuePair <ResourceInfo, UnityWebRequest> > tasks =
                new List <KeyValuePair <ResourceInfo, UnityWebRequest> >();

            for (int i = 0; i < downloadList.Count; i++)
            {
                ResourceInfo info     = downloadList[i];
                var          path     = info.Path;
                FileInfo     fileInfo = info.FileInfo;
                if (fileInfo.Directory != null && !fileInfo.Directory.Exists)
                {
                    fileInfo.Directory.Create();
                }

                UnityWebRequest www = new UnityWebRequest(path);
                www.downloadHandler = new DownloadFileHandler(fileInfo);

                www.SendWebRequest();
                tasks.Add(new KeyValuePair <ResourceInfo, UnityWebRequest>(info, www));

                while (tasks.Count >= this.MaxTaskCount || (i == downloadList.Count - 1 && tasks.Count > 0))
                {
                    long tmpSize = 0;
                    for (int j = tasks.Count - 1; j >= 0; j--)
                    {
                        var             task  = tasks[j];
                        ResourceInfo    _info = task.Key;
                        UnityWebRequest _www  = task.Value;

                        if (!_www.isDone)
                        {
                            tmpSize += (long)Math.Max(0,
                                                      _www.downloadedBytes); //the UnityWebRequest.downloadedProgress has a bug in android platform
                            continue;
                        }

                        progressInfo.CompletedCount += 1;
                        tasks.RemoveAt(j);
                        downloadedSize += _info.FileSize;
                        if (_www.isNetworkError || _www.isHttpError)
                        {
                            promise.SetException(new Exception(_www.error));
                            Log.Error(
                                $"Downloads file '{_info.FileInfo.FullName}' failure from the address '{(_info.Path)}'.Reason:{_www.error}");
                            _www.Dispose();

                            try
                            {
                                foreach (var kv in tasks)
                                {
                                    kv.Value.Dispose();
                                }
                            }
                            catch (Exception)
                            {
                            }

                            yield break;
                        }

                        _www.Dispose();
                    }

                    progressInfo.CompletedSize = downloadedSize + tmpSize;
                    promise.UpdateProgress(progressInfo);
                    yield return(null);
                }
            }

            promise.SetResult(infos);
        }