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 |