Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(505)

Side by Side Diff: pkg/barback/lib/src/phase.dart

Issue 18650004: Make Assets know their ID. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Tweak doc. Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/barback/lib/src/asset_set.dart ('k') | pkg/barback/lib/src/transform.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 barback.phase; 5 library barback.phase;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'asset.dart'; 9 import 'asset.dart';
10 import 'asset_graph.dart'; 10 import 'asset_graph.dart';
11 import 'asset_id.dart'; 11 import 'asset_id.dart';
12 import 'asset_node.dart'; 12 import 'asset_node.dart';
13 import 'asset_set.dart';
13 import 'errors.dart'; 14 import 'errors.dart';
14 import 'transform_node.dart'; 15 import 'transform_node.dart';
15 import 'transformer.dart'; 16 import 'transformer.dart';
16 17
17 /// One phase in the ordered series of transformations in an [AssetGraph]. 18 /// One phase in the ordered series of transformations in an [AssetGraph].
18 /// 19 ///
19 /// Each phase can access outputs from previous phases and can in turn pass 20 /// Each phase can access outputs from previous phases and can in turn pass
20 /// outputs to later phases. Phases are processed strictly serially. All 21 /// outputs to later phases. Phases are processed strictly serially. All
21 /// transforms in a phase will be complete before moving on to the next phase. 22 /// transforms in a phase will be complete before moving on to the next phase.
22 /// Within a single phase, all transforms will be run in parallel. 23 /// Within a single phase, all transforms will be run in parallel.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 /// 63 ///
63 /// Outputs from this phase will be passed to it. 64 /// Outputs from this phase will be passed to it.
64 final Phase _next; 65 final Phase _next;
65 66
66 Phase(this.graph, this._index, this._transformers, this._next); 67 Phase(this.graph, this._index, this._transformers, this._next);
67 68
68 /// Updates the phase's inputs with [updated] and removes [removed]. 69 /// Updates the phase's inputs with [updated] and removes [removed].
69 /// 70 ///
70 /// This marks any affected [transforms] as dirty or discards them if their 71 /// This marks any affected [transforms] as dirty or discards them if their
71 /// inputs are removed. 72 /// inputs are removed.
72 void updateInputs(Map<AssetId, Asset> updated, Set<AssetId> removed) { 73 void updateInputs(AssetSet updated, Set<AssetId> removed) {
73 // Remove any nodes that are no longer being output. Handle removals first 74 // Remove any nodes that are no longer being output. Handle removals first
74 // in case there are assets that were removed by one transform but updated 75 // in case there are assets that were removed by one transform but updated
75 // by another. In that case, the update should win. 76 // by another. In that case, the update should win.
76 for (var id in removed) { 77 for (var id in removed) {
77 var node = inputs.remove(id); 78 var node = inputs.remove(id);
78 79
79 // Every transform that was using it is dirty now. 80 // Every transform that was using it is dirty now.
80 if (node != null) { 81 if (node != null) {
81 node.consumers.forEach((consumer) => consumer.dirty()); 82 node.consumers.forEach((consumer) => consumer.dirty());
82 } 83 }
83 } 84 }
84 85
85 // Update and new or modified assets. 86 // Update and new or modified assets.
86 updated.forEach((id, asset) { 87 for (var asset in updated) {
87 var node = inputs.putIfAbsent(id, () => new AssetNode(id)); 88 var node = inputs[asset.id];
88 89 if (node == null) {
89 // If it's a new node, remember that so we can see if any new transforms 90 // It's a new node. Add it and remember it so we can see if any new
90 // will consume it. 91 // transforms will consume it.
91 if (node.asset == null) _newInputs.add(node); 92 node = new AssetNode(asset);
92 93 inputs[asset.id] = node;
93 node.updateAsset(asset); 94 _newInputs.add(node);
94 }); 95 } else {
96 node.updateAsset(asset);
97 }
98 }
95 } 99 }
96 100
97 /// Processes this phase. 101 /// Processes this phase.
98 /// 102 ///
99 /// For all new inputs, it tries to see if there are transformers that can 103 /// For all new inputs, it tries to see if there are transformers that can
100 /// consume them. Then all applicable transforms are applied. 104 /// consume them. Then all applicable transforms are applied.
101 /// 105 ///
102 /// Returns a future that completes when processing is done. If there is 106 /// Returns a future that completes when processing is done. If there is
103 /// nothing to process, returns `null`. 107 /// nothing to process, returns `null`.
104 Future process() { 108 Future process() {
105 var future = _processNewInputs(); 109 var future = _processNewInputs();
106 if (future == null) { 110 if (future == null) {
107 return _processTransforms(); 111 return _processTransforms();
108 } 112 }
109 113
110 return future.then((_) => _processTransforms()); 114 return future.then((_) => _processTransforms());
111 } 115 }
112 116
113 /// Creates new transforms for any new inputs that are applicable. 117 /// Creates new transforms for any new inputs that are applicable.
114 Future _processNewInputs() { 118 Future _processNewInputs() {
115 if (_newInputs.isEmpty) return null; 119 if (_newInputs.isEmpty) return null;
116 120
117 var futures = []; 121 var futures = [];
118 for (var node in _newInputs) { 122 for (var node in _newInputs) {
119 for (var transformer in _transformers) { 123 for (var transformer in _transformers) {
120 // TODO(rnystrom): Catch all errors from isPrimary() and redirect 124 // TODO(rnystrom): Catch all errors from isPrimary() and redirect
121 // to results. 125 // to results.
122 futures.add(transformer.isPrimary(node.id).then((isPrimary) { 126 futures.add(transformer.isPrimary(node.asset).then((isPrimary) {
123 if (!isPrimary) return; 127 if (!isPrimary) return;
124 var transform = new TransformNode(this, transformer, node); 128 var transform = new TransformNode(this, transformer, node);
125 node.consumers.add(transform); 129 node.consumers.add(transform);
126 _transforms.add(transform); 130 _transforms.add(transform);
127 })); 131 }));
128 } 132 }
129 } 133 }
130 134
131 _newInputs.clear(); 135 _newInputs.clear();
132 136
133 return Future.wait(futures); 137 return Future.wait(futures);
134 } 138 }
135 139
136 /// Applies all currently wired up and dirty transforms. 140 /// Applies all currently wired up and dirty transforms.
137 /// 141 ///
138 /// Passes their outputs to the next phase. 142 /// Passes their outputs to the next phase.
139 Future _processTransforms() { 143 Future _processTransforms() {
140 var dirtyTransforms = _transforms.where((transform) => transform.isDirty); 144 var dirtyTransforms = _transforms.where((transform) => transform.isDirty);
141 if (dirtyTransforms.isEmpty) return null; 145 if (dirtyTransforms.isEmpty) return null;
142 146
143 return Future.wait(dirtyTransforms.map((transform) => transform.apply())) 147 return Future.wait(dirtyTransforms.map((transform) => transform.apply()))
144 .then((transformOutputs) { 148 .then((transformOutputs) {
145 // Collect all of the outputs. Since the transforms are run in parallel, 149 // Collect all of the outputs. Since the transforms are run in parallel,
146 // we have to be careful here to ensure that the result is deterministic 150 // we have to be careful here to ensure that the result is deterministic
147 // and not influenced by the order that transforms complete. 151 // and not influenced by the order that transforms complete.
148 var updated = new Map<AssetId, Asset>(); 152 var updated = new AssetSet();
149 var removed = new Set<AssetId>(); 153 var removed = new Set<AssetId>();
150 var collisions = new Set<AssetId>(); 154 var collisions = new Set<AssetId>();
151 155
152 // Handle the generated outputs of all transforms first. 156 // Handle the generated outputs of all transforms first.
153 for (var outputs in transformOutputs) { 157 for (var outputs in transformOutputs) {
154 // Collect the outputs of all transformers together. 158 // Collect the outputs of all transformers together.
155 outputs.updated.forEach((id, asset) { 159 for (var asset in outputs.updated) {
156 if (updated.containsKey(id)) { 160 if (updated.containsId(asset.id)) {
157 // Report a collision. 161 // Report a collision.
158 collisions.add(id); 162 collisions.add(asset.id);
159 } else { 163 } else {
160 // TODO(rnystrom): In the case of a collision, the asset that 164 // TODO(rnystrom): In the case of a collision, the asset that
161 // "wins" is chosen non-deterministically. Do something better. 165 // "wins" is chosen non-deterministically. Do something better.
162 updated[id] = asset; 166 updated.add(asset);
163 } 167 }
164 }); 168 }
165 169
166 // Track any assets no longer output by this transform. We don't 170 // Track any assets no longer output by this transform. We don't
167 // handle the case where *another* transform generates the asset 171 // handle the case where *another* transform generates the asset
168 // no longer generated by this one. updateInputs() handles that. 172 // no longer generated by this one. updateInputs() handles that.
169 removed.addAll(outputs.removed); 173 removed.addAll(outputs.removed);
170 } 174 }
171 175
172 // Report any collisions in deterministic order. 176 // Report any collisions in deterministic order.
173 collisions = collisions.toList(); 177 collisions = collisions.toList();
174 collisions.sort((a, b) => a.toString().compareTo(b.toString())); 178 collisions.sort((a, b) => a.toString().compareTo(b.toString()));
175 for (var collision in collisions) { 179 for (var collision in collisions) {
176 graph.reportError(new AssetCollisionException(collision)); 180 graph.reportError(new AssetCollisionException(collision));
177 // TODO(rnystrom): Define what happens after a collision occurs. 181 // TODO(rnystrom): Define what happens after a collision occurs.
178 } 182 }
179 183
180 // Pass the outputs to the next phase. 184 // Pass the outputs to the next phase.
181 _next.updateInputs(updated, removed); 185 _next.updateInputs(updated, removed);
182 }); 186 });
183 } 187 }
184 } 188 }
OLDNEW
« no previous file with comments | « pkg/barback/lib/src/asset_set.dart ('k') | pkg/barback/lib/src/transform.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698