1
1
package lime .app ;
2
2
3
+ import lime .app .Future ;
4
+ import lime .system .ThreadPool ;
5
+ import lime .system .WorkOutput ;
6
+
3
7
/**
4
8
`Promise` is an implementation of Futures and Promises, with the exception that
5
9
in addition to "success" and "failure" states (represented as "complete" and "error"),
@@ -10,18 +14,20 @@ package lime.app;
10
14
for recipients of it's `Future` object. For example:
11
15
12
16
```haxe
13
- function examplePromise ():Future<String> {
14
-
15
- var promise = new Promise<String> ();
17
+ function examplePromise():Future<String>
18
+ {
19
+ var promise = new Promise<String>();
16
20
17
21
var progress = 0, total = 10;
18
- var timer = new Timer (100);
19
- timer.run = function () {
22
+ var timer = new Timer(100);
23
+ timer.run = function()
24
+ {
20
25
21
26
promise.progress (progress, total);
22
27
progress++;
23
28
24
- if (progress == total) {
29
+ if (progress == total)
30
+ {
25
31
26
32
promise.complete ("Done!");
27
33
timer.stop ();
@@ -31,12 +37,11 @@ package lime.app;
31
37
};
32
38
33
39
return promise.future;
34
-
35
40
}
36
41
37
- var future = examplePromise ();
38
- future.onComplete (function (message) { trace (message); });
39
- future.onProgress (function (loaded, total) { trace ("Progress: " + loaded + ", " + total); });
42
+ var future = examplePromise();
43
+ future.onComplete(function(message) { trace(message); });
44
+ future.onProgress(function(loaded, total) { trace("Progress: " + loaded + ", " + total); });
40
45
```
41
46
**/
42
47
#if !lime_debug
@@ -69,6 +74,8 @@ class Promise<T>
69
74
**/
70
75
public var isError (get , null ): Bool ;
71
76
77
+ private var jobID : Int = - 1 ;
78
+
72
79
#if commonjs
73
80
private static function __init__ ()
74
81
{
@@ -96,11 +103,23 @@ class Promise<T>
96
103
**/
97
104
public function complete (data : T ): Promise <T >
98
105
{
106
+ if (! ThreadPool .isMainThread ())
107
+ {
108
+ haxe. MainLoop .runInMainThread (complete .bind (data ));
109
+ return this ;
110
+ }
111
+
99
112
if (! future .isError )
100
113
{
101
114
future .isComplete = true ;
102
115
future .value = data ;
103
116
117
+ if (jobID != - 1 )
118
+ {
119
+ FutureWork .cancelJob (jobID );
120
+ jobID = - 1 ;
121
+ }
122
+
104
123
if (future .__completeListeners != null )
105
124
{
106
125
for (listener in future .__completeListeners )
@@ -115,6 +134,45 @@ class Promise<T>
115
134
return this ;
116
135
}
117
136
137
+ /**
138
+ Runs the given function asynchronously, and resolves this `Promise` with
139
+ the complete, error, and/or progress events sent by that function.
140
+ Sample usage:
141
+
142
+ ```haxe
143
+ function examplePromise():Future<String>
144
+ {
145
+ var promise = new Promise<String>();
146
+ promise.completeAsync(function(state:State, output:WorkOutput):Void
147
+ {
148
+ output.sendProgress({progress:state.progress, total:10});
149
+ state.progress++;
150
+
151
+ if (state.progress == 10)
152
+ {
153
+ output.sendComplete("Done!");
154
+ }
155
+ },
156
+ {progress: 0}, MULTI_THREADED);
157
+
158
+ return promise.future;
159
+ }
160
+
161
+ var future = examplePromise();
162
+ future.onComplete(function(message) { trace(message); });
163
+ future.onProgress(function(loaded, total) { trace("Progress: " + loaded + ", " + total); });
164
+ ```
165
+
166
+ @param doWork A function to perform work asynchronously. For best results,
167
+ see the guidelines in the `ThreadPool` class overview.
168
+ @param state The value to pass to `doWork`.
169
+ @param mode Which mode to run the job in: `SINGLE_THREADED` or `MULTI_THREADED`.
170
+ **/
171
+ public function completeAsync (doWork : WorkFunction <State -> WorkOutput -> Void >, ? state : State , ? mode : ThreadMode = MULTI_THREADED ): Void
172
+ {
173
+ jobID = FutureWork .run (doWork , this , state , mode );
174
+ }
175
+
118
176
/**
119
177
Resolves this `Promise` with the complete, error and/or progress state
120
178
of another `Future`
@@ -137,11 +195,23 @@ class Promise<T>
137
195
**/
138
196
public function error (msg : Dynamic ): Promise <T >
139
197
{
198
+ if (! ThreadPool .isMainThread ())
199
+ {
200
+ haxe. MainLoop .runInMainThread (error .bind (msg ));
201
+ return this ;
202
+ }
203
+
140
204
if (! future .isComplete )
141
205
{
142
206
future .isError = true ;
143
207
future .error = msg ;
144
208
209
+ if (jobID != - 1 )
210
+ {
211
+ FutureWork .cancelJob (jobID );
212
+ jobID = - 1 ;
213
+ }
214
+
145
215
if (future .__errorListeners != null )
146
216
{
147
217
for (listener in future .__errorListeners )
@@ -164,6 +234,12 @@ class Promise<T>
164
234
**/
165
235
public function progress (progress : Int , total : Int ): Promise <T >
166
236
{
237
+ if (! ThreadPool .isMainThread ())
238
+ {
239
+ haxe. MainLoop .runInMainThread (this .progress .bind (progress , total ));
240
+ return this ;
241
+ }
242
+
167
243
if (! future .isError && ! future .isComplete )
168
244
{
169
245
if (future .__progressListeners != null )
@@ -179,12 +255,12 @@ class Promise<T>
179
255
}
180
256
181
257
// Get & Set Methods
182
- @:noCompletion private function get_isComplete (): Bool
258
+ @:noCompletion private inline function get_isComplete (): Bool
183
259
{
184
260
return future .isComplete ;
185
261
}
186
262
187
- @:noCompletion private function get_isError (): Bool
263
+ @:noCompletion private inline function get_isError (): Bool
188
264
{
189
265
return future .isError ;
190
266
}
0 commit comments