| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 import 'dart:async'; | 5 import 'dart:async'; |
| 6 import 'dart:collection'; | 6 import 'dart:collection'; |
| 7 import 'dart:mirrors'; | 7 import 'dart:mirrors'; |
| 8 import 'dart:sky' as sky; | 8 import 'dart:sky' as sky; |
| 9 | 9 |
| 10 import '../app/view.dart'; | 10 import '../app/view.dart'; |
| 11 import '../rendering/box.dart'; | 11 import '../rendering/box.dart'; |
| 12 import '../rendering/object.dart'; | 12 import '../rendering/object.dart'; |
| 13 | 13 |
| 14 export '../rendering/box.dart' show BoxConstraints, BoxDecoration, Border, Borde
rSide, EdgeDims; | 14 export '../rendering/box.dart' show BoxConstraints, BoxDecoration, Border, Borde
rSide, EdgeDims; |
| 15 export '../rendering/flex.dart' show FlexDirection; | 15 export '../rendering/flex.dart' show FlexDirection; |
| 16 export '../rendering/object.dart' show Point, Size, Rect, Color, Paint, Path; | 16 export '../rendering/object.dart' show Point, Size, Rect, Color, Paint, Path; |
| 17 | 17 |
| 18 | |
| 19 // final sky.Tracing _tracing = sky.window.tracing; | |
| 20 | |
| 21 final bool _shouldLogRenderDuration = false; | 18 final bool _shouldLogRenderDuration = false; |
| 22 | 19 |
| 23 /* | 20 // All Effen nodes derive from UINode. All nodes have a _parent, a _key and |
| 24 * All Effen nodes derive from UINode. All nodes have a _parent, a _key and | 21 // can be sync'd. |
| 25 * can be sync'd. | |
| 26 */ | |
| 27 abstract class UINode { | 22 abstract class UINode { |
| 28 | 23 |
| 29 UINode({ Object key }) { | 24 UINode({ String key }) { |
| 30 _key = key == null ? "$runtimeType" : "$runtimeType-$key"; | 25 _key = key == null ? "$runtimeType" : "$runtimeType-$key"; |
| 31 assert(this is AbstractUINodeRoot || _inRenderDirtyComponents); // you shoul
d not build the UI tree ahead of time, build it only during build() | 26 assert(this is AbstractUINodeRoot || _inRenderDirtyComponents); // you shoul
d not build the UI tree ahead of time, build it only during build() |
| 32 } | 27 } |
| 33 | 28 |
| 34 String _key; | 29 String _key; |
| 35 String get key => _key; | 30 String get key => _key; |
| 36 | 31 |
| 37 UINode _parent; | 32 UINode _parent; |
| 38 UINode get parent => _parent; | 33 UINode get parent => _parent; |
| 39 | 34 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 return node; | 145 return node; |
| 151 } | 146 } |
| 152 } | 147 } |
| 153 | 148 |
| 154 | 149 |
| 155 // Descendants of TagNode provide a way to tag RenderObjectWrapper and | 150 // Descendants of TagNode provide a way to tag RenderObjectWrapper and |
| 156 // Component nodes with annotations, such as event listeners, | 151 // Component nodes with annotations, such as event listeners, |
| 157 // stylistic information, etc. | 152 // stylistic information, etc. |
| 158 abstract class TagNode extends UINode { | 153 abstract class TagNode extends UINode { |
| 159 | 154 |
| 160 TagNode(UINode content, { Object key }) : this.content = content, super(key: k
ey); | 155 TagNode(UINode content, { String key }) |
| 156 : this.content = content, super(key: key); |
| 161 | 157 |
| 162 UINode content; | 158 UINode content; |
| 163 | 159 |
| 164 void _sync(UINode old, dynamic slot) { | 160 void _sync(UINode old, dynamic slot) { |
| 165 UINode oldContent = old == null ? null : (old as TagNode).content; | 161 UINode oldContent = old == null ? null : (old as TagNode).content; |
| 166 content = syncChild(content, oldContent, slot); | 162 content = syncChild(content, oldContent, slot); |
| 167 assert(content.root != null); | 163 assert(content.root != null); |
| 168 _root = content.root; | 164 _root = content.root; |
| 169 assert(_root == root); // in case a subclass reintroduces it | 165 assert(_root == root); // in case a subclass reintroduces it |
| 170 } | 166 } |
| 171 | 167 |
| 172 void remove() { | 168 void remove() { |
| 173 if (content != null) | 169 if (content != null) |
| 174 removeChild(content); | 170 removeChild(content); |
| 175 super.remove(); | 171 super.remove(); |
| 176 } | 172 } |
| 177 | 173 |
| 178 } | 174 } |
| 179 | 175 |
| 180 class ParentDataNode extends TagNode { | 176 class ParentDataNode extends TagNode { |
| 181 ParentDataNode(UINode content, this.parentData, { Object key }): super(content
, key: key); | 177 ParentDataNode(UINode content, this.parentData, { String key }) |
| 178 : super(content, key: key); |
| 182 final ParentData parentData; | 179 final ParentData parentData; |
| 183 } | 180 } |
| 184 | 181 |
| 185 typedef void GestureEventListener(sky.GestureEvent e); | 182 typedef void GestureEventListener(sky.GestureEvent e); |
| 186 typedef void PointerEventListener(sky.PointerEvent e); | 183 typedef void PointerEventListener(sky.PointerEvent e); |
| 187 typedef void EventListener(sky.Event e); | 184 typedef void EventListener(sky.Event e); |
| 188 | 185 |
| 189 class EventListenerNode extends TagNode { | 186 class EventListenerNode extends TagNode { |
| 190 | 187 |
| 191 EventListenerNode(UINode content, { | 188 EventListenerNode(UINode content, { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 if (listener != null) { | 265 if (listener != null) { |
| 269 listener(e); | 266 listener(e); |
| 270 } | 267 } |
| 271 } | 268 } |
| 272 | 269 |
| 273 } | 270 } |
| 274 | 271 |
| 275 | 272 |
| 276 abstract class Component extends UINode { | 273 abstract class Component extends UINode { |
| 277 | 274 |
| 278 Component({ Object key, bool stateful }) | 275 Component({ String key, bool stateful }) |
| 279 : _stateful = stateful != null ? stateful : false, | 276 : _stateful = stateful != null ? stateful : false, |
| 280 _order = _currentOrder + 1, | 277 _order = _currentOrder + 1, |
| 281 super(key: key); | 278 super(key: key); |
| 282 | 279 |
| 283 Component.fromArgs(Object key, bool stateful) | |
| 284 : this(key: key, stateful: stateful); | |
| 285 | |
| 286 static Component _currentlyBuilding; | 280 static Component _currentlyBuilding; |
| 287 bool get _isBuilding => _currentlyBuilding == this; | 281 bool get _isBuilding => _currentlyBuilding == this; |
| 288 | 282 |
| 289 bool _stateful; | 283 bool _stateful; |
| 290 bool _dirty = true; | 284 bool _dirty = true; |
| 291 bool _disqualifiedFromEverAppearingAgain = false; | 285 bool _disqualifiedFromEverAppearingAgain = false; |
| 292 | 286 |
| 293 UINode _built; | 287 UINode _built; |
| 294 dynamic _slot; // cached slot from the last time we were synced | 288 dynamic _slot; // cached slot from the last time we were synced |
| 295 | 289 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 // (but don't call super.syncFields() if you inherit directly from | 328 // (but don't call super.syncFields() if you inherit directly from |
| 335 // Component, since that'll fire an assert). | 329 // Component, since that'll fire an assert). |
| 336 // If you don't ever become stateful, then don't override this. | 330 // If you don't ever become stateful, then don't override this. |
| 337 void syncFields(Component source) { | 331 void syncFields(Component source) { |
| 338 assert(false); | 332 assert(false); |
| 339 } | 333 } |
| 340 | 334 |
| 341 final int _order; | 335 final int _order; |
| 342 static int _currentOrder = 0; | 336 static int _currentOrder = 0; |
| 343 | 337 |
| 344 /* There are three cases here: | 338 // There are three cases here: |
| 345 * 1) Building for the first time: | 339 // 1) Building for the first time: |
| 346 * assert(_built == null && old == null) | 340 // assert(_built == null && old == null) |
| 347 * 2) Re-building (because a dirty flag got set): | 341 // 2) Re-building (because a dirty flag got set): |
| 348 * assert(_built != null && old == null) | 342 // assert(_built != null && old == null) |
| 349 * 3) Syncing against an old version | 343 // 3) Syncing against an old version |
| 350 * assert(_built == null && old != null) | 344 // assert(_built == null && old != null) |
| 351 */ | |
| 352 void _sync(UINode old, dynamic slot) { | 345 void _sync(UINode old, dynamic slot) { |
| 353 assert(_built == null || old == null); | 346 assert(_built == null || old == null); |
| 354 assert(!_disqualifiedFromEverAppearingAgain); | 347 assert(!_disqualifiedFromEverAppearingAgain); |
| 355 | 348 |
| 356 Component oldComponent = old as Component; | 349 Component oldComponent = old as Component; |
| 357 | 350 |
| 358 _slot = slot; | 351 _slot = slot; |
| 359 | 352 |
| 360 var oldBuilt; | 353 var oldBuilt; |
| 361 if (oldComponent == null) { | 354 if (oldComponent == null) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 assert(!_inRenderDirtyComponents); | 442 assert(!_inRenderDirtyComponents); |
| 450 _dirtyComponents.add(c); | 443 _dirtyComponents.add(c); |
| 451 | 444 |
| 452 if (!_buildScheduled) { | 445 if (!_buildScheduled) { |
| 453 _buildScheduled = true; | 446 _buildScheduled = true; |
| 454 new Future.microtask(_buildDirtyComponents); | 447 new Future.microtask(_buildDirtyComponents); |
| 455 } | 448 } |
| 456 } | 449 } |
| 457 | 450 |
| 458 | 451 |
| 459 /* | 452 // RenderObjectWrappers correspond to a desired state of a RenderObject. |
| 460 * RenderObjectWrappers correspond to a desired state of a RenderObject. | 453 // They are fully immutable, with one exception: A UINode which is a |
| 461 * They are fully immutable, with one exception: A UINode which is a | 454 // Component which lives within an MultiChildRenderObjectWrapper's |
| 462 * Component which lives within an MultiChildRenderObjectWrapper's | 455 // children list, may be replaced with the "old" instance if it has |
| 463 * children list, may be replaced with the "old" instance if it has | 456 // become stateful. |
| 464 * become stateful. | |
| 465 */ | |
| 466 abstract class RenderObjectWrapper extends UINode { | 457 abstract class RenderObjectWrapper extends UINode { |
| 467 | 458 |
| 468 RenderObjectWrapper({ | 459 RenderObjectWrapper({ String key }) : super(key: key); |
| 469 Object key | |
| 470 }) : super(key: key); | |
| 471 | 460 |
| 472 RenderObject createNode(); | 461 RenderObject createNode(); |
| 473 | 462 |
| 474 void insert(RenderObjectWrapper child, dynamic slot); | 463 void insert(RenderObjectWrapper child, dynamic slot); |
| 475 | 464 |
| 476 static final Map<RenderObject, RenderObjectWrapper> _nodeMap = | 465 static final Map<RenderObject, RenderObjectWrapper> _nodeMap = |
| 477 new HashMap<RenderObject, RenderObjectWrapper>(); | 466 new HashMap<RenderObject, RenderObjectWrapper>(); |
| 478 | 467 |
| 479 static RenderObjectWrapper _getMounted(RenderObject node) => _nodeMap[node]; | 468 static RenderObjectWrapper _getMounted(RenderObject node) => _nodeMap[node]; |
| 480 | 469 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 | 506 |
| 518 void remove() { | 507 void remove() { |
| 519 assert(root != null); | 508 assert(root != null); |
| 520 _nodeMap.remove(root); | 509 _nodeMap.remove(root); |
| 521 super.remove(); | 510 super.remove(); |
| 522 } | 511 } |
| 523 } | 512 } |
| 524 | 513 |
| 525 abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper { | 514 abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper { |
| 526 | 515 |
| 527 OneChildRenderObjectWrapper({ UINode child, Object key }) : _child = child, su
per(key: key); | 516 OneChildRenderObjectWrapper({ UINode child, String key }) |
| 517 : _child = child, super(key: key); |
| 528 | 518 |
| 529 UINode _child; | 519 UINode _child; |
| 530 UINode get child => _child; | 520 UINode get child => _child; |
| 531 | 521 |
| 532 void syncRenderObject(RenderObjectWrapper old) { | 522 void syncRenderObject(RenderObjectWrapper old) { |
| 533 super.syncRenderObject(old); | 523 super.syncRenderObject(old); |
| 534 UINode oldChild = old == null ? null : (old as OneChildRenderObjectWrapper).
child; | 524 UINode oldChild = old == null ? null : (old as OneChildRenderObjectWrapper).
child; |
| 535 _child = syncChild(child, oldChild, null); | 525 _child = syncChild(child, oldChild, null); |
| 536 } | 526 } |
| 537 | 527 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 557 super.remove(); | 547 super.remove(); |
| 558 } | 548 } |
| 559 | 549 |
| 560 } | 550 } |
| 561 | 551 |
| 562 abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper { | 552 abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper { |
| 563 | 553 |
| 564 // In MultiChildRenderObjectWrapper subclasses, slots are RenderObject nodes | 554 // In MultiChildRenderObjectWrapper subclasses, slots are RenderObject nodes |
| 565 // to use as the "insert before" sibling in ContainerRenderObjectMixin.add() c
alls | 555 // to use as the "insert before" sibling in ContainerRenderObjectMixin.add() c
alls |
| 566 | 556 |
| 567 MultiChildRenderObjectWrapper({ | 557 MultiChildRenderObjectWrapper({ String key, List<UINode> children }) |
| 568 Object key, | 558 : this.children = children == null ? const [] : children, |
| 569 List<UINode> children | 559 super(key: key) { |
| 570 }) : this.children = children == null ? const [] : children, | |
| 571 super(key: key) { | |
| 572 assert(!_debugHasDuplicateIds()); | 560 assert(!_debugHasDuplicateIds()); |
| 573 } | 561 } |
| 574 | 562 |
| 575 final List<UINode> children; | 563 final List<UINode> children; |
| 576 | 564 |
| 577 void insert(RenderObjectWrapper child, dynamic slot) { | 565 void insert(RenderObjectWrapper child, dynamic slot) { |
| 578 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer | 566 final root = this.root; // TODO(ianh): Remove this once the analyzer is clev
erer |
| 579 assert(slot == null || slot is RenderObject); | 567 assert(slot == null || slot is RenderObject); |
| 580 assert(root is ContainerRenderObjectMixin); | 568 assert(root is ContainerRenderObjectMixin); |
| 581 root.add(child.root, before: slot); | 569 root.add(child.root, before: slot); |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 849 if (root.parent == null) { | 837 if (root.parent == null) { |
| 850 // we haven't attached it yet | 838 // we haven't attached it yet |
| 851 assert(_container.child == null); | 839 assert(_container.child == null); |
| 852 _container.child = root; | 840 _container.child = root; |
| 853 } | 841 } |
| 854 assert(root.parent == _container); | 842 assert(root.parent == _container); |
| 855 } | 843 } |
| 856 | 844 |
| 857 UINode build() => builder(); | 845 UINode build() => builder(); |
| 858 } | 846 } |
| OLD | NEW |