public static async Task <FetchResult> LoadTask(MonoBehaviour runner, Uri uri) { FetchResult result = new FetchResult() { Asset = null, FailureMessage = null }; var ifNoneMatch = MREAPI.AppsAPI.AssetCache.SupportsSync ? MREAPI.AppsAPI.AssetCache.GetVersionSync(uri) : await MREAPI.AppsAPI.AssetCache.GetVersion(uri); runner.StartCoroutine(LoadCoroutine()); // Spin asynchronously until the request completes. while (!result.IsPopulated) { await Task.Delay(10); } // handle caching if (ifNoneMatch != null && result.ReturnCode == 304) { var assets = MREAPI.AppsAPI.AssetCache.SupportsSync ? MREAPI.AppsAPI.AssetCache.LeaseAssetsSync(uri) : await MREAPI.AppsAPI.AssetCache.LeaseAssets(uri); result.Asset = assets.FirstOrDefault() as T; } else if (result.Asset != null) { MREAPI.AppsAPI.AssetCache.StoreAssets( uri, new UnityEngine.Object[] { result.Asset as UnityEngine.Object }, result.ETag); } return(result); IEnumerator LoadCoroutine() { DownloadHandler handler; if (typeof(T) == typeof(UnityEngine.AudioClip)) { handler = new DownloadHandlerAudioClip(uri, AudioType.UNKNOWN); } else if (typeof(T) == typeof(UnityEngine.Texture)) { handler = new DownloadHandlerTexture(false); } else { result.FailureMessage = $"Unknown download type: {typeof(T)}"; yield break; } // Spin asynchronously until the load throttler would allow us through. while (AssetLoadThrottling.WouldThrottle()) { yield return(null); } using (var scope = new AssetLoadThrottling.AssetLoadScope()) using (var www = new UnityWebRequest(uri, "GET", handler, null)) { if (ifNoneMatch != null) { www.SetRequestHeader("If-None-Match", ifNoneMatch); } yield return(www.SendWebRequest()); if (www.isNetworkError) { result.ReturnCode = -1; result.FailureMessage = www.error; } else { result.ReturnCode = www.responseCode; result.ETag = www.GetResponseHeader("ETag") ?? "unversioned"; if (www.isHttpError) { result.FailureMessage = $"[{www.responseCode}] {uri}"; } else if (www.responseCode >= 200 && www.responseCode <= 299) { if (typeof(T).IsAssignableFrom(typeof(UnityEngine.AudioClip))) { result.Asset = ((DownloadHandlerAudioClip)handler).audioClip as T; } else if (typeof(T).IsAssignableFrom(typeof(UnityEngine.Texture))) { result.Asset = ((DownloadHandlerTexture)handler).texture as T; } } } } } }
public static async Task <FetchResult> LoadTask(MonoBehaviour runner, Uri uri) { FetchResult result = new FetchResult() { Asset = null, FailureMessage = null }; runner.StartCoroutine(LoadCoroutine()); // Spin asynchronously until the request completes. while (!result.IsPopulated) { await Task.Delay(10); } return(result); IEnumerator LoadCoroutine() { DownloadHandler handler; if (typeof(T) == typeof(UnityEngine.AudioClip)) { handler = new DownloadHandlerAudioClip(uri, AudioType.UNKNOWN); } else if (typeof(T) == typeof(UnityEngine.Texture)) { handler = new DownloadHandlerTexture(false); } else { result.FailureMessage = $"Unknown download type: {typeof(T)}"; yield break; } // Spin asynchronously until the load throttler would allow us through. while (AssetLoadThrottling.WouldThrottle()) { yield return(null); } using (var scope = new AssetLoadThrottling.AssetLoadScope()) using (var www = new UnityWebRequest(uri, "GET", handler, null)) { yield return(www.SendWebRequest()); if (www.isNetworkError) { result.FailureMessage = www.error; } else if (www.isHttpError) { result.FailureMessage = $"[{www.responseCode}] {uri}"; } else { if (typeof(T) == typeof(UnityEngine.AudioClip)) { result.Asset = ((DownloadHandlerAudioClip)handler).audioClip as T; } else if (typeof(T) == typeof(UnityEngine.Texture)) { result.Asset = ((DownloadHandlerTexture)handler).texture as T; } } } } }
public static async Task <FetchResult> LoadTask(MonoBehaviour runner, Uri uri) { // acquire the exclusive right to load this asset if (!await MREAPI.AppsAPI.AssetCache.AcquireLoadingLock(uri)) { throw new TimeoutException("Failed to acquire exclusive loading rights for " + uri); } FetchResult result = new FetchResult() { Asset = null, FailureMessage = null }; var ifNoneMatch = MREAPI.AppsAPI.AssetCache.SupportsSync ? MREAPI.AppsAPI.AssetCache.TryGetVersionSync(uri) : await MREAPI.AppsAPI.AssetCache.TryGetVersion(uri); // if the cached version is unversioned, i.e. the server doesn't support ETags, don't bother making request if (ifNoneMatch == Constants.UnversionedAssetVersion) { var assets = MREAPI.AppsAPI.AssetCache.SupportsSync ? MREAPI.AppsAPI.AssetCache.LeaseAssetsSync(uri) : await MREAPI.AppsAPI.AssetCache.LeaseAssets(uri); result.Asset = assets.FirstOrDefault() as T; MREAPI.AppsAPI.AssetCache.ReleaseLoadingLock(uri); return(result); } runner.StartCoroutine(LoadCoroutine()); // Spin asynchronously until the request completes. while (!result.IsPopulated) { await Task.Delay(10); } // handle caching if (!string.IsNullOrEmpty(ifNoneMatch) && result.ReturnCode == 304) { var assets = MREAPI.AppsAPI.AssetCache.SupportsSync ? MREAPI.AppsAPI.AssetCache.LeaseAssetsSync(uri) : await MREAPI.AppsAPI.AssetCache.LeaseAssets(uri); result.Asset = assets.FirstOrDefault() as T; } else if (result.Asset != null) { MREAPI.AppsAPI.AssetCache.StoreAssets( uri, new UnityEngine.Object[] { result.Asset }, result.ETag); } MREAPI.AppsAPI.AssetCache.ReleaseLoadingLock(uri); return(result); IEnumerator LoadCoroutine() { DownloadHandler handler; if (typeof(T) == typeof(UnityEngine.AudioClip)) { handler = new DownloadHandlerAudioClip(uri, AudioType.UNKNOWN); } else if (typeof(T) == typeof(UnityEngine.Texture)) { handler = new DownloadHandlerTexture(false); } else { result.FailureMessage = $"Unknown download type: {typeof(T)}"; yield break; } // Spin asynchronously until the load throttler would allow us through. while (AssetLoadThrottling.WouldThrottle()) { yield return(null); } using (var scope = new AssetLoadThrottling.AssetLoadScope()) using (var www = new UnityWebRequest(uri, "GET", handler, null)) { if (!string.IsNullOrEmpty(ifNoneMatch)) { www.SetRequestHeader("If-None-Match", ifNoneMatch); } yield return(www.SendWebRequest()); if (www.isNetworkError) { result.ReturnCode = -1; result.FailureMessage = www.error; } else { result.ReturnCode = www.responseCode; result.ETag = www.GetResponseHeader("ETag") ?? Constants.UnversionedAssetVersion; if (www.isHttpError) { result.FailureMessage = $"[{www.responseCode}] {uri}"; } else if (www.responseCode >= 200 && www.responseCode <= 299) { if (typeof(T).IsAssignableFrom(typeof(UnityEngine.AudioClip))) { result.Asset = ((DownloadHandlerAudioClip)handler).audioClip as T; } else if (typeof(T).IsAssignableFrom(typeof(UnityEngine.Texture))) { result.Asset = ((DownloadHandlerTexture)handler).texture as T; } } } } } }
public static async Task <FetchResult> LoadTask(Node runner, Uri uri) { // acquire the exclusive right to load this asset if (!await MREAPI.AppsAPI.AssetCache.AcquireLoadingLock(uri)) { throw new TimeoutException("Failed to acquire exclusive loading rights for " + uri); } FetchResult result = new FetchResult() { Asset = null, FailureMessage = null }; var ifNoneMatch = MREAPI.AppsAPI.AssetCache.SupportsSync ? MREAPI.AppsAPI.AssetCache.TryGetVersionSync(uri) : await MREAPI.AppsAPI.AssetCache.TryGetVersion(uri); // if the cached version is unversioned, i.e. the server doesn't support ETags, don't bother making request if (ifNoneMatch == Constants.UnversionedAssetVersion) { var assets = MREAPI.AppsAPI.AssetCache.SupportsSync ? MREAPI.AppsAPI.AssetCache.LeaseAssetsSync(uri) : await MREAPI.AppsAPI.AssetCache.LeaseAssets(uri); result.Asset = assets.FirstOrDefault() as T; MREAPI.AppsAPI.AssetCache.ReleaseLoadingLock(uri); return(result); } await LoadCoroutine(runner); // handle caching if (!string.IsNullOrEmpty(ifNoneMatch) && result.ReturnCode == 304) { var assets = MREAPI.AppsAPI.AssetCache.SupportsSync ? MREAPI.AppsAPI.AssetCache.LeaseAssetsSync(uri) : await MREAPI.AppsAPI.AssetCache.LeaseAssets(uri); result.Asset = assets.FirstOrDefault() as T; } else if (result.Asset != null) { MREAPI.AppsAPI.AssetCache.StoreAssets( uri, new Godot.Object[] { result.Asset }, result.ETag); } MREAPI.AppsAPI.AssetCache.ReleaseLoadingLock(uri); return(result); async Task LoadCoroutine(Node runner) { DownloadHandler handler; if (typeof(T) == typeof(Godot.AudioStream)) { handler = new DownloadHandlerAudioStream(uri, AudioType.Unknown); } else if (typeof(T) == typeof(Godot.Texture)) { handler = new DownloadHandlerTexture(uri); } else { result.FailureMessage = $"Unknown download type: {typeof(T)}"; return; } // Spin asynchronously until the load throttler would allow us through. while (AssetLoadThrottling.WouldThrottle()) { await runner.ToSignal(Engine.GetMainLoop(), "idle_frame"); } using (var scope = new AssetLoadThrottling.AssetLoadScope()) using (var www = new GodotWebRequest(uri, HTTPClient.Method.Get, handler)) { if (!string.IsNullOrEmpty(ifNoneMatch)) { www.SetRequestHeader("If-None-Match", ifNoneMatch); } Error error = www.SendWebRequest(); if (error != 0) { result.ReturnCode = -1; result.FailureMessage = error.ToString(); } else { result.ReturnCode = www.GetResponseCode(); result.ETag = www.GetResponseHeader("ETag") ?? Constants.UnversionedAssetVersion; if (result.ReturnCode >= 200 && result.ReturnCode <= 299) { if (typeof(T).IsAssignableFrom(typeof(AudioStream))) { result.Asset = ((DownloadHandlerAudioStream)handler).AudioStream as T; } else if (typeof(T).IsAssignableFrom(typeof(Godot.Texture))) { result.Asset = ((DownloadHandlerTexture)handler).Texture as T; } } else { result.FailureMessage = $"[{result.ReturnCode}] {uri}"; } } } } }