OLD | NEW |
| (Empty) |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library pub.asset.serialize.aggregate_transform; | |
6 | |
7 import 'dart:async'; | |
8 import 'dart:isolate'; | |
9 | |
10 import 'package:barback/barback.dart'; | |
11 // TODO(nweiz): don't import from "src" once issue 14966 is fixed. | |
12 import 'package:barback/src/internal_asset.dart'; | |
13 | |
14 import '../serialize.dart'; | |
15 import 'get_input_transform.dart'; | |
16 | |
17 /// Serialize the methods shared between [AggregateTransform] and | |
18 /// [DeclaringAggregateTransform]. | |
19 /// | |
20 /// [additionalFields] contains additional serialized fields to add to the | |
21 /// serialized transform. [methodHandlers] is a set of additional methods. Each | |
22 /// value should take a JSON message and return the response (which may be a | |
23 /// Future). | |
24 Map _serializeBaseAggregateTransform(transform, Map additionalFields, | |
25 Map<String, Function> methodHandlers) { | |
26 var receivePort = new ReceivePort(); | |
27 receivePort.listen((wrappedMessage) { | |
28 respond(wrappedMessage, (message) { | |
29 var handler = methodHandlers[message['type']]; | |
30 if (handler != null) return handler(message); | |
31 | |
32 if (message['type'] == 'consumePrimary') { | |
33 transform.consumePrimary(deserializeId(message['assetId'])); | |
34 return null; | |
35 } | |
36 | |
37 assert(message['type'] == 'log'); | |
38 var method = { | |
39 'Info': transform.logger.info, | |
40 'Fine': transform.logger.fine, | |
41 'Warning': transform.logger.warning, | |
42 'Error': transform.logger.error | |
43 }[message['level']]; | |
44 assert(method != null); | |
45 | |
46 var assetId = message['assetId'] == null ? null : | |
47 deserializeId(message['assetId']); | |
48 var span = message['span'] == null ? null : | |
49 deserializeSpan(message['span']); | |
50 method(message['message'], asset: assetId, span: span); | |
51 }); | |
52 }); | |
53 | |
54 return { | |
55 'port': receivePort.sendPort, | |
56 'key': transform.key, | |
57 'package': transform.package | |
58 }..addAll(additionalFields); | |
59 } | |
60 | |
61 /// Converts [transform] into a serializable map. | |
62 Map serializeAggregateTransform(AggregateTransform transform) { | |
63 return _serializeBaseAggregateTransform(transform, { | |
64 'primaryInputs': serializeStream(transform.primaryInputs, serializeAsset) | |
65 }, { | |
66 'getInput': (message) => transform.getInput(deserializeId(message['id'])) | |
67 .then((asset) => serializeAsset(asset)), | |
68 'addOutput': (message) => | |
69 transform.addOutput(deserializeAsset(message['output'])) | |
70 }); | |
71 } | |
72 | |
73 /// Converts [transform] into a serializable map. | |
74 Map serializeDeclaringAggregateTransform( | |
75 DeclaringAggregateTransform transform) { | |
76 return _serializeBaseAggregateTransform(transform, { | |
77 'primaryIds': serializeStream(transform.primaryIds, serializeId) | |
78 }, { | |
79 'declareOutput': (message) => | |
80 transform.declareOutput(deserializeId(message['output'])) | |
81 }); | |
82 } | |
83 | |
84 /// The base class for wrappers for [AggregateTransform]s that are in the host | |
85 /// isolate. | |
86 class _ForeignBaseAggregateTransform { | |
87 /// The port with which we communicate with the host isolate. | |
88 /// | |
89 /// This port and all messages sent across it are specific to this transform. | |
90 final SendPort _port; | |
91 | |
92 final String key; | |
93 | |
94 final String package; | |
95 | |
96 TransformLogger get logger => _logger; | |
97 TransformLogger _logger; | |
98 | |
99 _ForeignBaseAggregateTransform(Map transform) | |
100 : _port = transform['port'], | |
101 key = transform['key'], | |
102 package = transform['package'] { | |
103 _logger = new TransformLogger((assetId, level, message, span) { | |
104 call(_port, { | |
105 'type': 'log', | |
106 'level': level.name, | |
107 'message': message, | |
108 'assetId': assetId == null ? null : serializeId(assetId), | |
109 'span': span == null ? null : serializeSpan(span) | |
110 }); | |
111 }); | |
112 } | |
113 | |
114 void consumePrimary(AssetId id) { | |
115 call(_port, {'type': 'consumePrimary', 'assetId': serializeId(id)}); | |
116 } | |
117 } | |
118 | |
119 // We can get away with only removing the class declarations in incompatible | |
120 // barback versions because merely referencing undefined types in type | |
121 // annotations isn't a static error. Only implementing an undefined interface is | |
122 // a static error. | |
123 //# if barback >=0.14.1 | |
124 | |
125 /// A wrapper for an [AggregateTransform] that's in the host isolate. | |
126 /// | |
127 /// This retrieves inputs from and sends outputs and logs to the host isolate. | |
128 class ForeignAggregateTransform extends _ForeignBaseAggregateTransform | |
129 with GetInputTransform implements AggregateTransform { | |
130 final Stream<Asset> primaryInputs; | |
131 | |
132 /// Creates a transform from a serialized map sent from the host isolate. | |
133 ForeignAggregateTransform(Map transform) | |
134 : primaryInputs = deserializeStream( | |
135 transform['primaryInputs'], deserializeAsset), | |
136 super(transform); | |
137 | |
138 Future<Asset> getInput(AssetId id) { | |
139 return call(_port, { | |
140 'type': 'getInput', | |
141 'id': serializeId(id) | |
142 }).then(deserializeAsset); | |
143 } | |
144 | |
145 void addOutput(Asset output) { | |
146 call(_port, { | |
147 'type': 'addOutput', | |
148 'output': serializeAsset(output) | |
149 }); | |
150 } | |
151 } | |
152 | |
153 /// A wrapper for a [DeclaringAggregateTransform] that's in the host isolate. | |
154 class ForeignDeclaringAggregateTransform | |
155 extends _ForeignBaseAggregateTransform | |
156 implements DeclaringAggregateTransform { | |
157 final Stream<AssetId> primaryIds; | |
158 | |
159 /// Creates a transform from a serializable map sent from the host isolate. | |
160 ForeignDeclaringAggregateTransform(Map transform) | |
161 : primaryIds = deserializeStream( | |
162 transform['primaryIds'], deserializeId), | |
163 super(transform); | |
164 | |
165 void declareOutput(AssetId id) { | |
166 call(_port, { | |
167 'type': 'declareOutput', | |
168 'output': serializeId(id) | |
169 }); | |
170 } | |
171 } | |
172 | |
173 //# end | |
OLD | NEW |