Commit 243a49f7 authored by Adam Barth's avatar Adam Barth

Merge pull request #2992 from abarth/reactive_build

Reactivating a StatefulElement should imply a build
parents 66316433 b841e868
...@@ -626,11 +626,11 @@ class _InactiveElements { ...@@ -626,11 +626,11 @@ class _InactiveElements {
}); });
} }
void _deactivate(Element element) { void _deactivateRecursively(Element element) {
assert(element._debugLifecycleState == _ElementLifecycle.active); assert(element._debugLifecycleState == _ElementLifecycle.active);
element.deactivate(); element.deactivate();
assert(element._debugLifecycleState == _ElementLifecycle.inactive); assert(element._debugLifecycleState == _ElementLifecycle.inactive);
element.visitChildren(_deactivate); element.visitChildren(_deactivateRecursively);
assert(() { element.debugDeactivated(); return true; }); assert(() { element.debugDeactivated(); return true; });
} }
...@@ -639,7 +639,7 @@ class _InactiveElements { ...@@ -639,7 +639,7 @@ class _InactiveElements {
assert(!_elements.contains(element)); assert(!_elements.contains(element));
assert(element._parent == null); assert(element._parent == null);
if (element._active) if (element._active)
_deactivate(element); _deactivateRecursively(element);
_elements.add(element); _elements.add(element);
} }
...@@ -840,12 +840,12 @@ abstract class Element implements BuildContext { ...@@ -840,12 +840,12 @@ abstract class Element implements BuildContext {
_slot = newSlot; _slot = newSlot;
} }
void _updateDepth() { void _updateDepth(int parentDepth) {
int expectedDepth = _parent.depth + 1; int expectedDepth = parentDepth + 1;
if (_depth < expectedDepth) { if (_depth < expectedDepth) {
_depth = expectedDepth; _depth = expectedDepth;
visitChildren((Element child) { visitChildren((Element child) {
child._updateDepth(); child._updateDepth(expectedDepth);
}); });
} }
} }
...@@ -885,7 +885,7 @@ abstract class Element implements BuildContext { ...@@ -885,7 +885,7 @@ abstract class Element implements BuildContext {
if (newChild != null) { if (newChild != null) {
assert(newChild._parent == null); assert(newChild._parent == null);
assert(() { _debugCheckForCycles(newChild); return true; }); assert(() { _debugCheckForCycles(newChild); return true; });
newChild.activate(this, newSlot); newChild._activateWithParent(this, newSlot);
Element updatedChild = updateChild(newChild, newWidget, newSlot); Element updatedChild = updateChild(newChild, newWidget, newSlot);
assert(newChild == updatedChild); assert(newChild == updatedChild);
return updatedChild; return updatedChild;
...@@ -917,16 +917,23 @@ abstract class Element implements BuildContext { ...@@ -917,16 +917,23 @@ abstract class Element implements BuildContext {
_inactiveElements.add(child); // this eventually calls child.deactivate() _inactiveElements.add(child); // this eventually calls child.deactivate()
} }
void activate(Element parent, dynamic newSlot) { void _activateWithParent(Element parent, dynamic newSlot) {
assert(_debugLifecycleState == _ElementLifecycle.inactive); assert(_debugLifecycleState == _ElementLifecycle.inactive);
_parent = parent; _parent = parent;
_reactivate(); _updateDepth(_parent.depth);
_updateDepth(); _activateRecursively(this);
attachRenderObject(newSlot); attachRenderObject(newSlot);
assert(_debugLifecycleState == _ElementLifecycle.active); assert(_debugLifecycleState == _ElementLifecycle.active);
} }
void _reactivate() { static void _activateRecursively(Element element) {
assert(element._debugLifecycleState == _ElementLifecycle.inactive);
element.activate();
assert(element._debugLifecycleState == _ElementLifecycle.active);
element.visitChildren(_activateRecursively);
}
void activate() {
assert(_debugLifecycleState == _ElementLifecycle.inactive); assert(_debugLifecycleState == _ElementLifecycle.inactive);
assert(widget != null); assert(widget != null);
assert(depth != null); assert(depth != null);
...@@ -934,7 +941,6 @@ abstract class Element implements BuildContext { ...@@ -934,7 +941,6 @@ abstract class Element implements BuildContext {
_active = true; _active = true;
_updateInheritance(); _updateInheritance();
assert(() { _debugLifecycleState = _ElementLifecycle.active; return true; }); assert(() { _debugLifecycleState = _ElementLifecycle.active; return true; });
visitChildren((Element child) => child._reactivate());
} }
void deactivate() { void deactivate() {
...@@ -1430,6 +1436,12 @@ class StatefulElement extends ComponentElement { ...@@ -1430,6 +1436,12 @@ class StatefulElement extends ComponentElement {
rebuild(); rebuild();
} }
@override
void activate() {
super.activate();
markNeedsBuild();
}
@override @override
void deactivate() { void deactivate() {
_state.deactivate(); _state.deactivate();
......
...@@ -26,6 +26,29 @@ class StateMarkerState extends State<StateMarker> { ...@@ -26,6 +26,29 @@ class StateMarkerState extends State<StateMarker> {
} }
} }
class DeactivateLogger extends StatefulWidget {
DeactivateLogger({ Key key, this.log }) : super(key: key);
final List<String> log;
@override
DeactivateLoggerState createState() => new DeactivateLoggerState();
}
class DeactivateLoggerState extends State<DeactivateLogger> {
@override
void deactivate() {
config.log.add('deactivate');
super.deactivate();
}
@override
Widget build(BuildContext context) {
config.log.add('build');
return new Container();
}
}
void main() { void main() {
test('can reparent state', () { test('can reparent state', () {
testWidgets((WidgetTester tester) { testWidgets((WidgetTester tester) {
...@@ -293,4 +316,28 @@ void main() { ...@@ -293,4 +316,28 @@ void main() {
expect(keyState.marker, equals("marked")); expect(keyState.marker, equals("marked"));
}); });
}); });
test('Deactivate implies build', () {
testWidgets((WidgetTester tester) {
GlobalKey key = new GlobalKey();
List<String> log = <String>[];
DeactivateLogger logger = new DeactivateLogger(key: key, log: log);
tester.pumpWidget(
new Container(key: new UniqueKey(), child: logger)
);
expect(log, equals(['build']));
tester.pumpWidget(
new Container(key: new UniqueKey(), child: logger)
);
expect(log, equals(['build', 'deactivate', 'build']));
log.clear();
tester.pump();
expect(log, isEmpty);
});
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment