专栏首页游戏开发之旅Unity中使用WWW封装下载类管理代码片段

Unity中使用WWW封装下载类管理代码片段

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/CJB_King/article/details/89315810

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class DownloadManager : MonoBehaviour , System.IDisposable {
	// using classes
	public class Request {
		public string url;
		public DownloadDelegate del;
		
		public WWWForm form;
		
		public byte[] bytes;
		public Hashtable header;
		
		//-------------------------------------------------------------
		// Constractors
		//-------------------------------------------------------------
		public Request(string url, DownloadDelegate del) {
			this.url = url;
			this.del = del;
		}
		
		public Request(string url, DownloadDelegate del, WWWForm form) : this(url, del) {
			this.form = form;
		}
		
		public Request(string url, DownloadDelegate del, byte[] bytes) : this(url, del) {
			this.bytes = bytes;
		}
		
		public Request(string url, DownloadDelegate del, byte[] bytes, Hashtable header) : this(url, del, bytes) {
			this.header = header;
		}
		
		//
		public WWW MakeWWw() {
			if(header != null) {
				return new WWW(url, bytes, header);
			}
			if(bytes != null) {
				return new WWW(url, bytes);
			}
			if(form != null) {
				return new WWW(url, form);
			}
			return new WWW(url);
		}
	}
	
	class TimeOut {
		float beforProgress;
		float beforTime;
		
		public bool CheckTimeout(float progress) {
			float now = Time.time;
			if((now - beforTime)>TIME_OUT) {
				// timeout
				return true;
			}
			// update progress
			if(beforProgress != progress) {
				beforProgress = progress;
				beforTime = now;
			}
			return false;
		}
	}
	
	// delegates
	public delegate void DownloadDelegate(WWW www);
	public delegate void DownloadErrorDelegate(string error);
	public delegate void DownloadFinishDelegate();
	
	// const
	public const float TIME_OUT = 20f;
	
	// public 
	public event DownloadErrorDelegate OnError;
	public event DownloadFinishDelegate OnFinish;
	
	// member
	Queue<Request> requests;
	WWW _www;
	bool isDownloading = false;
	TimeOut timeout;
	
	// static
	private static DownloadManager _instance;
	static public DownloadManager instance {
		get {
			if(_instance == null) {
				GameObject go = new GameObject();
				go.name = "DownloadManager";
				_instance = go.AddComponent<DownloadManager>();
				DontDestroyOnLoad(go);
			}
			return _instance;
		}
	}
	
	//-------------------------------------------
	// life cycle
	//-------------------------------------------
	void Awake () {
		requests = new Queue<Request>();
		timeout = new TimeOut();
	}
	
	void Destroy() {
		this.Dispose();
		_instance = null;
	}
	
	public void Dispose() {
		isDownloading = false;
		StopAllCoroutines();
		if(_www != null) {
			_www.Dispose();
		}
		requests.Clear();
		OnError = null;
		OnFinish = null;
	}
	
	void FixedUpdate(){
		if(!isDownloading) {
			this.enabled = false;
		}
		
		if(timeout.CheckTimeout(CurrentProgress)) {
			// timeout
			if(OnError != null) OnError("timeout");
			this.Dispose();
		}
	}
	
	//-------------------------------------------
	// public
	//-------------------------------------------
	public void Push(Request req) {
		requests.Enqueue(req);
	}
	
	public void Excute() {
		if(isDownloading) {
			Debug.Log("aleady downloading...");
			return;
		}
		StartCoroutine("Download");
	}
	
	public float CurrentProgress {
		get {
			if(_www == null) { return 0f;}
			return _www.progress;
		}
	}
	
	//-------------------------------------------
	// private
	//-------------------------------------------
	IEnumerator Download() {
		if(requests.Count == 0) {
			Debug.LogWarning("no requests");
			return true;
		}
		this.isDownloading = true;
		this.enabled = true;
		
		while(requests.Count>0) {
			Request req = requests.Dequeue();
			_www = req.MakeWWw();
			yield return _www;
			// error check
			if(_www.error != null && _www.error.Length > 0) {
				if(OnError != null) OnError(_www.error);
			}
			// call delegate
			req.del(_www);
		}
		
		if(OnFinish != null) OnFinish();
		this.isDownloading = false;
		this.enabled = false;
	}
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Unity UI案例(绘制圆环)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明...

    bering
  • Unity游戏开发Photon Server之客户端架构

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明...

    bering
  • Unity編輯器案列

    Unity最强大的地方之一是它扩展性非常强的编辑器。Unite Europe 2016上有一个视频专门讲编辑器编程的:

    bering
  • 从源码角度理解Java设计模式——责任链模式

    适用场景(核心):只要把你的请求抛给第一个处理者,不用关心谁处理的,并且最终会返回你一个结果。

    我叫刘半仙
  • (三十二)c#Winform自定义控件-表格

    GitHub:https://github.com/kwwwvagaa/NetWinformControl

    冰封一夏
  • 【java基础】ConcurrentHashMap1.7和1.8的不同实现

    在多线程环境下,使用HashMap进行put操作时存在丢失数据的情况,为了避免这种bug的隐患,强烈建议使用ConcurrentHashMap代替HashMap...

    用户5640963
  • redis源码阅读之集合对象

    redis当中集合对象的底层实现为intset和hashtable实现,用hashtable实现时,存储具体值的是key,value统一用NULL。其实集合对象...

    本人秃顶程序员
  • python基础(一)

    py3study
  • Spring Bean的生命周期管理

    三哥
  • Spring Bean的生命周期管理

    Spring Bean存活于容器之中,一般情况下spring bean对context的情况并不了解,如果希望某个bean知道自己在context中的代号:be...

    阿杜

扫码关注云+社区

领取腾讯云代金券