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

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

Issue 23038018: Factor a PhaseOutput class out of Phase. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review change. Created 7 years, 4 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/phase.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library barback.phase_output;
6
7 import 'dart:async';
8 import 'dart:collection';
9
10 import 'asset_cascade.dart';
11 import 'asset_id.dart';
12 import 'asset_node.dart';
13 import 'errors.dart';
14 import 'phase_input.dart';
15 import 'stream_pool.dart';
16 import 'transformer.dart';
17 import 'utils.dart';
18
19 /// A class that handles a single output of a phase.
20 ///
21 /// Normally there's only a single [AssetNode] for a phase's output, but it's
22 /// possible that multiple transformers in the same phase emit assets with the
23 /// same id, causing collisions. This handles those collisions by forwarding the
24 /// chronologically first asset.
25 class PhaseOutput {
26 /// The phase for which this is an output.
27 final Phase _phase;
28
29 /// The asset node for this output.
30 AssetNode get output => _outputController.node;
31 final AssetNodeController _outputController;
32
33 /// The assets for this output.
34 ///
35 /// If there's no collision, this will only have one element. Otherwise, it
36 /// will be ordered by which asset was added first.
37 final _assets = new Queue<AssetNode>();
38
39 /// The [AssetCollisionException] for this output, or null if there is no
40 /// collision currently.
41 AssetCollisionException get collisionException {
42 if (_assets.length == 1) return null;
43 return new AssetCollisionException(
44 _assets.where((asset) => asset.transform != null)
45 .map((asset) => asset.transform.info),
46 output.id);
47 }
48
49 PhaseOutput(this._phase, AssetNode output)
50 : _outputController = new AssetNodeController.from(output) {
51 assert(!output.state.isRemoved);
52 add(output);
53 }
54
55 /// Adds an asset node as an output with this id.
56 void add(AssetNode node) {
57 assert(node.id == output.id);
58 _assets.add(node);
59 _watchAsset(node);
60 }
61
62 /// Watches [node] for state changes and adjusts [_assets] and [output]
63 /// appropriately when they occur.
64 void _watchAsset(AssetNode node) {
65 node.onStateChange.listen((state) {
66 if (state.isRemoved) {
67 _removeAsset(node);
68 return;
69 }
70 if (_assets.first != node) return;
71
72 if (state.isAvailable) {
73 _outputController.setAvailable(node.asset);
74 } else {
75 assert(state.isDirty);
76 _outputController.setDirty();
77 }
78 });
79 }
80
81 /// Removes [node] as an output.
82 void _removeAsset(AssetNode node) {
83 if (_assets.length == 1) {
84 assert(_assets.single == node);
85 _outputController.setRemoved();
86 return;
87 }
88
89 // If there was more than one asset, we're resolving a collision --
90 // possibly partially.
91 var wasFirst = _assets.first == node;
92 _assets.remove(node);
93
94 // If this was the first asset, we replace it with the next asset
95 // (chronologically).
96 if (wasFirst) {
97 var newOutput = _assets.first;
98 _outputController.setTransform(newOutput.transform);
99 if (newOutput.state.isAvailable) {
100 if (output.state.isAvailable) _outputController.setDirty();
101 _outputController.setAvailable(newOutput.asset);
102 } else {
103 assert(newOutput.isDirty);
104 if (!output.isDirty) _outputController.setDirty();
105 }
106 }
107
108 // If there's still a collision, report it. This lets the user know
109 // if they've successfully resolved the collision or not.
110 if (_assets.length > 1) {
111 // Pump the event queue to ensure that the removal of the input triggers
112 // a new build to which we can attach the error.
113 // TODO(nweiz): report this through the output asset.
114 newFuture(() => _phase.cascade.reportError(collisionException));
115 }
116 }
117 }
OLDNEW
« no previous file with comments | « pkg/barback/lib/src/phase.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698