Instantly share code, notes, and snippets.

Embed
What would you like to do?
Unity DownloadManager
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
/**
DownloadManager
@author koki ibukuro
*/
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;
}
}
@asus4

This comment has been minimized.

Owner

asus4 commented Apr 25, 2012

USAGE

void Start() {
    DownloadManager dm = DownloadManager.instance;

    dm.OnError += OnError;
    dm.OnFinish += OnAllFinish;

    dm.Push(new DownloadManager.Request(url, OnFinishDownload));
    dm.Excute();
}

void OnFinishDownload(WWW www) {

}

void OnError(string error) {

}

void OnAllFinish() {

}

OR

void Start() {
    DownloadManager dm = DownloadManager.instance;

    dm.OnError += OnError;
    dm.OnFinish += OnAllFinish;

    var req = new DownloadManager.Request(url, 
        (WWW www) => {
            // on finish download
        }
    );
    dm.Push(req);
    dm.Excute();
}

void OnError(string error) {

}

void OnAllFinish() {

}
@asus4

This comment has been minimized.

Owner

asus4 commented Apr 27, 2012

タイムアウトも実装したのです!

@trkprro

This comment has been minimized.

trkprro commented Jan 2, 2014

how to download

@shivanraptor

This comment has been minimized.

shivanraptor commented Feb 25, 2014

In NetworkManager line 170, it should be:

yield return true; 

instead of return true, as IEnumerator cannot return result directly.

Almost forget to mention, Nice work !

@Gor-Gasp

This comment has been minimized.

Gor-Gasp commented Mar 9, 2015

Hi, thanks for a good work. Hashtable is obsolete and a Dictionary<string,string> could be used for Hader instead.

Regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment