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 library fn; | 5 library fn; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:collection'; | 8 import 'dart:collection'; |
9 import 'dart:sky' as sky; | 9 import 'dart:sky' as sky; |
10 import 'reflect.dart' as reflect; | 10 import 'reflect.dart' as reflect; |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 sw.stop(); | 521 sw.stop(); |
522 if (_shouldLogRenderDuration) | 522 if (_shouldLogRenderDuration) |
523 print("Render took ${sw.elapsedMicroseconds} microseconds"); | 523 print("Render took ${sw.elapsedMicroseconds} microseconds"); |
524 } finally { | 524 } finally { |
525 _inRenderDirtyComponents = false; | 525 _inRenderDirtyComponents = false; |
526 } | 526 } |
527 } | 527 } |
528 | 528 |
529 void _scheduleComponentForRender(Component c) { | 529 void _scheduleComponentForRender(Component c) { |
530 assert(!_inRenderDirtyComponents); | 530 assert(!_inRenderDirtyComponents); |
531 if (_inRenderDirtyComponents) | |
532 return; | |
533 | |
534 _dirtyComponents.add(c); | 531 _dirtyComponents.add(c); |
535 | 532 |
536 if (!_renderScheduled) { | 533 if (!_renderScheduled) { |
537 _renderScheduled = true; | 534 _renderScheduled = true; |
538 new Future.microtask(_renderDirtyComponents); | 535 new Future.microtask(_renderDirtyComponents); |
539 } | 536 } |
540 } | 537 } |
541 | 538 |
542 abstract class Component extends Node { | 539 abstract class Component extends Node { |
543 bool _dirty = true; // components begin dirty because they haven't rendered. | 540 bool _dirty = true; // components begin dirty because they haven't rendered. |
544 Node _rendered = null; | 541 Node _rendered = null; |
545 bool _removed = false; | 542 bool _removed = false; |
546 final int _order; | 543 final int _order; |
547 static int _currentOrder = 0; | 544 static int _currentOrder = 0; |
548 bool _stateful; | 545 bool _stateful; |
549 static Component _currentlyRendering; | 546 static Component _currentlyRendering; |
550 | 547 |
551 Component({ Object key, bool stateful }) | 548 Component({ Object key, bool stateful }) |
552 : _stateful = stateful != null ? stateful : false, | 549 : _stateful = stateful != null ? stateful : false, |
553 _order = _currentOrder + 1, | 550 _order = _currentOrder + 1, |
554 super(key:key); | 551 super(key:key); |
555 | 552 |
556 void willUnmount() {} | 553 void didUnmount() {} |
557 | 554 |
558 void _remove() { | 555 void _remove() { |
559 assert(_rendered != null); | 556 assert(_rendered != null); |
560 assert(_root != null); | 557 assert(_root != null); |
561 willUnmount(); | |
562 _rendered._remove(); | 558 _rendered._remove(); |
563 _rendered = null; | 559 _rendered = null; |
564 _root = null; | 560 _root = null; |
565 _removed = true; | 561 _removed = true; |
| 562 didUnmount(); |
566 } | 563 } |
567 | 564 |
568 // TODO(rafaelw): It seems wrong to expose DOM at all. This is presently | 565 // TODO(rafaelw): It seems wrong to expose DOM at all. This is presently |
569 // needed to get sizing info. | 566 // needed to get sizing info. |
570 sky.Node getRoot() => _root; | 567 sky.Node getRoot() => _root; |
571 | 568 |
572 bool _sync(Node old, sky.Node host, sky.Node insertBefore) { | 569 bool _sync(Node old, sky.Node host, sky.Node insertBefore) { |
573 Component oldComponent = old as Component; | 570 Component oldComponent = old as Component; |
574 | 571 |
575 if (oldComponent == null || oldComponent == this) { | 572 if (oldComponent == null || oldComponent == this) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 var rendered = _rendered; | 630 var rendered = _rendered; |
634 while (rendered is Component) { | 631 while (rendered is Component) { |
635 rendered = rendered._rendered; | 632 rendered = rendered._rendered; |
636 } | 633 } |
637 sky.Node root = rendered._root; | 634 sky.Node root = rendered._root; |
638 | 635 |
639 _renderInternal(root.parentNode, root.nextSibling); | 636 _renderInternal(root.parentNode, root.nextSibling); |
640 } | 637 } |
641 | 638 |
642 void setState(Function fn()) { | 639 void setState(Function fn()) { |
643 assert(_rendered != null); // cannot setState before mounting. | 640 assert(_rendered != null || _removed); // cannot setState before mounting. |
644 _stateful = true; | 641 _stateful = true; |
645 fn(); | 642 fn(); |
646 if (_currentlyRendering != this) { | 643 if (!_removed && _currentlyRendering != this) { |
647 _dirty = true; | 644 _dirty = true; |
648 _scheduleComponentForRender(this); | 645 _scheduleComponentForRender(this); |
649 } | 646 } |
650 } | 647 } |
651 | 648 |
652 Node render(); | 649 Node render(); |
653 } | 650 } |
654 | 651 |
655 abstract class App extends Component { | 652 abstract class App extends Component { |
656 sky.Node _host = null; | 653 sky.Node _host = null; |
657 App() : super(stateful: true) { | 654 App() : super(stateful: true) { |
658 _host = sky.document.createElement('div'); | 655 _host = sky.document.createElement('div'); |
659 sky.document.appendChild(_host); | 656 sky.document.appendChild(_host); |
660 | 657 |
661 new Future.microtask(() { | 658 new Future.microtask(() { |
662 Stopwatch sw = new Stopwatch()..start(); | 659 Stopwatch sw = new Stopwatch()..start(); |
663 | 660 |
664 _sync(null, _host, null); | 661 _sync(null, _host, null); |
665 assert(_root is sky.Node); | 662 assert(_root is sky.Node); |
666 | 663 |
667 sw.stop(); | 664 sw.stop(); |
668 if (_shouldLogRenderDuration) | 665 if (_shouldLogRenderDuration) |
669 print("Initial render: ${sw.elapsedMicroseconds} microseconds"); | 666 print("Initial render: ${sw.elapsedMicroseconds} microseconds"); |
670 }); | 667 }); |
671 } | 668 } |
672 } | 669 } |
OLD | NEW |