From 3dad6d81d09d9f4742c3ad99c4ef91cbcdaccfdb Mon Sep 17 00:00:00 2001 From: Joshua Granick Date: Thu, 6 Oct 2016 12:12:04 -0700 Subject: [PATCH] Improvements to Future/Promise --- lime/app/Future.hx | 145 +++++++++++++++++++++++++++++++------------- lime/app/Promise.hx | 30 +++++---- 2 files changed, 123 insertions(+), 52 deletions(-) diff --git a/lime/app/Future.hx b/lime/app/Future.hx index 60c05f0ec..0b188dfc4 100644 --- a/lime/app/Future.hx +++ b/lime/app/Future.hx @@ -1,24 +1,23 @@ package lime.app; +import lime.system.System; import lime.system.ThreadPool; +import lime.utils.Log; @:allow(lime.app.Promise) -class Future { +/*@:generic*/ class Future { - private static var __threadPool:ThreadPool; - - public var isCompleted (get, null):Bool; + public var error:Dynamic; + public var isComplete (default, null):Bool; + public var isError (default, null):Bool; public var value (default, null):T; - private var __completed:Bool; private var __completeListeners:ArrayVoid>; - private var __errored:Bool; private var __errorListeners:ArrayVoid>; - private var __errorMessage:Dynamic; private var __progressListeners:ArrayVoid>; @@ -26,19 +25,10 @@ class Future { if (work != null) { - if (__threadPool == null) { - - __threadPool = new ThreadPool (); - __threadPool.doWork.add (threadPool_doWork); - __threadPool.onComplete.add (threadPool_onComplete); - __threadPool.onError.add (threadPool_onError); - - } - var promise = new Promise (); promise.future = this; - __threadPool.queue ({ promise: promise, work: work } ); + FutureWork.queue ({ promise: promise, work: work }); } @@ -49,11 +39,11 @@ class Future { if (listener != null) { - if (__completed) { + if (isComplete) { listener (value); - } else if (!__errored) { + } else if (!isError) { if (__completeListeners == null) { @@ -76,11 +66,11 @@ class Future { if (listener != null) { - if (__errored) { + if (isError) { - listener (__errorMessage); + listener (error); - } else if (!__completed) { + } else if (!isComplete) { if (__errorListeners == null) { @@ -118,16 +108,78 @@ class Future { } + public function ready (waitTime:Int = -1):Future { + + #if js + + if (isComplete || isError) { + + return this; + + } else { + + Log.warn ("Cannot block thread in JavaScript"); + return this; + + } + + #else + + if (isComplete || isError) { + + return this; + + } else { + + var time = System.getTimer (); + var end = (waitTime > -1) ? time + waitTime : time; + + while (!isComplete && !isError && time <= end) { + + #if sys + Sys.sleep (0.01); + #end + + time = System.getTimer (); + + } + + return this; + + } + + #end + + } + + + public function result (waitTime:Int = -1):Null { + + ready (waitTime); + + if (isComplete) { + + return value; + + } else { + + return null; + + } + + } + + public function then (next:T->Future):Future { - if (__completed) { + if (isComplete) { return next (value); - } else if (__errored) { + } else if (isError) { var future = new Future (); - future.onError (__errorMessage); + future.onError (error); return future; } else { @@ -152,6 +204,31 @@ class Future { } +} + + +@:dox(hide) private class FutureWork { + + + private static var threadPool:ThreadPool; + + + public static function queue (state:Dynamic = null):Void { + + if (threadPool == null) { + + threadPool = new ThreadPool (); + threadPool.doWork.add (threadPool_doWork); + threadPool.onComplete.add (threadPool_onComplete); + threadPool.onError.add (threadPool_onError); + + } + + threadPool.queue (state); + + } + + // Event Handlers @@ -164,11 +241,11 @@ class Future { try { var result = state.work (); - __threadPool.sendComplete ({ promise: state.promise, result: result } ); + threadPool.sendComplete ({ promise: state.promise, result: result } ); } catch (e:Dynamic) { - __threadPool.sendError ({ promise: state.promise, error: e } ); + threadPool.sendError ({ promise: state.promise, error: e } ); } @@ -189,18 +266,4 @@ class Future { } - - - // Get & Set Methods - - - - - private function get_isCompleted ():Bool { - - return (__completed || __errored); - - } - - } \ No newline at end of file diff --git a/lime/app/Promise.hx b/lime/app/Promise.hx index 62c35e318..cfc795abc 100644 --- a/lime/app/Promise.hx +++ b/lime/app/Promise.hx @@ -4,25 +4,26 @@ package lime.app; @:allow(lime.app.Future) -class Promise { +@:generic class Promise { public var future (default, null):Future; - public var isCompleted (get, null):Bool; + public var isComplete (get, null):Bool; + public var isError (get, null):Bool; public function new () { - future = new Future (); + future = new Future (); } public function complete (data:T):Promise { - if (!future.__errored) { + if (!future.isError) { - future.__completed = true; + future.isComplete = true; future.value = data; if (future.__completeListeners != null) { @@ -58,10 +59,10 @@ class Promise { public function error (msg:Dynamic):Promise { - if (!future.__completed) { + if (!future.isComplete) { - future.__errored = true; - future.__errorMessage = msg; + future.isError = true; + future.error = msg; if (future.__errorListeners != null) { @@ -84,7 +85,7 @@ class Promise { public function progress (progress:Float):Promise { - if (!future.__errored && !future.__completed) { + if (!future.isError && !future.isComplete) { if (future.__progressListeners != null) { @@ -110,9 +111,16 @@ class Promise { - private function get_isCompleted ():Bool { + private function get_isComplete ():Bool { - return future.isCompleted; + return future.isComplete; + + } + + + private function get_isError ():Bool { + + return future.isError; }