Chromium Code Reviews| 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 library pub.asset.serialize.transform; | 5 library pub.asset.serialize.transform; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:isolate'; | 8 import 'dart:isolate'; |
| 9 import 'dart:convert'; | 9 import 'dart:convert'; |
| 10 | 10 |
| 11 import 'package:barback/barback.dart'; | 11 import 'package:barback/barback.dart'; |
| 12 // TODO(nweiz): don't import from "src" once issue 14966 is fixed. | 12 // TODO(nweiz): don't import from "src" once issue 14966 is fixed. |
| 13 import 'package:barback/src/internal_asset.dart'; | 13 import 'package:barback/src/internal_asset.dart'; |
| 14 | 14 |
| 15 import '../serialize.dart'; | 15 import '../serialize.dart'; |
| 16 import '../utils.dart'; | 16 import '../utils.dart'; |
| 17 | 17 |
| 18 /// Converts [transform] into a serializable map. | 18 /// Serialize the methods shared between [Transform] and [DeclaringTransform]. |
| 19 Map serializeTransform(Transform transform) { | 19 /// |
| 20 /// [additionalFields] contains additional serialized fields to add to the | |
| 21 /// serialized transform. [handleMessage] handles additional methods that differ | |
| 22 /// between the two. It should return a [Future] if it handles a method, or | |
| 23 /// `null` if it doesn't. | |
| 24 Map _serializeBaseTransform(transform, Map additionalFields, | |
| 25 Future handleMessage(message)) { | |
|
Bob Nystrom
2014/04/16 16:21:00
Since handleMessage is specifically for handling m
nweiz
2014/04/16 20:28:21
Done.
| |
| 20 var receivePort = new ReceivePort(); | 26 var receivePort = new ReceivePort(); |
| 21 receivePort.listen((wrappedMessage) { | 27 receivePort.listen((wrappedMessage) { |
| 22 respond(wrappedMessage, (message) { | 28 respond(wrappedMessage, (message) { |
| 23 if (message['type'] == 'getInput') { | 29 var handled = handleMessage(message); |
| 24 return transform.getInput(deserializeId(message['id'])) | 30 if (handled != null) return handled; |
| 25 .then((asset) => serializeAsset(asset)); | |
| 26 } | |
| 27 | |
| 28 if (message['type'] == 'addOutput') { | |
| 29 transform.addOutput(deserializeAsset(message['output'])); | |
| 30 return null; | |
| 31 } | |
| 32 | 31 |
| 33 if (message['type'] == 'consumePrimary') { | 32 if (message['type'] == 'consumePrimary') { |
| 34 transform.consumePrimary(); | 33 transform.consumePrimary(); |
| 35 return null; | 34 return null; |
| 36 } | 35 } |
| 37 | 36 |
| 38 assert(message['type'] == 'log'); | 37 assert(message['type'] == 'log'); |
| 39 var method; | 38 var method; |
| 40 if (message['level'] == 'Info') { | 39 if (message['level'] == 'Info') { |
| 41 method = transform.logger.info; | 40 method = transform.logger.info; |
| 42 } else if (message['level'] == 'Fine') { | 41 } else if (message['level'] == 'Fine') { |
| 43 method = transform.logger.fine; | 42 method = transform.logger.fine; |
| 44 } else if (message['level'] == 'Warning') { | 43 } else if (message['level'] == 'Warning') { |
| 45 method = transform.logger.warning; | 44 method = transform.logger.warning; |
| 46 } else { | 45 } else { |
| 47 assert(message['level'] == 'Error'); | 46 assert(message['level'] == 'Error'); |
| 48 method = transform.logger.error; | 47 method = transform.logger.error; |
|
Bob Nystrom
2014/04/16 16:21:00
Seems like a map would be simpler here.
nweiz
2014/04/16 20:28:21
Done.
| |
| 49 } | 48 } |
| 50 | 49 |
| 51 var assetId = message['assetId'] == null ? null : | 50 var assetId = message['assetId'] == null ? null : |
| 52 deserializeId(message['assetId']); | 51 deserializeId(message['assetId']); |
| 53 var span = message['span'] == null ? null : | 52 var span = message['span'] == null ? null : |
| 54 deserializeSpan(message['span']); | 53 deserializeSpan(message['span']); |
| 55 method(message['message'], asset: assetId, span: span); | 54 method(message['message'], asset: assetId, span: span); |
| 56 }); | 55 }); |
| 57 }); | 56 }); |
| 58 | 57 |
| 59 return { | 58 return {'port': receivePort.sendPort}..addAll(additionalFields); |
| 60 'port': receivePort.sendPort, | |
| 61 'primaryInput': serializeAsset(transform.primaryInput) | |
| 62 }; | |
| 63 } | 59 } |
| 64 | 60 |
| 65 /// A wrapper for a [Transform] that's in the host isolate. | 61 /// Converts [transform] into a serializable map. |
| 66 /// | 62 Map serializeTransform(Transform transform) { |
| 67 /// This retrieves inputs from and sends outputs and logs to the host isolate. | 63 return _serializeBaseTransform(transform, { |
| 68 class ForeignTransform implements Transform { | 64 'primaryInput': serializeAsset(transform.primaryInput) |
| 65 }, (message) { | |
|
Bob Nystrom
2014/04/16 16:21:00
...and then here, do:
{
'getInput': () => retur
nweiz
2014/04/16 20:28:21
Done.
| |
| 66 if (message['type'] == 'getInput') { | |
| 67 return transform.getInput(deserializeId(message['id'])) | |
| 68 .then((asset) => serializeAsset(asset)); | |
| 69 } | |
| 70 | |
| 71 if (message['type'] != 'addOutput') return null; | |
| 72 | |
| 73 transform.addOutput(deserializeAsset(message['output'])); | |
| 74 return new Future.value(); | |
| 75 }); | |
| 76 } | |
| 77 | |
| 78 /// Converts [transform] into a serializable map. | |
| 79 Map serializeDeclaringTransform(DeclaringTransform transform) { | |
| 80 return _serializeBaseTransform(transform, { | |
| 81 'primaryId': serializeId(transform.primaryId) | |
| 82 }, (message) { | |
| 83 if (message['type'] != 'declareOutput') return null; | |
| 84 | |
| 85 transform.declareOutput(deserializeId(message['output'])); | |
| 86 return new Future.value(); | |
| 87 }); | |
| 88 } | |
| 89 | |
| 90 /// The base class for wrappers for [Transform]s that are in the host isolate. | |
| 91 class _ForeignBaseTransform { | |
| 69 /// The port with which we communicate with the host isolate. | 92 /// The port with which we communicate with the host isolate. |
| 70 /// | 93 /// |
| 71 /// This port and all messages sent across it are specific to this transform. | 94 /// This port and all messages sent across it are specific to this transform. |
| 72 final SendPort _port; | 95 final SendPort _port; |
| 73 | 96 |
| 74 final Asset primaryInput; | |
| 75 | |
| 76 TransformLogger get logger => _logger; | 97 TransformLogger get logger => _logger; |
| 77 TransformLogger _logger; | 98 TransformLogger _logger; |
| 78 | 99 |
| 79 /// Creates a transform from a serializable map sent from the host isolate. | 100 _ForeignBaseTransform(Map transform) |
| 80 ForeignTransform(Map transform) | 101 : _port = transform['port'] { |
| 81 : _port = transform['port'], | |
| 82 primaryInput = deserializeAsset(transform['primaryInput']) { | |
| 83 _logger = new TransformLogger((assetId, level, message, span) { | 102 _logger = new TransformLogger((assetId, level, message, span) { |
| 84 call(_port, { | 103 call(_port, { |
| 85 'type': 'log', | 104 'type': 'log', |
| 86 'level': level.name, | 105 'level': level.name, |
| 87 'message': message, | 106 'message': message, |
| 88 'assetId': assetId == null ? null : serializeId(assetId), | 107 'assetId': assetId == null ? null : serializeId(assetId), |
| 89 'span': span == null ? null : serializeSpan(span) | 108 'span': span == null ? null : serializeSpan(span) |
| 90 }); | 109 }); |
| 91 }); | 110 }); |
| 92 } | 111 } |
| 93 | 112 |
| 113 void consumePrimary() { | |
| 114 call(_port, {'type': 'consumePrimary'}); | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 /// A wrapper for a [Transform] that's in the host isolate. | |
| 119 /// | |
| 120 /// This retrieves inputs from and sends outputs and logs to the host isolate. | |
| 121 class ForeignTransform extends _ForeignBaseTransform implements Transform { | |
| 122 final Asset primaryInput; | |
| 123 | |
| 124 /// Creates a transform from a serializable map sent from the host isolate. | |
|
Bob Nystrom
2014/04/16 16:21:00
"serializable" -> "serialized".
nweiz
2014/04/16 20:28:21
Done.
| |
| 125 ForeignTransform(Map transform) | |
| 126 : primaryInput = deserializeAsset(transform['primaryInput']), | |
| 127 super(transform); | |
| 128 | |
| 94 Future<Asset> getInput(AssetId id) { | 129 Future<Asset> getInput(AssetId id) { |
| 95 return call(_port, { | 130 return call(_port, { |
| 96 'type': 'getInput', | 131 'type': 'getInput', |
| 97 'id': serializeId(id) | 132 'id': serializeId(id) |
| 98 }).then(deserializeAsset); | 133 }).then(deserializeAsset); |
| 99 } | 134 } |
| 100 | 135 |
| 101 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { | 136 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { |
| 102 if (encoding == null) encoding = UTF8; | 137 if (encoding == null) encoding = UTF8; |
| 103 return getInput(id).then((input) => input.readAsString(encoding: encoding)); | 138 return getInput(id).then((input) => input.readAsString(encoding: encoding)); |
| 104 } | 139 } |
| 105 | 140 |
| 106 Stream<List<int>> readInput(AssetId id) => | 141 Stream<List<int>> readInput(AssetId id) => |
| 107 futureStream(getInput(id).then((input) => input.read())); | 142 futureStream(getInput(id).then((input) => input.read())); |
| 108 | 143 |
| 109 Future<bool> hasInput(AssetId id) { | 144 Future<bool> hasInput(AssetId id) { |
| 110 return getInput(id).then((_) => true).catchError((error) { | 145 return getInput(id).then((_) => true).catchError((error) { |
| 111 if (error is AssetNotFoundException && error.id == id) return false; | 146 if (error is AssetNotFoundException && error.id == id) return false; |
| 112 throw error; | 147 throw error; |
| 113 }); | 148 }); |
| 114 } | 149 } |
| 115 | 150 |
| 116 void addOutput(Asset output) { | 151 void addOutput(Asset output) { |
| 117 call(_port, { | 152 call(_port, { |
| 118 'type': 'addOutput', | 153 'type': 'addOutput', |
| 119 'output': serializeAsset(output) | 154 'output': serializeAsset(output) |
| 120 }); | 155 }); |
| 121 } | 156 } |
| 157 } | |
| 122 | 158 |
| 123 void consumePrimary() { | 159 /// A wrapper for a [DeclaringTransform] that's in the host isolate. |
| 124 call(_port, {'type': 'consumePrimary'}); | 160 class ForeignDeclaringTransform extends _ForeignBaseTransform |
| 161 implements DeclaringTransform { | |
| 162 final AssetId primaryId; | |
| 163 | |
| 164 /// Creates a transform from a serializable map sent from the host isolate. | |
| 165 ForeignDeclaringTransform(Map transform) | |
| 166 : primaryId = deserializeId(transform['primaryId']), | |
| 167 super(transform); | |
| 168 | |
| 169 void declareOutput(AssetId id) { | |
| 170 call(_port, { | |
| 171 'type': 'declareOutput', | |
| 172 'output': serializeId(id) | |
| 173 }); | |
| 125 } | 174 } |
| 126 } | 175 } |
| OLD | NEW |