Commit 03eaf1d1 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Fix hot reload (#5799)

I forgot that it was possible for the root view to get marked dirty
without getting a new widget. This fixes that case to work.
parent 59739abe
......@@ -8,6 +8,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:meta/meta.dart';
import 'package:mojo/core.dart' as core;
import 'package:sky_services/semantics/semantics.mojom.dart' as mojom;
......@@ -195,6 +196,7 @@ abstract class RendererBinding extends BindingBase implements SchedulerBinding,
/// list.
//
// When editing the above, also update widgets/binding.dart's copy.
@protected
void beginFrame() {
assert(renderView != null);
pipelineOwner.flushLayout();
......@@ -208,7 +210,7 @@ abstract class RendererBinding extends BindingBase implements SchedulerBinding,
void reassembleApplication() {
super.reassembleApplication();
pipelineOwner.reassemble();
beginFrame();
handleBeginFrame(null);
}
@override
......
......@@ -491,11 +491,14 @@ class RenderObjectToWidgetElement<T extends RenderObject> extends RootRenderObje
@override
void performRebuild() {
assert(_newWidget != null);
final Widget newWidget = _newWidget;
_newWidget = null;
if (_newWidget != null) {
// _newWidget can be null if, for instance, we were rebuilt
// due to a reassemble.
final Widget newWidget = _newWidget;
_newWidget = null;
update(newWidget);
}
super.performRebuild();
update(newWidget);
assert(_newWidget == null);
}
......
......@@ -1537,15 +1537,25 @@ class BuildOwner {
assert(_dirtyElements[index] != null);
assert(_dirtyElements[index]._inDirtyList);
assert(!_dirtyElements[index]._active || _dirtyElements[index]._debugIsInScope(context));
_dirtyElements[index].rebuild();
try {
_dirtyElements[index].rebuild();
} catch (e, stack) {
_debugReportException(
'while rebuilding dirty elements', e, stack,
informationCollector: (StringBuffer information) {
information.writeln('The element being rebuilt at the time was index $index of $dirtyCount:');
information.write(' ${_dirtyElements[index]}');
}
);
}
index += 1;
if (dirtyCount < _dirtyElements.length) {
_dirtyElements.sort(_elementSort);
dirtyCount = _dirtyElements.length;
}
}
} finally {
assert(!_dirtyElements.any((BuildableElement element) => element._active && element.dirty));
} finally {
for (BuildableElement element in _dirtyElements) {
assert(element._inDirtyList);
element._inDirtyList = false;
......@@ -3149,11 +3159,14 @@ class MultiChildRenderObjectElement extends RenderObjectElement {
}
}
void _debugReportException(String context, dynamic exception, StackTrace stack) {
void _debugReportException(String context, dynamic exception, StackTrace stack, {
InformationCollector informationCollector
}) {
FlutterError.reportError(new FlutterErrorDetails(
exception: exception,
stack: stack,
library: 'widgets library',
context: context
context: context,
informationCollector: informationCollector,
));
}
// Copyright 2016 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:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('reassemble does not crash', (WidgetTester tester) async {
await tester.pumpWidget(new MaterialApp(
home: new Text('Hello World')
));
await tester.pump();
tester.binding.reassembleApplication();
await tester.pump();
});
}
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