| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** Common functionality to all send ports. */ | 5 /** Common functionality to all send ports. */ |
| 6 class _BaseSendPort implements SendPort { | 6 class _BaseSendPort implements SendPort { |
| 7 /** Id for the destination isolate. */ | 7 /** Id for the destination isolate. */ |
| 8 final int _isolateId; | 8 final int _isolateId; |
| 9 | 9 |
| 10 _BaseSendPort(this._isolateId); | 10 _BaseSendPort(this._isolateId); |
| 11 | 11 |
| 12 _ReceivePortSingleShotImpl call(var message) { | |
| 13 final result = new _ReceivePortSingleShotImpl(); | |
| 14 this.send(message, result.toSendPort()); | |
| 15 return result; | |
| 16 } | |
| 17 | |
| 18 static void checkReplyTo(SendPort replyTo) { | 12 static void checkReplyTo(SendPort replyTo) { |
| 19 if (replyTo !== null | 13 if (replyTo !== null |
| 20 && replyTo is! _NativeJsSendPort | 14 && replyTo is! _NativeJsSendPort |
| 21 && replyTo is! _WorkerSendPort | 15 && replyTo is! _WorkerSendPort |
| 22 && replyTo is! _BufferingSendPort) { | 16 && replyTo is! _BufferingSendPort) { |
| 23 throw new Exception("SendPort.send: Illegal replyTo port type"); | 17 throw new Exception("SendPort.send: Illegal replyTo port type"); |
| 24 } | 18 } |
| 25 } | 19 } |
| 26 | 20 |
| 27 // TODO(sigmund): replace the current SendPort.call with the following: | 21 Future call(var message) { |
| 28 //Future call(var message) { | 22 final completer = new Completer(); |
| 29 // final completer = new Completer(); | 23 final port = new _ReceivePortImpl(); |
| 30 // final port = new _ReceivePort.singleShot(); | 24 send(message, port.toSendPort()); |
| 31 // send(message, port.toSendPort()); | 25 port.receive((value, ignoreReplyTo) { |
| 32 // port.receive((value, ignoreReplyTo) { | 26 port.close(); |
| 33 // if (value is Exception) { | 27 if (value is Exception) { |
| 34 // completer.completeException(value); | 28 completer.completeException(value); |
| 35 // } else { | 29 } else { |
| 36 // completer.complete(value); | 30 completer.complete(value); |
| 37 // } | 31 } |
| 38 // }); | 32 }); |
| 39 // return completer.future; | 33 return completer.future; |
| 40 //} | 34 } |
| 41 | 35 |
| 42 abstract void send(var message, [SendPort replyTo]); | 36 abstract void send(var message, [SendPort replyTo]); |
| 43 abstract bool operator ==(var other); | 37 abstract bool operator ==(var other); |
| 44 abstract int hashCode(); | 38 abstract int hashCode(); |
| 45 } | 39 } |
| 46 | 40 |
| 47 /** A send port that delivers messages in-memory via native JavaScript calls. */ | 41 /** A send port that delivers messages in-memory via native JavaScript calls. */ |
| 48 class _NativeJsSendPort extends _BaseSendPort implements SendPort { | 42 class _NativeJsSendPort extends _BaseSendPort implements SendPort { |
| 49 final _ReceivePortImpl _receivePort; | 43 final _ReceivePortImpl _receivePort; |
| 50 | 44 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 int hashCode() => _id; | 174 int hashCode() => _id; |
| 181 } | 175 } |
| 182 | 176 |
| 183 /** Default factory for receive ports. */ | 177 /** Default factory for receive ports. */ |
| 184 class _ReceivePortFactory { | 178 class _ReceivePortFactory { |
| 185 | 179 |
| 186 factory ReceivePort() { | 180 factory ReceivePort() { |
| 187 return new _ReceivePortImpl(); | 181 return new _ReceivePortImpl(); |
| 188 } | 182 } |
| 189 | 183 |
| 190 factory ReceivePort.singleShot() { | |
| 191 return new _ReceivePortSingleShotImpl(); | |
| 192 } | |
| 193 } | 184 } |
| 194 | 185 |
| 195 /** Implementation of a multi-use [ReceivePort] on top of JavaScript. */ | 186 /** Implementation of a multi-use [ReceivePort] on top of JavaScript. */ |
| 196 class _ReceivePortImpl implements ReceivePort { | 187 class _ReceivePortImpl implements ReceivePort { |
| 197 int _id; | 188 int _id; |
| 198 Function _callback; | 189 Function _callback; |
| 199 static int _nextFreeId = 1; | 190 static int _nextFreeId = 1; |
| 200 | 191 |
| 201 _ReceivePortImpl() | 192 _ReceivePortImpl() |
| 202 : _id = _nextFreeId++ { | 193 : _id = _nextFreeId++ { |
| 203 _globalState.currentContext.register(_id, this); | 194 _globalState.currentContext.register(_id, this); |
| 204 } | 195 } |
| 205 | 196 |
| 206 void receive(void onMessage(var message, SendPort replyTo)) { | 197 void receive(void onMessage(var message, SendPort replyTo)) { |
| 207 _callback = onMessage; | 198 _callback = onMessage; |
| 208 } | 199 } |
| 209 | 200 |
| 210 void close() { | 201 void close() { |
| 211 _callback = null; | 202 _callback = null; |
| 212 _globalState.currentContext.unregister(_id); | 203 _globalState.currentContext.unregister(_id); |
| 213 } | 204 } |
| 214 | 205 |
| 215 SendPort toSendPort() { | 206 SendPort toSendPort() { |
| 216 return new _NativeJsSendPort(this, _globalState.currentContext.id); | 207 return new _NativeJsSendPort(this, _globalState.currentContext.id); |
| 217 } | 208 } |
| 218 } | 209 } |
| 219 | 210 |
| 220 /** Implementation of a single-shot [ReceivePort]. */ | |
| 221 class _ReceivePortSingleShotImpl implements ReceivePort { | |
| 222 | |
| 223 _ReceivePortSingleShotImpl() : _port = new _ReceivePortImpl() { } | |
| 224 | |
| 225 void receive(void callback(var message, SendPort replyTo)) { | |
| 226 _port.receive((var message, SendPort replyTo) { | |
| 227 _port.close(); | |
| 228 callback(message, replyTo); | |
| 229 }); | |
| 230 } | |
| 231 | |
| 232 void close() { | |
| 233 _port.close(); | |
| 234 } | |
| 235 | |
| 236 SendPort toSendPort() => _port.toSendPort(); | |
| 237 | |
| 238 final _ReceivePortImpl _port; | |
| 239 } | |
| 240 | |
| 241 /** Wait until all ports in a message are resolved. */ | 211 /** Wait until all ports in a message are resolved. */ |
| 242 _waitForPendingPorts(var message, void callback()) { | 212 _waitForPendingPorts(var message, void callback()) { |
| 243 final finder = new _PendingSendPortFinder(); | 213 final finder = new _PendingSendPortFinder(); |
| 244 finder.traverse(message); | 214 finder.traverse(message); |
| 245 Futures.wait(finder.ports).then((_) => callback()); | 215 Futures.wait(finder.ports).then((_) => callback()); |
| 246 } | 216 } |
| 247 | 217 |
| 248 | 218 |
| 249 /** Visitor that finds all unresolved [SendPort]s in a message. */ | 219 /** Visitor that finds all unresolved [SendPort]s in a message. */ |
| 250 class _PendingSendPortFinder extends _MessageTraverser { | 220 class _PendingSendPortFinder extends _MessageTraverser { |
| 251 List<Future<SendPort>> ports; | 221 List<Future<SendPort>> ports; |
| 252 _PendingSendPortFinder() : super(), ports = []; | 222 _PendingSendPortFinder() : super(), ports = []; |
| 253 | 223 |
| 254 visitPrimitive(x) {} | 224 visitPrimitive(x) {} |
| 255 visitNativeJsSendPort(_NativeJsSendPort port) {} | 225 visitNativeJsSendPort(_NativeJsSendPort port) {} |
| 256 visitWorkerSendPort(_WorkerSendPort port) {} | 226 visitWorkerSendPort(_WorkerSendPort port) {} |
| 257 visitReceivePort(_ReceivePortImpl port) {} | |
| 258 visitReceivePortSingleShot(_ReceivePortSingleShotImpl port) {} | |
| 259 | 227 |
| 260 visitList(List list) { | 228 visitList(List list) { |
| 261 final visited = _getInfo(list); | 229 final visited = _getInfo(list); |
| 262 if (visited !== null) return; | 230 if (visited !== null) return; |
| 263 _attachInfo(list, true); | 231 _attachInfo(list, true); |
| 264 // TODO(sigmund): replace with the following: (bug #1660) | 232 // TODO(sigmund): replace with the following: (bug #1660) |
| 265 // list.forEach(_dispatch); | 233 // list.forEach(_dispatch); |
| 266 list.forEach((e) => _dispatch(e)); | 234 list.forEach((e) => _dispatch(e)); |
| 267 } | 235 } |
| 268 | 236 |
| 269 visitMap(Map map) { | 237 visitMap(Map map) { |
| 270 final visited = _getInfo(map); | 238 final visited = _getInfo(map); |
| 271 if (visited !== null) return; | 239 if (visited !== null) return; |
| 272 | 240 |
| 273 _attachInfo(map, true); | 241 _attachInfo(map, true); |
| 274 // TODO(sigmund): replace with the following: (bug #1660) | 242 // TODO(sigmund): replace with the following: (bug #1660) |
| 275 // map.getValues().forEach(_dispatch); | 243 // map.getValues().forEach(_dispatch); |
| 276 map.getValues().forEach((e) => _dispatch(e)); | 244 map.getValues().forEach((e) => _dispatch(e)); |
| 277 } | 245 } |
| 278 | 246 |
| 279 visitBufferingSendPort(_BufferingSendPort port) { | 247 visitBufferingSendPort(_BufferingSendPort port) { |
| 280 if (port._port == null) { | 248 if (port._port == null) { |
| 281 ports.add(port._futurePort); | 249 ports.add(port._futurePort); |
| 282 } | 250 } |
| 283 } | 251 } |
| 284 } | 252 } |
| OLD | NEW |