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 'app.dart'; | 7 import 'app.dart'; |
8 import 'dart:async'; | 8 import 'dart:async'; |
9 import 'dart:collection'; | 9 import 'dart:collection'; |
10 import 'dart:mirrors'; | 10 import 'dart:mirrors'; |
11 import 'dart:sky' as sky; | 11 import 'dart:sky' as sky; |
12 import 'package:vector_math/vector_math.dart'; | 12 import 'package:vector_math/vector_math.dart'; |
13 import 'reflect.dart' as reflect; | |
14 import 'rendering/block.dart'; | 13 import 'rendering/block.dart'; |
15 import 'rendering/box.dart'; | 14 import 'rendering/box.dart'; |
16 import 'rendering/flex.dart'; | 15 import 'rendering/flex.dart'; |
17 import 'rendering/object.dart'; | 16 import 'rendering/object.dart'; |
18 import 'rendering/paragraph.dart'; | 17 import 'rendering/paragraph.dart'; |
19 import 'rendering/stack.dart'; | 18 import 'rendering/stack.dart'; |
20 export 'rendering/object.dart' show Point, Size, Rect, Color, Paint, Path; | 19 export 'rendering/object.dart' show Point, Size, Rect, Color, Paint, Path; |
21 export 'rendering/box.dart' show BoxConstraints, BoxDecoration, Border, BorderSi
de, EdgeDims; | 20 export 'rendering/box.dart' show BoxConstraints, BoxDecoration, Border, BorderSi
de, EdgeDims; |
22 export 'rendering/flex.dart' show FlexDirection; | 21 export 'rendering/flex.dart' show FlexDirection; |
23 | 22 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 _notifyingMountStatus = false; | 81 _notifyingMountStatus = false; |
83 } | 82 } |
84 } | 83 } |
85 void _didMount() { } | 84 void _didMount() { } |
86 void _didUnmount() { } | 85 void _didUnmount() { } |
87 | 86 |
88 RenderObject root; | 87 RenderObject root; |
89 | 88 |
90 // Subclasses which implements Nodes that become stateful may return true | 89 // Subclasses which implements Nodes that become stateful may return true |
91 // if the |old| node has become stateful and should be retained. | 90 // if the |old| node has become stateful and should be retained. |
92 bool _willSync(UINode old) => false; | 91 // This is called immediately before _sync(). |
| 92 // Component._retainStatefulNodeIfPossible() calls syncFields(). |
| 93 bool _retainStatefulNodeIfPossible(UINode old) => false; |
93 | 94 |
94 bool get interchangeable => false; // if true, then keys can be duplicated | 95 bool get interchangeable => false; // if true, then keys can be duplicated |
95 | 96 |
96 void _sync(UINode old, dynamic slot); | 97 void _sync(UINode old, dynamic slot); |
97 // 'slot' is the identifier that the parent RenderObjectWrapper uses to know | 98 // 'slot' is the identifier that the parent RenderObjectWrapper uses to know |
98 // where to put this descendant | 99 // where to put this descendant |
99 | 100 |
100 void remove() { | 101 void remove() { |
101 root = null; | 102 root = null; |
102 setParent(null); | 103 setParent(null); |
(...skipping 21 matching lines...) Expand all Loading... |
124 } | 125 } |
125 | 126 |
126 if (node == null) { | 127 if (node == null) { |
127 // the child in this slot has gone away | 128 // the child in this slot has gone away |
128 assert(oldNode.mounted); | 129 assert(oldNode.mounted); |
129 removeChild(oldNode); | 130 removeChild(oldNode); |
130 assert(!oldNode.mounted); | 131 assert(!oldNode.mounted); |
131 return null; | 132 return null; |
132 } | 133 } |
133 | 134 |
134 if (oldNode != null && node._key == oldNode._key && node._willSync(oldNode))
{ | 135 if (oldNode != null && node._key == oldNode._key && node._retainStatefulNode
IfPossible(oldNode)) { |
135 assert(oldNode.mounted); | 136 assert(oldNode.mounted); |
136 assert(!node.mounted); | 137 assert(!node.mounted); |
137 oldNode._sync(node, slot); | 138 oldNode._sync(node, slot); |
138 assert(oldNode.root is RenderObject); | 139 assert(oldNode.root is RenderObject); |
139 return oldNode; | 140 return oldNode; |
140 } | 141 } |
141 | 142 |
142 if (oldNode != null && node._key != oldNode._key) { | 143 if (oldNode != null && node._key != oldNode._key) { |
143 assert(oldNode.mounted); | 144 assert(oldNode.mounted); |
144 removeChild(oldNode); | 145 removeChild(oldNode); |
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 } | 923 } |
923 | 924 |
924 void remove() { | 925 void remove() { |
925 assert(_built != null); | 926 assert(_built != null); |
926 assert(root != null); | 927 assert(root != null); |
927 removeChild(_built); | 928 removeChild(_built); |
928 _built = null; | 929 _built = null; |
929 super.remove(); | 930 super.remove(); |
930 } | 931 } |
931 | 932 |
932 bool _willSync(UINode old) { | 933 bool _retainStatefulNodeIfPossible(UINode old) { |
933 assert(!_disqualifiedFromEverAppearingAgain); | 934 assert(!_disqualifiedFromEverAppearingAgain); |
934 | 935 |
935 Component oldComponent = old as Component; | 936 Component oldComponent = old as Component; |
936 if (oldComponent == null || !oldComponent._stateful) | 937 if (oldComponent == null || !oldComponent._stateful) |
937 return false; | 938 return false; |
938 | 939 |
939 // Make |this| the "old" Component | 940 // Make |this|, the newly-created object, into the "old" Component, and kill
it |
940 _stateful = false; | 941 _stateful = false; |
941 _built = oldComponent._built; | 942 _built = oldComponent._built; |
942 assert(_built != null); | 943 assert(_built != null); |
943 _disqualifiedFromEverAppearingAgain = true; | 944 _disqualifiedFromEverAppearingAgain = true; |
944 | 945 |
945 // Make |oldComponent| the "new" component | 946 // Make |oldComponent| the "new" component |
946 reflect.copyPublicFields(this, oldComponent); | |
947 oldComponent._built = null; | 947 oldComponent._built = null; |
948 oldComponent._dirty = true; | 948 oldComponent._dirty = true; |
| 949 oldComponent.syncFields(this); |
949 return true; | 950 return true; |
950 } | 951 } |
951 | 952 |
| 953 // This is called by _retainStatefulNodeIfPossible(), during syncChild(), just
before _sync() is called. |
| 954 void syncFields(Component source) { |
| 955 assert(key == source.key); |
| 956 assert(_stateful); |
| 957 } |
| 958 |
952 final int _order; | 959 final int _order; |
953 static int _currentOrder = 0; | 960 static int _currentOrder = 0; |
954 | 961 |
955 /* There are three cases here: | 962 /* There are three cases here: |
956 * 1) Building for the first time: | 963 * 1) Building for the first time: |
957 * assert(_built == null && old == null) | 964 * assert(_built == null && old == null) |
958 * 2) Re-building (because a dirty flag got set): | 965 * 2) Re-building (because a dirty flag got set): |
959 * assert(_built != null && old == null) | 966 * assert(_built != null && old == null) |
960 * 3) Syncing against an old version | 967 * 3) Syncing against an old version |
961 * assert(_built == null && old != null) | 968 * assert(_built == null && old != null) |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1113 } | 1120 } |
1114 | 1121 |
1115 } | 1122 } |
1116 | 1123 |
1117 class Text extends Component { | 1124 class Text extends Component { |
1118 Text(this.data) : super(key: '*text*'); | 1125 Text(this.data) : super(key: '*text*'); |
1119 final String data; | 1126 final String data; |
1120 bool get interchangeable => true; | 1127 bool get interchangeable => true; |
1121 UINode build() => new Paragraph(text: data); | 1128 UINode build() => new Paragraph(text: data); |
1122 } | 1129 } |
OLD | NEW |