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

Side by Side Diff: sky/examples/fn/lib/component.dart

Issue 971183002: Initial commit of Effen reactive framework experiment for Sky (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 9 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
« no previous file with comments | « sky/examples/fn/README.md ('k') | sky/examples/fn/lib/fakesky.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 part of fn;
2
3 List<Component> _dirtyComponents = new List<Component>();
4 bool _renderScheduled = false;
5
6 void _renderDirtyComponents() {
7 Stopwatch sw = new Stopwatch()..start();
8
9 _dirtyComponents.sort((a, b) => a._order - b._order);
10 for (var comp in _dirtyComponents) {
11 comp._renderIfDirty();
12 }
13
14 _dirtyComponents.clear();
15 _renderScheduled = false;
16 sw.stop();
17 print("Render took ${sw.elapsedMicroseconds} microseconds");
18 }
19
20 void _scheduleComponentForRender(Component c) {
21 _dirtyComponents.add(c);
22
23 if (!_renderScheduled) {
24 _renderScheduled = true;
25 new Future.microtask(_renderDirtyComponents);
26 }
27 }
28
29 abstract class Component extends Node {
30 bool _dirty = true; // components begin dirty because they haven't rendered.
31 Node _rendered = null;
32 bool _removed = false;
33 int _order;
34 static int _currentOrder = 0;
35 bool _stateful;
36 static Component _currentlyRendering;
37
38 Component({ Object key, bool stateful })
39 : _stateful = stateful != null ? stateful : false,
40 _order = _currentOrder + 1,
41 super(key:key);
42
43 void willUnmount() {}
44
45 void _remove() {
46 assert(_rendered != null);
47 assert(_root != null);
48 willUnmount();
49 _rendered._remove();
50 _rendered = null;
51 _root = null;
52 _removed = true;
53 }
54
55 // TODO(rafaelw): It seems wrong to expose DOM at all. This is presently
56 // needed to get sizing info.
57 sky.Node getRoot() => _root;
58
59 bool _sync(Node old, sky.Node host, sky.Node insertBefore) {
60 Component oldComponent = old as Component;
61
62 if (oldComponent == null || oldComponent == this) {
63 _renderInternal(host, insertBefore);
64 return false;
65 }
66
67 assert(oldComponent != null);
68 assert(_dirty);
69 assert(_rendered == null);
70
71 if (oldComponent._stateful) {
72 _stateful = false; // prevent iloop from _renderInternal below.
73
74 reflect.copyPublicFields(this, oldComponent);
75
76 oldComponent._dirty = true;
77 _dirty = false;
78
79 oldComponent._renderInternal(host, insertBefore);
80 return true; // Must retain old component
81 }
82
83 _rendered = oldComponent._rendered;
84 _renderInternal(host, insertBefore);
85 return false;
86 }
87
88 void _renderInternal(sky.Node host, sky.Node insertBefore) {
89 if (!_dirty) {
90 assert(_rendered != null);
91 return;
92 }
93
94 var oldRendered = _rendered;
95 int lastOrder = _currentOrder;
96 _currentOrder = _order;
97 _currentlyRendering = this;
98 _rendered = render();
99 _currentlyRendering = null;
100 _currentOrder = lastOrder;
101
102 _dirty = false;
103
104 // TODO(rafaelw): This prevents components from returning different node
105 // types as their root node at different times. Consider relaxing.
106 assert(oldRendered == null ||
107 _rendered.runtimeType == oldRendered.runtimeType);
108
109 if (_rendered._sync(oldRendered, host, insertBefore)) {
110 _rendered = oldRendered; // retain stateful component
111 }
112 _root = _rendered._root;
113 assert(_rendered._root is sky.Node);
114 }
115
116 void _renderIfDirty() {
117 assert(_rendered != null);
118 assert(!_removed);
119
120 var rendered = _rendered;
121 while (rendered is Component) {
122 rendered = rendered._rendered;
123 }
124 sky.Node root = rendered._root;
125
126 _renderInternal(root.parentNode, root.nextSibling);
127 }
128
129 void setState(Function fn()) {
130 assert(_rendered != null); // cannot setState before mounting.
131 _stateful = true;
132 fn();
133 if (_currentlyRendering != this) {
134 _dirty = true;
135 _scheduleComponentForRender(this);
136 }
137 }
138
139 Node render();
140 }
141
142 abstract class App extends Component {
143 sky.Node _host = null;
144 App()
145 : super(stateful: true) {
146
147 _host = sky.document.createElement('div');
148 sky.document.appendChild(_host);
149
150 new Future.microtask(() {
151 Stopwatch sw = new Stopwatch()..start();
152 _sync(null, _host, null);
153 assert(_root is sky.Node);
154 sw.stop();
155 print("Initial render: ${sw.elapsedMicroseconds} microseconds");
156 });
157 }
158 }
OLDNEW
« no previous file with comments | « sky/examples/fn/README.md ('k') | sky/examples/fn/lib/fakesky.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698