| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 import 'dart:async'; | 5 import 'dart:async'; |
| 6 import 'dart:isolate'; | 6 import 'dart:isolate'; |
| 7 | 7 |
| 8 import 'package:async/async.dart'; |
| 8 import 'package:barback/barback.dart'; | 9 import 'package:barback/barback.dart'; |
| 9 | 10 |
| 10 //# if source_span | 11 //# if source_span |
| 11 import 'package:source_span/source_span.dart'; | 12 import 'package:source_span/source_span.dart'; |
| 12 //# end | 13 //# end |
| 13 | 14 |
| 14 import 'serialize/exception.dart'; | 15 import 'serialize/exception.dart'; |
| 15 import 'utils.dart'; | |
| 16 | 16 |
| 17 export 'serialize/aggregate_transform.dart'; | 17 export 'serialize/aggregate_transform.dart'; |
| 18 export 'serialize/exception.dart'; | 18 export 'serialize/exception.dart'; |
| 19 export 'serialize/transform.dart'; | 19 export 'serialize/transform.dart'; |
| 20 export 'serialize/transformer.dart'; | 20 export 'serialize/transformer.dart'; |
| 21 | 21 |
| 22 /// Converts [id] into a serializable map. | 22 /// Converts [id] into a serializable map. |
| 23 Map serializeId(AssetId id) => {'package': id.package, 'path': id.path}; | 23 Map serializeId(AssetId id) => {'package': id.package, 'path': id.path}; |
| 24 | 24 |
| 25 /// Converts a serializable map into an [AssetId]. | 25 /// Converts a serializable map into an [AssetId]. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 SourceLocation deserializeLocation(Map location) { | 70 SourceLocation deserializeLocation(Map location) { |
| 71 return new SourceLocation(location['offset'], | 71 return new SourceLocation(location['offset'], |
| 72 sourceUrl: location['sourceUrl'], | 72 sourceUrl: location['sourceUrl'], |
| 73 line: location['line'], | 73 line: location['line'], |
| 74 column: location['column']); | 74 column: location['column']); |
| 75 } | 75 } |
| 76 | 76 |
| 77 /// Converts [stream] into a serializable map. | 77 /// Converts [stream] into a serializable map. |
| 78 /// | 78 /// |
| 79 /// [serializeEvent] is used to serialize each event from the stream. | 79 /// [serializeEvent] is used to serialize each event from the stream. |
| 80 Map serializeStream(Stream stream, serializeEvent(event)) { | 80 Map serializeStream/*<T>*/(Stream/*<T>*/ stream, serializeEvent(/*=T*/ event)) { |
| 81 var receivePort = new ReceivePort(); | 81 var receivePort = new ReceivePort(); |
| 82 var map = {'replyTo': receivePort.sendPort}; | 82 var map = {'replyTo': receivePort.sendPort}; |
| 83 | 83 |
| 84 receivePort.first.then((message) { | 84 receivePort.first.then((message) { |
| 85 var sendPort = message['replyTo']; | 85 var sendPort = message['replyTo']; |
| 86 stream.listen((event) { | 86 stream.listen((event) { |
| 87 sendPort.send({ | 87 sendPort.send({ |
| 88 'type': 'event', | 88 'type': 'event', |
| 89 'value': serializeEvent(event) | 89 'value': serializeEvent(event) |
| 90 }); | 90 }); |
| 91 }, onError: (error, stackTrace) { | 91 }, onError: (error, stackTrace) { |
| 92 sendPort.send({ | 92 sendPort.send({ |
| 93 'type': 'error', | 93 'type': 'error', |
| 94 'error': serializeException(error, stackTrace) | 94 'error': serializeException(error, stackTrace) |
| 95 }); | 95 }); |
| 96 }, onDone: () => sendPort.send({'type': 'done'})); | 96 }, onDone: () => sendPort.send({'type': 'done'})); |
| 97 }); | 97 }); |
| 98 | 98 |
| 99 return map; | 99 return map; |
| 100 } | 100 } |
| 101 | 101 |
| 102 /// Converts a serializable map into a [Stream]. | 102 /// Converts a serializable map into a [Stream]. |
| 103 /// | 103 /// |
| 104 /// [deserializeEvent] is used to deserialize each event from the stream. | 104 /// [deserializeEvent] is used to deserialize each event from the stream. |
| 105 Stream deserializeStream(Map stream, deserializeEvent(event)) { | 105 Stream/*<T>*/ deserializeStream/*<T>*/(Map stream, |
| 106 return callbackStream(() { | 106 /*=T*/ deserializeEvent(event)) { |
| 107 return new LazyStream(() { |
| 107 var receivePort = new ReceivePort(); | 108 var receivePort = new ReceivePort(); |
| 108 stream['replyTo'].send({'replyTo': receivePort.sendPort}); | 109 stream['replyTo'].send({'replyTo': receivePort.sendPort}); |
| 109 | 110 |
| 110 var controller = new StreamController(sync: true); | 111 var controller = new StreamController(sync: true); |
| 111 receivePort.listen((event) { | 112 receivePort.listen((event) { |
| 112 switch (event['type']) { | 113 switch (event['type']) { |
| 113 case 'event': | 114 case 'event': |
| 114 controller.add(deserializeEvent(event['value'])); | 115 controller.add(deserializeEvent(event['value'])); |
| 115 break; | 116 break; |
| 116 case 'error': | 117 case 'error': |
| 117 var exception = deserializeException(event['error']); | 118 var exception = deserializeException(event['error']); |
| 118 controller.addError(exception, exception.stackTrace); | 119 controller.addError(exception, exception.stackTrace); |
| 119 break; | 120 break; |
| 120 case 'done': | 121 case 'done': |
| 121 controller.close(); | 122 controller.close(); |
| 122 receivePort.close(); | 123 receivePort.close(); |
| 123 break; | 124 break; |
| 124 } | 125 } |
| 125 }); | 126 }); |
| 126 | 127 |
| 127 return controller.stream; | 128 return controller.stream; |
| 128 }); | 129 }); |
| 129 } | 130 } |
| 130 | 131 |
| 131 /// Wraps [message] and sends it across [port], then waits for a response which | 132 /// Wraps [message] and sends it across [port], then waits for a response which |
| 132 /// should be sent using [respond]. | 133 /// should be sent using [respond]. |
| 133 /// | 134 /// |
| 134 /// The returned Future will complete to the value or error returned by | 135 /// The returned Future will complete to the value or error returned by |
| 135 /// [respond]. | 136 /// [respond]. |
| 136 Future call(SendPort port, message) { | 137 Future/*<T>*/ call/*<T>*/(SendPort port, message) { |
| 137 var receivePort = new ReceivePort(); | 138 var receivePort = new ReceivePort(); |
| 138 port.send({ | 139 port.send({ |
| 139 'message': message, | 140 'message': message, |
| 140 'replyTo': receivePort.sendPort | 141 'replyTo': receivePort.sendPort |
| 141 }); | 142 }); |
| 142 | 143 |
| 143 return receivePort.first.then((response) { | 144 return new Future.sync(() async { |
| 144 if (response['type'] == 'success') return response['value']; | 145 var response = await receivePort.first; |
| 146 if (response['type'] == 'success') { |
| 147 return response['value'] as dynamic/*=T*/; |
| 148 } |
| 145 assert(response['type'] == 'error'); | 149 assert(response['type'] == 'error'); |
| 146 var exception = deserializeException(response['error']); | 150 var exception = deserializeException(response['error']); |
| 147 return new Future.error(exception, exception.stackTrace); | 151 return new Future.error(exception, exception.stackTrace); |
| 148 }); | 152 }); |
| 149 } | 153 } |
| 150 | 154 |
| 151 /// Responds to a message sent by [call]. | 155 /// Responds to a message sent by [call]. |
| 152 /// | 156 /// |
| 153 /// [wrappedMessage] is the raw message sent by [call]. This unwraps it and | 157 /// [wrappedMessage] is the raw message sent by [call]. This unwraps it and |
| 154 /// passes the contents of the message to [callback], then sends the return | 158 /// passes the contents of the message to [callback], then sends the return |
| 155 /// value of [callback] back to [call]. If [callback] returns a Future or | 159 /// value of [callback] back to [call]. If [callback] returns a Future or |
| 156 /// throws an error, that will also be sent. | 160 /// throws an error, that will also be sent. |
| 157 void respond(wrappedMessage, callback(message)) { | 161 void respond(wrappedMessage, callback(message)) { |
| 158 var replyTo = wrappedMessage['replyTo']; | 162 var replyTo = wrappedMessage['replyTo']; |
| 159 new Future.sync(() => callback(wrappedMessage['message'])) | 163 new Future.sync(() => callback(wrappedMessage['message'])) |
| 160 .then((result) => replyTo.send({'type': 'success', 'value': result})) | 164 .then((result) => replyTo.send({'type': 'success', 'value': result})) |
| 161 .catchError((error, stackTrace) { | 165 .catchError((error, stackTrace) { |
| 162 replyTo.send({ | 166 replyTo.send({ |
| 163 'type': 'error', | 167 'type': 'error', |
| 164 'error': serializeException(error, stackTrace) | 168 'error': serializeException(error, stackTrace) |
| 165 }); | 169 }); |
| 166 }); | 170 }); |
| 167 } | 171 } |
| OLD | NEW |