| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 // Dart core library. | |
| 6 | |
| 7 /** A promise to value of type [T] that may be computed asynchronously. */ | |
| 8 interface Promise<T> default PromiseImpl<T> { | |
| 9 | |
| 10 Promise(); | |
| 11 | |
| 12 /** A promise that already has a computed value. */ | |
| 13 Promise.fromValue(T value); | |
| 14 | |
| 15 /** | |
| 16 * The value once it is computed. It will be null when the promise is in | |
| 17 * progress ([:!isDone():]), when it was cancelled ([:isCancelled():]), or | |
| 18 * when the computed value is actually null. | |
| 19 */ | |
| 20 T get value(); | |
| 21 | |
| 22 /** | |
| 23 * Provide the computed value; throws an exception if a value has already been | |
| 24 * provided or the promise previously completed with an error; ignored if the | |
| 25 * promise was cancelled. | |
| 26 */ | |
| 27 void complete(T value); | |
| 28 | |
| 29 /** Error that occurred while computing the value, if any; null otherwise. */ | |
| 30 get error(); | |
| 31 | |
| 32 /** Indicate that an error was found while computing this value. */ | |
| 33 void fail(var error); | |
| 34 | |
| 35 /** Whether the asynchronous work is done (normally or with errors). */ | |
| 36 bool isDone(); | |
| 37 | |
| 38 /** Whether the work represented by this promise has been cancelled. */ | |
| 39 bool isCancelled(); | |
| 40 | |
| 41 /** Whether the work represented by this promise has computed a value. */ | |
| 42 bool hasValue(); | |
| 43 | |
| 44 /** Whether the work represented by this promise has finished in an error. */ | |
| 45 bool hasError(); | |
| 46 | |
| 47 /** Cancel the asynchronous work of this promise, if possible. */ | |
| 48 bool cancel(); | |
| 49 | |
| 50 /** Register a normal continuation to execute when the value is available. */ | |
| 51 void addCompleteHandler(void completeHandler(T result)); | |
| 52 | |
| 53 /** Register an error continuation to execute if an error is found. */ | |
| 54 void addErrorHandler(void errorHandler(var error)); | |
| 55 | |
| 56 /** Register a handler to execute when [cancel] is called. */ | |
| 57 void addCancelHandler(void cancelHandler()); | |
| 58 | |
| 59 /** | |
| 60 * When this promise completes, execute [callback]. The result of [callback] | |
| 61 * will be exposed through the returned promise. This promise, and the | |
| 62 * resulting promise (r) are connected as follows: | |
| 63 * - this.complete --> r.complete (with the result of [callback]) | |
| 64 * - this.error --> r.error (the same error is propagated to r) | |
| 65 * - this.cancel --> r.error (the cancellation is shown as an error to r) | |
| 66 * - r.cancel --> this continues executing regardless | |
| 67 */ | |
| 68 Promise then(callback(T value)); | |
| 69 | |
| 70 /** | |
| 71 * Converts this promise so that its result is a non-promise value. For | |
| 72 * instance, if this promise is of type Promise<Promise<Promise<T>>>, | |
| 73 * flatten returns a Promise<T>. | |
| 74 */ | |
| 75 Promise flatten(); | |
| 76 | |
| 77 /** | |
| 78 * Mark this promise as complete when some or all values in [arr] are | |
| 79 * computed. Every time one of the promises is computed, it is passed to | |
| 80 * [joinDone]. When [joinDone] returns true, this instance is marked as | |
| 81 * complete with the last value that was computed. | |
| 82 */ | |
| 83 void join(Collection<Promise> arr, bool joinDone(Promise completed)); | |
| 84 | |
| 85 /** | |
| 86 * Mark this promise as complete when [n] promises in [arr] complete, then | |
| 87 * cancel the rest of the promises in [arr] that didn't complete. | |
| 88 */ | |
| 89 void waitFor(Collection<Promise> arr, int n); | |
| 90 } | |
| 91 | |
| 92 | |
| 93 interface Proxy extends Promise<bool> default ProxyImpl { | |
| 94 | |
| 95 Proxy.forPort(SendPort port); | |
| 96 Proxy.forIsolate(Isolate isolate); | |
| 97 Proxy._forIsolateWithPromise(Isolate isolate, Promise<SendPort> promise); | |
| 98 /* | |
| 99 * The [Proxy.forReply] constructor is used to create a proxy for | |
| 100 * the object that will be the reply to a message send. | |
| 101 */ | |
| 102 Proxy.forReply(Promise<SendPort> port); | |
| 103 | |
| 104 void send(List message); | |
| 105 Promise call(List message); | |
| 106 | |
| 107 } | |
| 108 | |
| 109 | |
| 110 class ProxyImpl extends ProxyBase implements Proxy { | |
| 111 | |
| 112 ProxyImpl.forPort(SendPort port) | |
| 113 : super.forPort(port) { } | |
| 114 | |
| 115 ProxyImpl.forIsolate(Isolate isolate) | |
| 116 : this._forIsolateWithPromise(isolate, new Promise<SendPort>()); | |
| 117 | |
| 118 ProxyImpl._forIsolateWithPromise(Isolate isolate, Promise<SendPort> promise) | |
| 119 // TODO(floitsch): it seems wrong to call super.forReply here. | |
| 120 : super.forReply(promise) { | |
| 121 isolate.spawn().then((SendPort port) { | |
| 122 promise.complete(port); | |
| 123 }); | |
| 124 } | |
| 125 | |
| 126 /* | |
| 127 * The [Proxy.forReply] constructor is used to create a proxy for | |
| 128 * the object that will be the reply to a message send. | |
| 129 */ | |
| 130 ProxyImpl.forReply(Promise<SendPort> port) | |
| 131 : super.forReply(port) { } | |
| 132 | |
| 133 } | |
| 134 | |
| 135 | |
| 136 class Dispatcher<T> { | |
| 137 | |
| 138 Dispatcher(this.target) { } | |
| 139 | |
| 140 void _serve(ReceivePort port) { | |
| 141 port.receive((var message, SendPort replyTo) { | |
| 142 this.process(message, void reply(var response) { | |
| 143 Proxy proxy = new Proxy.forPort(replyTo); | |
| 144 proxy.send([response]); | |
| 145 }); | |
| 146 }); | |
| 147 } | |
| 148 | |
| 149 static SendPort serve(Dispatcher dispatcher) { | |
| 150 ReceivePort port = ProxyBase.register(dispatcher); | |
| 151 dispatcher._serve(port); | |
| 152 return port.toSendPort(); | |
| 153 } | |
| 154 | |
| 155 // BUG(5015671): DartC doesn't support 'abstract' yet. | |
| 156 /* abstract */ void process(var message, void reply(var response)) { | |
| 157 throw "Abstract method called"; | |
| 158 } | |
| 159 | |
| 160 T target; | |
| 161 | |
| 162 } | |
| 163 | |
| 164 // When a promise is sent across a port, it is converted to a | |
| 165 // Promise<SendPort> down which we must send a port to receive the | |
| 166 // completion value. Hand the Promise<SendPort> to this class to deal | |
| 167 // with it. | |
| 168 | |
| 169 class PromiseProxy<T> extends PromiseImpl<T> { | |
| 170 PromiseProxy(Promise<SendPort> sendCompleter) { | |
| 171 ReceivePort completer = new ReceivePort.singleShot(); | |
| 172 completer.receive((var msg, SendPort _) { | |
| 173 complete(msg[0]); | |
| 174 }); | |
| 175 sendCompleter.addCompleteHandler((SendPort port) { | |
| 176 port.send([completer.toSendPort()], null); | |
| 177 }); | |
| 178 } | |
| 179 } | |
| OLD | NEW |