Make UINode's key a String

We need the key to be a String even though we claimed we could support any
Object. Also, clean up some style nits including shortening the |root| getters
on OneChildRenderNodeWrappers.

Fixes https://github.com/domokit/sky_sdk/issues/26.

TBR=ianh@google.com

Review URL: https://codereview.chromium.org/1173293005.
This commit is contained in:
Adam Barth 2015-06-15 21:39:09 -07:00
parent 71c7be5ebc
commit 79455270b2
28 changed files with 121 additions and 134 deletions

View File

@ -12,7 +12,7 @@ import 'package:sky/widgets/basic.dart';
class StockArrow extends Component {
StockArrow({ Object key, this.percentChange }) : super(key: key);
StockArrow({ String key, this.percentChange }) : super(key: key);
final double percentChange;

View File

@ -11,7 +11,7 @@ import 'stock_row.dart';
class Stocklist extends FixedHeightScrollable {
Stocklist({
Object key,
String key,
this.stocks,
this.query
}) : super(itemHeight: StockRow.kHeight, key: key);

View File

@ -10,7 +10,7 @@ import 'package:sky/framework/theme/view_configuration.dart';
class StockMenu extends Component {
StockMenu({
Object key,
String key,
this.controller,
this.autorefresh: false,
this.onAutorefreshChanged

View File

@ -24,7 +24,7 @@ void addFlexChildSolidColor(RenderFlex parent, sky.Color backgroundColor, { int
// Solid colour, Widget version
class Rectangle extends Component {
Rectangle(this.color, { Object key }) : super(key: key);
Rectangle(this.color, { String key }) : super(key: key);
final Color color;
UINode build() {
return new Flexible(

View File

@ -9,7 +9,7 @@ import 'editable_string.dart';
class EditableText extends Component {
EditableText({Object key, this.value, this.focused})
EditableText({String key, this.value, this.focused})
: super(key: key, stateful: true);
// static final Style _cursorStyle = new Style('''

View File

@ -13,7 +13,7 @@ typedef void ValueChanged(value);
class Input extends Component {
Input({Object key,
Input({String key,
this.placeholder,
this.onChanged,
this.focused})

View File

@ -18,7 +18,7 @@ class _AnimationEntry {
abstract class AnimatedComponent extends Component {
AnimatedComponent({ Object key }) : super(key: key, stateful: true);
AnimatedComponent({ String key }) : super(key: key, stateful: true);
void syncFields(AnimatedComponent source) { }

View File

@ -1,3 +1,6 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:vector_math/vector_math.dart';
@ -18,10 +21,10 @@ export 'ui_node.dart' show UINode, Component, App, EventListenerNode, ParentData
// PAINTING NODES
class Opacity extends OneChildRenderObjectWrapper {
Opacity({ this.opacity, UINode child, Object key })
: super(child: child, key: key);
Opacity({ String key, this.opacity, UINode child })
: super(key: key, child: child);
RenderOpacity get root { RenderOpacity result = super.root; return result; }
RenderOpacity get root => super.root;
final double opacity;
RenderOpacity createNode() => new RenderOpacity(opacity: opacity);
@ -34,10 +37,10 @@ class Opacity extends OneChildRenderObjectWrapper {
class DecoratedBox extends OneChildRenderObjectWrapper {
DecoratedBox({ this.decoration, UINode child, Object key })
: super(child: child, key: key);
DecoratedBox({ String key, this.decoration, UINode child })
: super(key: key, child: child);
RenderDecoratedBox get root { RenderDecoratedBox result = super.root; return result; }
RenderDecoratedBox get root => super.root;
final BoxDecoration decoration;
RenderDecoratedBox createNode() => new RenderDecoratedBox(decoration: decoration);
@ -51,10 +54,10 @@ class DecoratedBox extends OneChildRenderObjectWrapper {
class CustomPaint extends OneChildRenderObjectWrapper {
CustomPaint({ this.callback, this.token, UINode child, Object key })
: super(child: child, key: key);
CustomPaint({ String key, this.callback, this.token, UINode child })
: super(key: key, child: child);
RenderCustomPaint get root { RenderCustomPaint result = super.root; return result; }
RenderCustomPaint get root => super.root;
final CustomPaintCallback callback;
final dynamic token; // set this to be repainted automatically when the token changes
@ -75,20 +78,18 @@ class CustomPaint extends OneChildRenderObjectWrapper {
}
class ClipRect extends OneChildRenderObjectWrapper {
ClipRect({ String key, UINode child })
: super(key: key, child: child);
ClipRect({ UINode child, Object key })
: super(child: child, key: key);
RenderClipRect get root { RenderClipRect result = super.root; return result; }
RenderClipRect get root => super.root;
RenderClipRect createNode() => new RenderClipRect();
}
class ClipOval extends OneChildRenderObjectWrapper {
ClipOval({ String key, UINode child })
: super(key: key, child: child);
ClipOval({ UINode child, Object key })
: super(child: child, key: key);
RenderClipOval get root { RenderClipOval result = super.root; return result; }
RenderClipOval get root => super.root;
RenderClipOval createNode() => new RenderClipOval();
}
@ -97,10 +98,10 @@ class ClipOval extends OneChildRenderObjectWrapper {
class Transform extends OneChildRenderObjectWrapper {
Transform({ this.transform, UINode child, Object key })
: super(child: child, key: key);
Transform({ String key, this.transform, UINode child })
: super(key: key, child: child);
RenderTransform get root { RenderTransform result = super.root; return result; }
RenderTransform get root => super.root;
final Matrix4 transform;
RenderTransform createNode() => new RenderTransform(transform: transform);
@ -114,10 +115,10 @@ class Transform extends OneChildRenderObjectWrapper {
class Padding extends OneChildRenderObjectWrapper {
Padding({ this.padding, UINode child, Object key })
: super(child: child, key: key);
Padding({ String key, this.padding, UINode child })
: super(key: key, child: child);
RenderPadding get root { RenderPadding result = super.root; return result; }
RenderPadding get root => super.root;
final EdgeDims padding;
RenderPadding createNode() => new RenderPadding(padding: padding);
@ -130,26 +131,23 @@ class Padding extends OneChildRenderObjectWrapper {
}
class Center extends OneChildRenderObjectWrapper {
Center({ String key, UINode child })
: super(key: key, child: child);
Center({ UINode child, Object key })
: super(child: child, key: key);
RenderPositionedBox get root { RenderPositionedBox result = super.root; return result; }
RenderPositionedBox get root => super.root;
RenderPositionedBox createNode() => new RenderPositionedBox();
}
class SizedBox extends OneChildRenderObjectWrapper {
SizedBox({
String key,
this.width,
this.height,
UINode child,
Object key
}) : super(child: child, key: key);
UINode child
}) : super(key: key, child: child);
RenderConstrainedBox get root { RenderConstrainedBox result = super.root; return result; }
RenderConstrainedBox get root => super.root;
final double width;
final double height;
@ -174,10 +172,11 @@ class SizedBox extends OneChildRenderObjectWrapper {
class ConstrainedBox extends OneChildRenderObjectWrapper {
ConstrainedBox({ this.constraints, UINode child, Object key })
: super(child: child, key: key);
ConstrainedBox({ String key, this.constraints, UINode child })
: super(key: key, child: child);
RenderConstrainedBox get root => super.root;
RenderConstrainedBox get root { RenderConstrainedBox result = super.root; return result; }
final BoxConstraints constraints;
RenderConstrainedBox createNode() => new RenderConstrainedBox(additionalConstraints: constraints);
@ -190,21 +189,19 @@ class ConstrainedBox extends OneChildRenderObjectWrapper {
}
class ShrinkWrapWidth extends OneChildRenderObjectWrapper {
ShrinkWrapWidth({ String key, UINode child })
: super(key: key, child: child);
ShrinkWrapWidth({ UINode child, Object key }) : super(child: child, key: key);
RenderShrinkWrapWidth get root { RenderShrinkWrapWidth result = super.root; return result; }
RenderShrinkWrapWidth get root => super.root;
RenderShrinkWrapWidth createNode() => new RenderShrinkWrapWidth();
}
class SizeObserver extends OneChildRenderObjectWrapper {
SizeObserver({ this.callback, UINode child, Object key })
: super(child: child, key: key);
SizeObserver({ String key, this.callback, UINode child })
: super(key: key, child: child);
RenderSizeObserver get root { RenderSizeObserver result = super.root; return result; }
RenderSizeObserver get root => super.root;
final SizeChangedCallback callback;
RenderSizeObserver createNode() => new RenderSizeObserver(callback: callback);
@ -227,7 +224,7 @@ class SizeObserver extends OneChildRenderObjectWrapper {
class Container extends Component {
Container({
Object key,
String key,
this.child,
this.constraints,
this.decoration,
@ -287,48 +284,47 @@ class Container extends Component {
// LAYOUT NODES
class Block extends MultiChildRenderObjectWrapper {
Block(List<UINode> children, { Object key })
Block(List<UINode> children, { String key })
: super(key: key, children: children);
RenderBlock get root { RenderBlock result = super.root; return result; }
RenderBlock get root => super.root;
RenderBlock createNode() => new RenderBlock();
}
class Stack extends MultiChildRenderObjectWrapper {
Stack(List<UINode> children, { Object key })
Stack(List<UINode> children, { String key })
: super(key: key, children: children);
RenderStack get root { RenderStack result = super.root; return result; }
RenderStack get root => super.root;
RenderStack createNode() => new RenderStack();
}
class Positioned extends ParentDataNode {
Positioned({
String key,
UINode child,
double top,
double right,
double bottom,
double left
}) : super(content, new StackParentData()..top = top
..right = right
..bottom = bottom
..left = left);
}) : super(content,
new StackParentData()..top = top
..right = right
..bottom = bottom
..left = left,
key: key);
}
class Flex extends MultiChildRenderObjectWrapper {
Flex(List<UINode> children, {
Object key,
String key,
this.direction: FlexDirection.horizontal,
this.justifyContent: FlexJustifyContent.flexStart,
this.alignItems: FlexAlignItems.center
}) : super(key: key, children: children);
RenderFlex get root { RenderFlex result = super.root; return result; }
RenderFlex get root => super.root;
RenderFlex createNode() => new RenderFlex(direction: this.direction);
final FlexDirection direction;
@ -345,15 +341,15 @@ class Flex extends MultiChildRenderObjectWrapper {
}
class Flexible extends ParentDataNode {
Flexible({ UINode child, int flex: 1, Object key })
Flexible({ String key, UINode child, int flex: 1 })
: super(child, new FlexBoxParentData()..flex = flex, key: key);
}
class Paragraph extends RenderObjectWrapper {
Paragraph({ Object key, this.text, this.style }) : super(key: key);
Paragraph({ String key, this.text, this.style }) : super(key: key);
RenderParagraph get root { RenderParagraph result = super.root; return result; }
RenderParagraph get root => super.root;
RenderParagraph createNode() => new RenderParagraph(text: text, style: style);
final String text;
@ -383,12 +379,12 @@ class Text extends Component {
class Image extends RenderObjectWrapper {
Image({
Object key,
String key,
this.src,
this.size
}) : super(key: key);
RenderImage get root { RenderImage result = super.root; return result; }
RenderImage get root => super.root;
RenderImage createNode() => new RenderImage(this.src, this.size);
final String src;

View File

@ -6,7 +6,7 @@ import 'basic.dart';
abstract class ButtonBase extends Component {
ButtonBase({ Object key, this.highlight: false }) : super(key: key);
ButtonBase({ String key, this.highlight: false }) : super(key: key);
bool highlight;

View File

@ -20,7 +20,7 @@ const double _kEdgeRadius = 1.0;
class Checkbox extends Toggleable {
Checkbox({
Object key,
String key,
bool value,
ValueChanged onChanged
}) : super(key: key, value: value, onChanged: onChanged);

View File

@ -109,7 +109,7 @@ class DrawerController {
class Drawer extends AnimatedComponent {
Drawer({
Object key,
String key,
this.controller,
this.children,
this.level: 0

View File

@ -8,7 +8,7 @@ import 'basic.dart';
class DrawerHeader extends Component {
DrawerHeader({ Object key, this.children }) : super(key: key);
DrawerHeader({ String key, this.children }) : super(key: key);
final List<UINode> children;

View File

@ -12,7 +12,7 @@ import 'scrollable.dart';
abstract class FixedHeightScrollable extends Scrollable {
FixedHeightScrollable({ this.itemHeight, Color backgroundColor, Object key })
FixedHeightScrollable({ String key, this.itemHeight, Color backgroundColor })
: super(key: key, backgroundColor: backgroundColor) {
assert(itemHeight != null);
}

View File

@ -15,8 +15,7 @@ const double _kSize = 56.0;
class FloatingActionButton extends ButtonBase {
FloatingActionButton({ Object key, this.child })
: super(key: key);
FloatingActionButton({ String key, this.child }) : super(key: key);
final UINode child;

View File

@ -100,10 +100,9 @@ class RenderInkWell extends RenderProxyBox {
}
class InkWell extends OneChildRenderObjectWrapper {
InkWell({ UINode child, Object key })
: super(child: child, key: key);
RenderInkWell get root { RenderInkWell result = super.root; return result; }
InkWell({ String key, UINode child })
: super(key: key, child: child);
RenderInkWell get root => super.root;
RenderInkWell createNode() => new RenderInkWell();
}

View File

@ -11,7 +11,7 @@ import 'basic.dart';
class Material extends Component {
Material({
Object key,
String key,
this.child,
this.edge: MaterialEdge.card,
this.level: 0,

View File

@ -5,7 +5,7 @@
import 'basic.dart';
class MenuDivider extends Component {
MenuDivider({ Object key }) : super(key: key);
MenuDivider({ String key }) : super(key: key);
UINode build() {
return new Container(

View File

@ -23,7 +23,8 @@ const BoxDecoration _kHighlightBoring = const BoxDecoration(
);
class MenuItem extends ButtonBase {
MenuItem({ Object key, this.icon, this.children, this.onGestureTap }) : super(key: key);
MenuItem({ String key, this.icon, this.children, this.onGestureTap })
: super(key: key);
String icon;
List<UINode> children;

View File

@ -7,7 +7,7 @@ import 'ui_node.dart';
class ModalOverlay extends Component {
ModalOverlay({ Object key, this.children, this.onDismiss }) : super(key: key);
ModalOverlay({ String key, this.children, this.onDismiss }) : super(key: key);
// static final Style _style = new Style('''
// position: absolute;

View File

@ -54,7 +54,7 @@ class PopupMenuController {
class PopupMenu extends AnimatedComponent {
PopupMenu({ Object key, this.controller, this.items, this.level })
PopupMenu({ String key, this.controller, this.items, this.level })
: super(key: key) {
_painter = new BoxPainter(new BoxDecoration(
backgroundColor: Grey[50],
@ -94,7 +94,10 @@ class PopupMenu extends AnimatedComponent {
int i = 0;
List<UINode> children = new List.from(items.map((List<UINode> item) {
double opacity = _opacityFor(i);
return new PopupMenuItem(key: i++, children: item, opacity: opacity);
// TODO(abarth): Using |i| for the key here seems wrong.
return new PopupMenuItem(key: (i++).toString(),
children: item
opacity: opacity);
}));
return new Opacity(

View File

@ -6,7 +6,7 @@ import 'basic.dart';
import 'ink_well.dart';
class PopupMenuItem extends Component {
PopupMenuItem({ Object key, this.children, this.opacity}) : super(key: key);
PopupMenuItem({ String key, this.children, this.opacity}) : super(key: key);
final List<UINode> children;
final double opacity;

View File

@ -14,7 +14,7 @@ typedef void ValueChanged(value);
class Radio extends ButtonBase {
Radio({
Object key,
String key,
this.value,
this.groupValue,
this.onChanged

View File

@ -14,7 +14,7 @@ enum RaisedButtonTheme { light, dark }
class RaisedButton extends ButtonBase {
RaisedButton({
Object key,
String key,
this.child,
this.enabled: true,
this.onPressed,

View File

@ -159,7 +159,7 @@ class Scaffold extends RenderObjectWrapper {
// ${typography.black.body1};''');
Scaffold({
Object key,
String key,
UINode toolbar,
UINode body,
UINode statusBar,
@ -178,7 +178,7 @@ class Scaffold extends RenderObjectWrapper {
UINode _drawer;
UINode _floatingActionButton;
RenderScaffold get root { RenderScaffold result = super.root; return result; }
RenderScaffold get root => super.root;
RenderScaffold createNode() => new RenderScaffold();
void insert(RenderObjectWrapper child, ScaffoldSlots slot) {

View File

@ -26,7 +26,8 @@ abstract class ScrollClient {
abstract class Scrollable extends Component {
Scrollable({ Object key, Color this.backgroundColor }) : super(key: key, stateful: true);
Scrollable({ String key, Color this.backgroundColor })
: super(key: key, stateful: true);
Color backgroundColor;

View File

@ -29,7 +29,7 @@ class Switch extends Toggleable {
// TODO(jackson): Hit-test the switch so that it can respond to both taps and swipe gestures
Switch({
Object key,
String key,
bool value,
ValueChanged onChanged
}) : super(key: key, value: value, onChanged: onChanged);

View File

@ -16,7 +16,7 @@ const double _kCheckDuration = 200.0;
abstract class Toggleable extends AnimatedComponent {
Toggleable({
Object key,
String key,
this.value,
this.onChanged
}) : super(key: key) {

View File

@ -15,18 +15,13 @@ export '../rendering/box.dart' show BoxConstraints, BoxDecoration, Border, Borde
export '../rendering/flex.dart' show FlexDirection;
export '../rendering/object.dart' show Point, Size, Rect, Color, Paint, Path;
// final sky.Tracing _tracing = sky.window.tracing;
final bool _shouldLogRenderDuration = false;
/*
* All Effen nodes derive from UINode. All nodes have a _parent, a _key and
* can be sync'd.
*/
// All Effen nodes derive from UINode. All nodes have a _parent, a _key and
// can be sync'd.
abstract class UINode {
UINode({ Object key }) {
UINode({ String key }) {
_key = key == null ? "$runtimeType" : "$runtimeType-$key";
assert(this is AbstractUINodeRoot || _inRenderDirtyComponents); // you should not build the UI tree ahead of time, build it only during build()
}
@ -157,7 +152,8 @@ abstract class UINode {
// stylistic information, etc.
abstract class TagNode extends UINode {
TagNode(UINode content, { Object key }) : this.content = content, super(key: key);
TagNode(UINode content, { String key })
: this.content = content, super(key: key);
UINode content;
@ -178,7 +174,8 @@ abstract class TagNode extends UINode {
}
class ParentDataNode extends TagNode {
ParentDataNode(UINode content, this.parentData, { Object key }): super(content, key: key);
ParentDataNode(UINode content, this.parentData, { String key })
: super(content, key: key);
final ParentData parentData;
}
@ -275,14 +272,11 @@ class EventListenerNode extends TagNode {
abstract class Component extends UINode {
Component({ Object key, bool stateful })
Component({ String key, bool stateful })
: _stateful = stateful != null ? stateful : false,
_order = _currentOrder + 1,
super(key: key);
Component.fromArgs(Object key, bool stateful)
: this(key: key, stateful: stateful);
static Component _currentlyBuilding;
bool get _isBuilding => _currentlyBuilding == this;
@ -341,14 +335,13 @@ abstract class Component extends UINode {
final int _order;
static int _currentOrder = 0;
/* There are three cases here:
* 1) Building for the first time:
* assert(_built == null && old == null)
* 2) Re-building (because a dirty flag got set):
* assert(_built != null && old == null)
* 3) Syncing against an old version
* assert(_built == null && old != null)
*/
// There are three cases here:
// 1) Building for the first time:
// assert(_built == null && old == null)
// 2) Re-building (because a dirty flag got set):
// assert(_built != null && old == null)
// 3) Syncing against an old version
// assert(_built == null && old != null)
void _sync(UINode old, dynamic slot) {
assert(_built == null || old == null);
assert(!_disqualifiedFromEverAppearingAgain);
@ -456,18 +449,14 @@ void _scheduleComponentForRender(Component c) {
}
/*
* RenderObjectWrappers correspond to a desired state of a RenderObject.
* They are fully immutable, with one exception: A UINode which is a
* Component which lives within an MultiChildRenderObjectWrapper's
* children list, may be replaced with the "old" instance if it has
* become stateful.
*/
// RenderObjectWrappers correspond to a desired state of a RenderObject.
// They are fully immutable, with one exception: A UINode which is a
// Component which lives within an MultiChildRenderObjectWrapper's
// children list, may be replaced with the "old" instance if it has
// become stateful.
abstract class RenderObjectWrapper extends UINode {
RenderObjectWrapper({
Object key
}) : super(key: key);
RenderObjectWrapper({ String key }) : super(key: key);
RenderObject createNode();
@ -524,7 +513,8 @@ abstract class RenderObjectWrapper extends UINode {
abstract class OneChildRenderObjectWrapper extends RenderObjectWrapper {
OneChildRenderObjectWrapper({ UINode child, Object key }) : _child = child, super(key: key);
OneChildRenderObjectWrapper({ UINode child, String key })
: _child = child, super(key: key);
UINode _child;
UINode get child => _child;
@ -564,11 +554,9 @@ abstract class MultiChildRenderObjectWrapper extends RenderObjectWrapper {
// In MultiChildRenderObjectWrapper subclasses, slots are RenderObject nodes
// to use as the "insert before" sibling in ContainerRenderObjectMixin.add() calls
MultiChildRenderObjectWrapper({
Object key,
List<UINode> children
}) : this.children = children == null ? const [] : children,
super(key: key) {
MultiChildRenderObjectWrapper({ String key, List<UINode> children })
: this.children = children == null ? const [] : children,
super(key: key) {
assert(!_debugHasDuplicateIds());
}