use promise in loader

This commit is contained in:
2015-07-17 21:27:20 +03:00
parent 61b0078f3f
commit 18808764f9
14 changed files with 74 additions and 121 deletions

View File

@@ -9,6 +9,7 @@
"contributors": ["shmyga"], "contributors": ["shmyga"],
"classPath": "src/main", "classPath": "src/main",
"dependencies": { "dependencies": {
"promhx": "",
"openfl": "" "openfl": ""
} }
} }

View File

@@ -1,4 +1,5 @@
-cp src -cp src
-lib promhx
-lib haxework -lib haxework
-main LoaderExample.hx -main LoaderExample.hx
-swf-version 10.1 -swf-version 10.1

View File

@@ -19,24 +19,24 @@ class LoaderExample {
// Json // Json
trace("Json Request"); trace("Json Request");
new JsonLoader().GET("http://umix.tv/channel/data2/renova.json") new JsonLoader().GET("http://umix.tv/channel/data2/renova.json")
.success(function(channel:Array<ChannelItem>) { .then(function(channel:Array<ChannelItem>) {
trace("Json Ok: " + channel.length); trace("Json Ok: " + channel.length);
for (item in channel) { for (item in channel) {
trace(item.id + ": " + item.message); trace(item.id + ": " + item.message);
} }
}) })
.fail(function(error) { .catchError(function(error) {
trace(error); trace(error);
}); });
// Image // Image
trace("Image Request"); trace("Image Request");
new ImageLoader().GET("http://umix.tv/channel/block/renova/1") new ImageLoader().GET("http://umix.tv/channel/block/renova/1")
.success(function(image:BitmapData) { .then(function(image:BitmapData) {
trace("Image Ok: " + image.width + "x" + image.height); trace("Image Ok: " + image.width + "x" + image.height);
Lib.current.addChild(new Bitmap(image)); Lib.current.addChild(new Bitmap(image));
}) })
.fail(function(error) { .catchError(function(error) {
trace(error); trace(error);
}); });
} }

View File

@@ -27,7 +27,7 @@ class ImageView extends SpriteView {
private function set_imageUrl(value:String):String { private function set_imageUrl(value:String):String {
if (imageUrl != value) { if (imageUrl != value) {
imageUrl = value; imageUrl = value;
new ImageLoader().GET(imageUrl).success(function(data) { new ImageLoader().GET(imageUrl).then(function(data) {
image = data; image = data;
}); });
} }

View File

@@ -6,11 +6,10 @@ import flash.events.ProgressEvent;
import haxework.net.manage.ILoaderManager; import haxework.net.manage.ILoaderManager;
import haxework.provider.Provider; import haxework.provider.Provider;
import flash.utils.ByteArray; import flash.utils.ByteArray;
import haxework.net.callback.Callback;
import haxework.net.callback.ICallback;
import flash.events.Event; import flash.events.Event;
import promhx.Deferred;
class BaseLoader<T> implements ILoader<T> { class BaseLoader<T> extends Deferred<T> implements ILoader<T> {
private static inline var TAG:String = "Loader"; private static inline var TAG:String = "Loader";
@@ -28,27 +27,29 @@ class BaseLoader<T> implements ILoader<T> {
private var url:String; private var url:String;
private var method:String; private var method:String;
private var data:Null<Dynamic>; private var data:Null<Dynamic>;
private var callback:ICallback<T>;
private var timer:Timer; private var timer:Timer;
public function new(?timeout = 0) { public function new(?timeout = 0) {
super();
this.timeout = timeout; this.timeout = timeout;
busy = false; busy = false;
completed = Math.NaN; completed = Math.NaN;
} }
public function request(url:String, method:String, data:Dynamic = null):ICallback<T> { public function request(url:String, method:String, data:Dynamic = null):Deferred<T> {
if (busy) throw "Busy"; if (busy) {
busy = true; throwError("Busy");
this.url = url; } else {
this.method = method; busy = true;
this.data = data; this.url = url;
callback = new Callback<T>(); this.method = method;
var url:String = this.url; this.data = data;
//L.d(TAG, "Request: " + prepareUrl(url)); var url:String = this.url;
//internalRequest(prepareUrl(url)); //L.d(TAG, "Request: " + prepareUrl(url));
Provider.get(ILoaderManager).add(this); //internalRequest(prepareUrl(url));
return callback; Provider.get(ILoaderManager).add(this);
}
return this;
} }
private function cockTimeout():Void { private function cockTimeout():Void {
@@ -65,25 +66,24 @@ class BaseLoader<T> implements ILoader<T> {
} }
} }
public function fromBytes(data:ByteArray):ICallback<T> { public function fromBytes(data:ByteArray):Deferred<T> {
if (busy) throw "Busy"; if (busy) {
busy = true; throwError("Busy");
callback = new Callback<T>(); } else {
internalFromBytes(data); busy = true;
return callback; internalFromBytes(data);
}
return this;
} }
public function GET(url:String, data:Dynamic = null):ICallback<T> { public function GET(url:String, data:Dynamic = null):Deferred<T> {
#if (openfl && lime) #if (openfl && lime)
if (StringTools.startsWith(url, "%assets%")) { if (StringTools.startsWith(url, "%assets%")) {
var path:String = url.substring(9); var path:String = url.substring(9);
var bytes:ByteArray = openfl.Assets.getBytes(path); var bytes:ByteArray = openfl.Assets.getBytes(path);
if (bytes == null) { if (bytes == null) {
Timer.delay(function() { throwError("Bytes is null for asset: " + path);
var c:ICallback<T> = callback; return null;
dispose();
c.callFail("Bytes is null for asset: " + path);
}, 1);
} else { } else {
return fromBytes(bytes); return fromBytes(bytes);
} }
@@ -92,11 +92,11 @@ class BaseLoader<T> implements ILoader<T> {
return request(url, URLRequestMethod.GET, data); return request(url, URLRequestMethod.GET, data);
} }
public function POST(url:String, data:Dynamic = null):ICallback<T> { public function POST(url:String, data:Dynamic = null):Deferred<T> {
return request(url, URLRequestMethod.POST, data); return request(url, URLRequestMethod.POST, data);
} }
public function DELETE(url:String, data:Dynamic = null):ICallback<T> { public function DELETE(url:String, data:Dynamic = null):Deferred<T> {
return request(url, URLRequestMethod.DELETE, data); return request(url, URLRequestMethod.DELETE, data);
} }
@@ -117,10 +117,11 @@ class BaseLoader<T> implements ILoader<T> {
private function onComplete(e:Event):Void { private function onComplete(e:Event):Void {
var data:T = extrudeResult(e); var data:T = extrudeResult(e);
if (data != null) { if (data != null) {
var c:ICallback<T> = callback; resolve(data);
dispose(); } else {
c.callSuccess(data); throwError("Data is null");
} }
dispose();
} }
private function onSecurityError(e:Event):Void { private function onSecurityError(e:Event):Void {
@@ -133,16 +134,14 @@ class BaseLoader<T> implements ILoader<T> {
} }
private function onError(e:Event):Void { private function onError(e:Event):Void {
var c:ICallback<T> = callback; throwError(e);
dispose(); dispose();
c.callFail(e);
} }
private function callTimeout():Void { private function callTimeout():Void {
var c:ICallback<T> = callback;
var error:String = "Timeout for: " + url; var error:String = "Timeout for: " + url;
throwError(error);
dispose(); dispose();
c.callFail(error);
} }
private function extrudeResult(e:Event):T { private function extrudeResult(e:Event):T {
@@ -154,13 +153,13 @@ class BaseLoader<T> implements ILoader<T> {
cancelTimeout(); cancelTimeout();
url = null; url = null;
data = null; data = null;
callback = null;
busy = false; busy = false;
completed = Math.NaN; completed = Math.NaN;
Provider.get(ILoaderManager).release(this); Provider.get(ILoaderManager).release(this);
} }
public function cancel():Void { public function cancel():Void {
throwError("Cancelled");
dispose(); dispose();
} }

View File

@@ -1,10 +1,5 @@
package haxework.net; package haxework.net;
import haxework.net.callback.Callback;
import haxework.net.callback.ICallback;
import haxework.provider.Provider;
import haxework.storage.IStorage;
import flash.display.BitmapData;
import flash.events.ProgressEvent; import flash.events.ProgressEvent;
import flash.system.Security; import flash.system.Security;
import flash.system.SecurityDomain; import flash.system.SecurityDomain;
@@ -22,24 +17,6 @@ class BaseMediaLoader<T> extends BaseLoader<T> {
private var loader:Loader; private var loader:Loader;
//ToDo: if storage use and local domen
//exclude youtube player
/*override public function GET(url:String, data:Dynamic = null):ICallback<T> {
var storage:IStorage = Provider.get(IStorage);
return if (storage.exists(url)) {
fromBytes(storage.read(url));
} else {
var callback:ICallback<T> = new Callback<T>();
new BytesLoader().GET(url)
.success(function(data:ByteArray):Void {
storage.write(url, data);
fromBytes(data).glue(callback);
})
.fail(callback.callFail);
callback;
}
}*/
override private function internalRequest(url:String):Void { override private function internalRequest(url:String):Void {
cockTimeout(); cockTimeout();
loader = buildLoader(); loader = buildLoader();

View File

@@ -1,10 +1,10 @@
package haxework.net; package haxework.net;
import flash.events.ErrorEvent;
import haxe.Timer; import haxe.Timer;
import flash.utils.ByteArray; import flash.utils.ByteArray;
import flash.net.URLRequestHeader; import flash.net.URLRequestHeader;
import flash.net.URLRequestMethod; import flash.net.URLRequestMethod;
import haxework.net.callback.ICallback;
import flash.net.URLVariables; import flash.net.URLVariables;
import flash.events.ProgressEvent; import flash.events.ProgressEvent;
import flash.net.URLLoaderDataFormat; import flash.net.URLLoaderDataFormat;
@@ -13,6 +13,7 @@ import flash.events.IOErrorEvent;
import flash.net.URLRequest; import flash.net.URLRequest;
import flash.events.Event; import flash.events.Event;
import flash.net.URLLoader; import flash.net.URLLoader;
import promhx.Thenable;
class BaseURLLoader<T> extends BaseLoader<T> { class BaseURLLoader<T> extends BaseLoader<T> {
@@ -45,14 +46,13 @@ class BaseURLLoader<T> extends BaseLoader<T> {
} }
override private function internalFromBytes(data:ByteArray):Void { override private function internalFromBytes(data:ByteArray):Void {
var c:ICallback<T> = callback;
if (data == null) { if (data == null) {
c.callFailAsync("Content not found"); throwError("Content not found");
} else { } else {
var data:T = extrudeResultFromBytes(data); var data:T = extrudeResultFromBytes(data);
c.callSuccessAsync(data); resolve(data);
} }
Timer.delay(dispose, 1); dispose();
} }
private function extrudeResultFromBytes(bytes:ByteArray):T { private function extrudeResultFromBytes(bytes:ByteArray):T {
@@ -90,11 +90,16 @@ class BaseURLLoader<T> extends BaseLoader<T> {
} }
override private function onError(e:Event):Void { override private function onError(e:Event):Void {
var c:ICallback<T> = callback;
var error:String = extrudeError(loader.data); var error:String = extrudeError(loader.data);
if (error != null) error = url + ": " + error; if (error != null && error != "") {
error = error + ". URL: " + url;
} else if (Std.is(e, ErrorEvent)) {
error = cast(e, ErrorEvent).text;
} else {
error = "Unknown Error. URL: " + url;
}
throwError(error);
dispose(); dispose();
c.callFail(error != null ? error : e);
} }
private function extrudeError(data:Dynamic):String { private function extrudeError(data:Dynamic):String {

View File

@@ -1,9 +1,7 @@
package haxework.net; package haxework.net;
import haxework.net.callback.Callback; import promhx.Promise;
import haxework.net.callback.ICallback; import promhx.Deferred;
import flash.events.Event;
import flash.net.URLLoader;
class BatchLoader<T> { class BatchLoader<T> {
@@ -13,39 +11,10 @@ class BatchLoader<T> {
this.factory = factory; this.factory = factory;
} }
public function GET(urls:Array<String>):ICallback<Array<T>> { public function GET(urls:Array<String>):Promise<Array<T>> {
var callbacks:Array<ICallback<T>> = urls.map(function(url:String):ICallback<T> { return Promise.whenAll(urls.map(function(url:String):Promise<T> {
var loader:ILoader<T> = Type.createInstance(factory, []); var loader:ILoader<T> = Type.createInstance(factory, []);
return loader.GET(url); return loader.GET(url).promise();
}); }));
return new BatchCallback(callbacks);
}
}
class BatchCallback<T> extends Callback<Array<T>> {
private var data:Array<T>;
private var counter:Int;
public function new(callbacks:Array<ICallback<T>>) {
super();
data = new Array<T>();
counter = callbacks.length;
for (i in 0...callbacks.length) {
register(callbacks[i], i);
}
}
private function register(callback:ICallback<T>, index:Int):Void {
callback
.success(function(d:T):Void {
data[index] = d;
if (--counter == 0) callSuccess(data);
})
.fail(function(error:Dynamic):Void {
L.e("BatchLoader", "", error);
if (--counter == 0) callSuccess(data);
});
} }
} }

View File

@@ -1,18 +1,18 @@
package haxework.net; package haxework.net;
import flash.utils.ByteArray; import flash.utils.ByteArray;
import haxework.net.callback.ICallback; import promhx.Deferred;
interface ILoader<T> { interface ILoader<T> {
public var timeout(default, default):Int; public var timeout(default, default):Int;
public var busy(default, null):Bool; public var busy(default, null):Bool;
public var completed(default, null):Float; public var completed(default, null):Float;
public function request(url:String, method:String, data:Dynamic = null):ICallback<T>; public function request(url:String, method:String, data:Dynamic = null):Deferred<T>;
public function fromBytes(data:ByteArray):ICallback<T>; public function fromBytes(data:ByteArray):Deferred<T>;
public function GET(url:String, data:Dynamic = null):ICallback<T>; public function GET(url:String, data:Dynamic = null):Deferred<T>;
public function POST(url:String, data:Dynamic = null):ICallback<T>; public function POST(url:String, data:Dynamic = null):Deferred<T>;
public function DELETE(url:String, data:Dynamic = null):ICallback<T>; public function DELETE(url:String, data:Dynamic = null):Deferred<T>;
public function cancel():Void; public function cancel():Void;
public function run():Void; public function run():Void;

View File

@@ -1,6 +1,5 @@
package haxework.net; package haxework.net;
import flash.utils.ByteArray;
import flash.display.LoaderInfo; import flash.display.LoaderInfo;
import flash.display.Loader; import flash.display.Loader;
import flash.display.Bitmap; import flash.display.Bitmap;

View File

@@ -1,7 +1,6 @@
package haxework.net; package haxework.net;
import flash.utils.ByteArray; import flash.utils.ByteArray;
import flash.errors.Error;
import flash.events.Event; import flash.events.Event;
import flash.net.URLLoader; import flash.net.URLLoader;
import haxe.Json; import haxe.Json;
@@ -15,7 +14,7 @@ class JsonLoader<T> extends BaseURLLoader<T> {
str = Std.string(cast(e.currentTarget, URLLoader).data); str = Std.string(cast(e.currentTarget, URLLoader).data);
data = Json.parse(str); data = Json.parse(str);
} catch (error:Dynamic) { } catch (error:Dynamic) {
throw new Error(error + ": " + url); throwError(error);
} }
return data; return data;
} }
@@ -27,7 +26,7 @@ class JsonLoader<T> extends BaseURLLoader<T> {
str = bytes.readUTFBytes(bytes.length); str = bytes.readUTFBytes(bytes.length);
data = Json.parse(str); data = Json.parse(str);
} catch (error:Dynamic) { } catch (error:Dynamic) {
throw new Error(error + ": " + url); throwError(error);
} }
return data; return data;
} }

View File

@@ -1,5 +1,6 @@
package haxework.net.callback; package haxework.net.callback;
@:deprecated("Use promhx.Deffered")
class AutoCallback { class AutoCallback {
public static function success<T>(?value:T):ICallback<T> { public static function success<T>(?value:T):ICallback<T> {

View File

@@ -2,6 +2,7 @@ package haxework.net.callback;
import haxe.Timer; import haxe.Timer;
@:deprecated("Use promhx.Deffered")
class Callback<T> implements ICallback<T> { class Callback<T> implements ICallback<T> {
public static function build<T>():ICallback<T> { public static function build<T>():ICallback<T> {

View File

@@ -2,6 +2,7 @@ package haxework.net.callback;
import haxework.core.IDisposable; import haxework.core.IDisposable;
@:deprecated("Use promhx.Deffered")
interface ICallback<T> extends IDisposable { interface ICallback<T> extends IDisposable {
public function success(f:T -> Void):ICallback<T>; public function success(f:T -> Void):ICallback<T>;
public function fail(f:Dynamic -> Void):ICallback<T>; public function fail(f:Dynamic -> Void):ICallback<T>;