using System; using System.Collections.Generic; using UnityEngine; #if UNITY_5_4_OR_NEWER using UnityEngine.Networking; using UnityEngine.Rendering; #endif namespace Cryville.Common.Unity { public class NetworkTaskWorker { bool suspended; NetworkTask currentNetworkTask; readonly Queue networkTasks = new Queue(); public int TaskCount { get { return networkTasks.Count; } } public void SubmitNetworkTask(NetworkTask task) { networkTasks.Enqueue(task); } public WorkerStatus TickBackgroundTasks() { if (suspended) return WorkerStatus.Suspended; if (currentNetworkTask != null) { if (currentNetworkTask.Canceled) currentNetworkTask = null; else if (currentNetworkTask.Done()) currentNetworkTask = null; } while (networkTasks.Count > 0 && currentNetworkTask == null) { var task = networkTasks.Dequeue(); if (task.Canceled) continue; currentNetworkTask = task; currentNetworkTask.Start(); } return currentNetworkTask == null ? WorkerStatus.Idle : WorkerStatus.Working; } public void SuspendBackgroundTasks() { suspended = true; if (currentNetworkTask != null) { currentNetworkTask.Cancel(); currentNetworkTask = null; } } public void ResumeBackgroundTasks() { suspended = false; } } public enum WorkerStatus { Idle, Working, Suspended, } public abstract class NetworkTask { protected NetworkTask(string uri) { Uri = uri; } public string Uri { get; private set; } public bool Canceled { get; private set; } public virtual void Cancel() { Canceled = true; } #if UNITY_5_4_OR_NEWER protected UnityWebRequest www; public virtual void Start() { www = new UnityWebRequest(Uri); www.SendWebRequest(); } public virtual bool Done() { if (!www.isDone) return false; return true; } #else protected WWW www; public virtual WWW Start() { return new WWW(Uri); } public abstract void Done(); #endif } public class LoadTextureTask : NetworkTask { public LoadTextureTask(string uri, Action callback) : base(uri) { Callback = callback; } public Action Callback { get; private set; } #if UNITY_5_4_OR_NEWER DownloadHandlerTexture handler; public override void Start() { handler = new DownloadHandlerTexture(); www = new UnityWebRequest(Uri, "GET", handler, null); www.SendWebRequest(); } public override bool Done() { if (!handler.isDone) return false; if (handler.texture != null) { var buffer = handler.texture; /*var result = new Texture2D(buffer.width, buffer.height, buffer.format, true); if (SystemInfo.copyTextureSupport.HasFlag(CopyTextureSupport.Basic)) { Graphics.CopyTexture(buffer, 0, 0, result, 0, 0); } else { result.LoadImage(handler.data); } result.Apply(true, true); Texture2D.Destroy(buffer); Callback(true, result);*/ Callback(true, buffer); } else { Callback(false, null); } www.Dispose(); handler.Dispose(); return true; } #else public override void PostProcess(WWW www) { bool succeeded = string.IsNullOrEmpty(www.error); if (succeeded) { var buffer = www.texture; var result = new Texture2D(buffer.width, buffer.height, buffer.format, true); result.SetPixels(buffer.GetPixels()); result.Apply(true, true); Texture2D.Destroy(buffer); Callback(true, result); } else Callback(false, null); } #endif } }