123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442 |
- using System;
- using System.Collections;
- using UnityEngine;
- #if !UniRxLibrary
- using ObservableUnity = UniRx.Observable;
- #endif
- #if UNITY_2018_3_OR_NEWER
- #pragma warning disable CS0618
- #endif
- namespace UniRx
- {
- using System.Threading;
- #if !(UNITY_METRO || UNITY_WP8) && (UNITY_4_4 || UNITY_4_3 || UNITY_4_2 || UNITY_4_1 || UNITY_4_0_1 || UNITY_4_0 || UNITY_3_5 || UNITY_3_4 || UNITY_3_3 || UNITY_3_2 || UNITY_3_1 || UNITY_3_0_0 || UNITY_3_0 || UNITY_2_6_1 || UNITY_2_6)
- // Fallback for Unity versions below 4.5
- using Hash = System.Collections.Hashtable;
- using HashEntry = System.Collections.DictionaryEntry;
- #else
- // Unity 4.5 release notes:
- // WWW: deprecated 'WWW(string url, byte[] postData, Hashtable headers)',
- // use 'public WWW(string url, byte[] postData, Dictionary<string, string> headers)' instead.
- using Hash = System.Collections.Generic.Dictionary<string, string>;
- using HashEntry = System.Collections.Generic.KeyValuePair<string, string>;
- #endif
- #if UNITY_2018_3_OR_NEWER
- [Obsolete("Use UnityWebRequest, a fully featured replacement which is more efficient and has additional features")]
- #endif
- public static partial class ObservableWWW
- {
- public static IObservable<string> Get(string url, Hash headers = null, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<string>((observer, cancellation) => FetchText(new WWW(url, null, (headers ?? new Hash())), observer, progress, cancellation));
- }
- public static IObservable<byte[]> GetAndGetBytes(string url, Hash headers = null, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<byte[]>((observer, cancellation) => FetchBytes(new WWW(url, null, (headers ?? new Hash())), observer, progress, cancellation));
- }
- public static IObservable<WWW> GetWWW(string url, Hash headers = null, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<WWW>((observer, cancellation) => Fetch(new WWW(url, null, (headers ?? new Hash())), observer, progress, cancellation));
- }
- public static IObservable<string> Post(string url, byte[] postData, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<string>((observer, cancellation) => FetchText(new WWW(url, postData), observer, progress, cancellation));
- }
- public static IObservable<string> Post(string url, byte[] postData, Hash headers, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<string>((observer, cancellation) => FetchText(new WWW(url, postData, headers), observer, progress, cancellation));
- }
- public static IObservable<string> Post(string url, WWWForm content, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<string>((observer, cancellation) => FetchText(new WWW(url, content), observer, progress, cancellation));
- }
- public static IObservable<string> Post(string url, WWWForm content, Hash headers, IProgress<float> progress = null)
- {
- var contentHeaders = content.headers;
- return ObservableUnity.FromCoroutine<string>((observer, cancellation) => FetchText(new WWW(url, content.data, MergeHash(contentHeaders, headers)), observer, progress, cancellation));
- }
- public static IObservable<byte[]> PostAndGetBytes(string url, byte[] postData, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<byte[]>((observer, cancellation) => FetchBytes(new WWW(url, postData), observer, progress, cancellation));
- }
- public static IObservable<byte[]> PostAndGetBytes(string url, byte[] postData, Hash headers, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<byte[]>((observer, cancellation) => FetchBytes(new WWW(url, postData, headers), observer, progress, cancellation));
- }
- public static IObservable<byte[]> PostAndGetBytes(string url, WWWForm content, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<byte[]>((observer, cancellation) => FetchBytes(new WWW(url, content), observer, progress, cancellation));
- }
- public static IObservable<byte[]> PostAndGetBytes(string url, WWWForm content, Hash headers, IProgress<float> progress = null)
- {
- var contentHeaders = content.headers;
- return ObservableUnity.FromCoroutine<byte[]>((observer, cancellation) => FetchBytes(new WWW(url, content.data, MergeHash(contentHeaders, headers)), observer, progress, cancellation));
- }
- public static IObservable<WWW> PostWWW(string url, byte[] postData, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<WWW>((observer, cancellation) => Fetch(new WWW(url, postData), observer, progress, cancellation));
- }
- public static IObservable<WWW> PostWWW(string url, byte[] postData, Hash headers, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<WWW>((observer, cancellation) => Fetch(new WWW(url, postData, headers), observer, progress, cancellation));
- }
- public static IObservable<WWW> PostWWW(string url, WWWForm content, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<WWW>((observer, cancellation) => Fetch(new WWW(url, content), observer, progress, cancellation));
- }
- public static IObservable<WWW> PostWWW(string url, WWWForm content, Hash headers, IProgress<float> progress = null)
- {
- var contentHeaders = content.headers;
- return ObservableUnity.FromCoroutine<WWW>((observer, cancellation) => Fetch(new WWW(url, content.data, MergeHash(contentHeaders, headers)), observer, progress, cancellation));
- }
- public static IObservable<AssetBundle> LoadFromCacheOrDownload(string url, int version, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<AssetBundle>((observer, cancellation) => FetchAssetBundle(WWW.LoadFromCacheOrDownload(url, version), observer, progress, cancellation));
- }
- public static IObservable<AssetBundle> LoadFromCacheOrDownload(string url, int version, uint crc, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<AssetBundle>((observer, cancellation) => FetchAssetBundle(WWW.LoadFromCacheOrDownload(url, version, crc), observer, progress, cancellation));
- }
- // over Unity5 supports Hash128
- #if !(UNITY_4_7 || UNITY_4_6 || UNITY_4_5 || UNITY_4_4 || UNITY_4_3 || UNITY_4_2 || UNITY_4_1 || UNITY_4_0_1 || UNITY_4_0 || UNITY_3_5 || UNITY_3_4 || UNITY_3_3 || UNITY_3_2 || UNITY_3_1 || UNITY_3_0_0 || UNITY_3_0 || UNITY_2_6_1 || UNITY_2_6)
- public static IObservable<AssetBundle> LoadFromCacheOrDownload(string url, Hash128 hash128, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<AssetBundle>((observer, cancellation) => FetchAssetBundle(WWW.LoadFromCacheOrDownload(url, hash128), observer, progress, cancellation));
- }
- public static IObservable<AssetBundle> LoadFromCacheOrDownload(string url, Hash128 hash128, uint crc, IProgress<float> progress = null)
- {
- return ObservableUnity.FromCoroutine<AssetBundle>((observer, cancellation) => FetchAssetBundle(WWW.LoadFromCacheOrDownload(url, hash128, crc), observer, progress, cancellation));
- }
- #endif
- // over 4.5, Hash define is Dictionary.
- // below Unity 4.5, WWW only supports Hashtable.
- // Unity 4.5, 4.6 WWW supports Dictionary and [Obsolete]Hashtable but WWWForm.content is Hashtable.
- // Unity 5.0 WWW only supports Dictionary and WWWForm.content is also Dictionary.
- #if !(UNITY_METRO || UNITY_WP8) && (UNITY_4_5 || UNITY_4_6 || UNITY_4_7)
- static Hash MergeHash(Hashtable wwwFormHeaders, Hash externalHeaders)
- {
- var newHeaders = new Hash();
- foreach (DictionaryEntry item in wwwFormHeaders)
- {
- newHeaders[item.Key.ToString()] = item.Value.ToString();
- }
- foreach (HashEntry item in externalHeaders)
- {
- newHeaders[item.Key] = item.Value;
- }
- return newHeaders;
- }
- #else
- static Hash MergeHash(Hash wwwFormHeaders, Hash externalHeaders)
- {
- foreach (HashEntry item in externalHeaders)
- {
- wwwFormHeaders[item.Key] = item.Value;
- }
- return wwwFormHeaders;
- }
- #endif
- static IEnumerator Fetch(WWW www, IObserver<WWW> observer, IProgress<float> reportProgress, CancellationToken cancel)
- {
- using (www)
- {
- if (reportProgress != null)
- {
- while (!www.isDone && !cancel.IsCancellationRequested)
- {
- try
- {
- reportProgress.Report(www.progress);
- }
- catch (Exception ex)
- {
- observer.OnError(ex);
- yield break;
- }
- yield return null;
- }
- }
- else
- {
- if (!www.isDone)
- {
- yield return www;
- }
- }
- if (cancel.IsCancellationRequested)
- {
- yield break;
- }
- if (reportProgress != null)
- {
- try
- {
- reportProgress.Report(www.progress);
- }
- catch (Exception ex)
- {
- observer.OnError(ex);
- yield break;
- }
- }
- if (!string.IsNullOrEmpty(www.error))
- {
- observer.OnError(new WWWErrorException(www, www.text));
- }
- else
- {
- observer.OnNext(www);
- observer.OnCompleted();
- }
- }
- }
- static IEnumerator FetchText(WWW www, IObserver<string> observer, IProgress<float> reportProgress, CancellationToken cancel)
- {
- using (www)
- {
- if (reportProgress != null)
- {
- while (!www.isDone && !cancel.IsCancellationRequested)
- {
- try
- {
- reportProgress.Report(www.progress);
- }
- catch (Exception ex)
- {
- observer.OnError(ex);
- yield break;
- }
- yield return null;
- }
- }
- else
- {
- if (!www.isDone)
- {
- yield return www;
- }
- }
- if (cancel.IsCancellationRequested)
- {
- yield break;
- }
- if (reportProgress != null)
- {
- try
- {
- reportProgress.Report(www.progress);
- }
- catch (Exception ex)
- {
- observer.OnError(ex);
- yield break;
- }
- }
- if (!string.IsNullOrEmpty(www.error))
- {
- observer.OnError(new WWWErrorException(www, www.text));
- }
- else
- {
- observer.OnNext(www.text);
- observer.OnCompleted();
- }
- }
- }
- static IEnumerator FetchBytes(WWW www, IObserver<byte[]> observer, IProgress<float> reportProgress, CancellationToken cancel)
- {
- using (www)
- {
- if (reportProgress != null)
- {
- while (!www.isDone && !cancel.IsCancellationRequested)
- {
- try
- {
- reportProgress.Report(www.progress);
- }
- catch (Exception ex)
- {
- observer.OnError(ex);
- yield break;
- }
- yield return null;
- }
- }
- else
- {
- if (!www.isDone)
- {
- yield return www;
- }
- }
- if (cancel.IsCancellationRequested)
- {
- yield break;
- }
- if (reportProgress != null)
- {
- try
- {
- reportProgress.Report(www.progress);
- }
- catch (Exception ex)
- {
- observer.OnError(ex);
- yield break;
- }
- }
- if (!string.IsNullOrEmpty(www.error))
- {
- observer.OnError(new WWWErrorException(www, www.text));
- }
- else
- {
- observer.OnNext(www.bytes);
- observer.OnCompleted();
- }
- }
- }
- static IEnumerator FetchAssetBundle(WWW www, IObserver<AssetBundle> observer, IProgress<float> reportProgress, CancellationToken cancel)
- {
- using (www)
- {
- if (reportProgress != null)
- {
- while (!www.isDone && !cancel.IsCancellationRequested)
- {
- try
- {
- reportProgress.Report(www.progress);
- }
- catch (Exception ex)
- {
- observer.OnError(ex);
- yield break;
- }
- yield return null;
- }
- }
- else
- {
- if (!www.isDone)
- {
- yield return www;
- }
- }
- if (cancel.IsCancellationRequested)
- {
- yield break;
- }
- if (reportProgress != null)
- {
- try
- {
- reportProgress.Report(www.progress);
- }
- catch (Exception ex)
- {
- observer.OnError(ex);
- yield break;
- }
- }
- if (!string.IsNullOrEmpty(www.error))
- {
- observer.OnError(new WWWErrorException(www, ""));
- }
- else
- {
- observer.OnNext(www.assetBundle);
- observer.OnCompleted();
- }
- }
- }
- }
- public class WWWErrorException : Exception
- {
- public string RawErrorMessage { get; private set; }
- public bool HasResponse { get; private set; }
- public string Text { get; private set; }
- public System.Net.HttpStatusCode StatusCode { get; private set; }
- public System.Collections.Generic.Dictionary<string, string> ResponseHeaders { get; private set; }
- public WWW WWW { get; private set; }
- // cache the text because if www was disposed, can't access it.
- public WWWErrorException(WWW www, string text)
- {
- this.WWW = www;
- this.RawErrorMessage = www.error;
- this.ResponseHeaders = www.responseHeaders;
- this.HasResponse = false;
- this.Text = text;
- var splitted = RawErrorMessage.Split(' ', ':');
- if (splitted.Length != 0)
- {
- int statusCode;
- if (int.TryParse(splitted[0], out statusCode))
- {
- this.HasResponse = true;
- this.StatusCode = (System.Net.HttpStatusCode)statusCode;
- }
- }
- }
- public override string ToString()
- {
- var text = this.Text;
- if (string.IsNullOrEmpty(text))
- {
- return RawErrorMessage;
- }
- else
- {
- return RawErrorMessage + " " + text;
- }
- }
- }
- }
- #if UNITY_2018_3_OR_NEWER
- #pragma warning restore CS0618
- #endif
|