This reverts commit c75edc268ca336c66a103f1c0d82c4dff140fca0.
This commit is contained in:
parent
c75edc268c
commit
63c49c3d83
@ -455,6 +455,7 @@ class RenderSectorSlice extends RenderSectorWithChildren {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChildMixin<RenderSector> {
|
class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChildMixin<RenderSector> {
|
||||||
|
|
||||||
RenderBoxToRenderSectorAdapter({ double innerRadius = 0.0, RenderSector? child })
|
RenderBoxToRenderSectorAdapter({ double innerRadius = 0.0, RenderSector? child })
|
||||||
: _innerRadius = innerRadius {
|
: _innerRadius = innerRadius {
|
||||||
this.child = child;
|
this.child = child;
|
||||||
@ -566,6 +567,7 @@ class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChil
|
|||||||
result.add(BoxHitTestEntry(this, position));
|
result.add(BoxHitTestEntry(this, position));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class RenderSolidColor extends RenderDecoratedSector {
|
class RenderSolidColor extends RenderDecoratedSector {
|
||||||
|
@ -90,13 +90,6 @@ class SectorAppState extends State<SectorApp> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void recursivelyDisposeChildren(RenderObject parent) {
|
|
||||||
parent.visitChildren((RenderObject child) {
|
|
||||||
recursivelyDisposeChildren(child);
|
|
||||||
child.dispose();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildBody() {
|
Widget buildBody() {
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
@ -114,12 +107,7 @@ class SectorAppState extends State<SectorApp> {
|
|||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(4.0),
|
padding: const EdgeInsets.all(4.0),
|
||||||
margin: const EdgeInsets.only(right: 10.0),
|
margin: const EdgeInsets.only(right: 10.0),
|
||||||
child: WidgetToRenderBoxAdapter(
|
child: WidgetToRenderBoxAdapter(renderBox: sectorAddIcon),
|
||||||
renderBox: sectorAddIcon,
|
|
||||||
onUnmount: () {
|
|
||||||
recursivelyDisposeChildren(sectorAddIcon);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const Text('ADD SECTOR'),
|
const Text('ADD SECTOR'),
|
||||||
],
|
],
|
||||||
@ -134,12 +122,7 @@ class SectorAppState extends State<SectorApp> {
|
|||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(4.0),
|
padding: const EdgeInsets.all(4.0),
|
||||||
margin: const EdgeInsets.only(right: 10.0),
|
margin: const EdgeInsets.only(right: 10.0),
|
||||||
child: WidgetToRenderBoxAdapter(
|
child: WidgetToRenderBoxAdapter(renderBox: sectorRemoveIcon),
|
||||||
renderBox: sectorRemoveIcon,
|
|
||||||
onUnmount: () {
|
|
||||||
recursivelyDisposeChildren(sectorRemoveIcon);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const Text('REMOVE SECTOR'),
|
const Text('REMOVE SECTOR'),
|
||||||
],
|
],
|
||||||
@ -159,9 +142,6 @@ class SectorAppState extends State<SectorApp> {
|
|||||||
child: WidgetToRenderBoxAdapter(
|
child: WidgetToRenderBoxAdapter(
|
||||||
renderBox: sectors,
|
renderBox: sectors,
|
||||||
onBuild: doUpdates,
|
onBuild: doUpdates,
|
||||||
onUnmount: () {
|
|
||||||
recursivelyDisposeChildren(sectors);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -283,15 +283,6 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
|
|||||||
_RenderEditableCustomPaint? _foregroundRenderObject;
|
_RenderEditableCustomPaint? _foregroundRenderObject;
|
||||||
_RenderEditableCustomPaint? _backgroundRenderObject;
|
_RenderEditableCustomPaint? _backgroundRenderObject;
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_foregroundRenderObject?.dispose();
|
|
||||||
_foregroundRenderObject = null;
|
|
||||||
_backgroundRenderObject?.dispose();
|
|
||||||
_backgroundRenderObject = null;
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _updateForegroundPainter(RenderEditablePainter? newPainter) {
|
void _updateForegroundPainter(RenderEditablePainter? newPainter) {
|
||||||
final _CompositeRenderEditablePainter effectivePainter = newPainter == null
|
final _CompositeRenderEditablePainter effectivePainter = newPainter == null
|
||||||
? _builtInForegroundPainters
|
? _builtInForegroundPainters
|
||||||
|
@ -438,13 +438,6 @@ class RenderImage extends RenderBox {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_image?.dispose();
|
|
||||||
_image = null;
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
super.debugFillProperties(properties);
|
super.debugFillProperties(properties);
|
||||||
|
@ -1111,19 +1111,6 @@ class PipelineOwner {
|
|||||||
/// The [RenderBox] subclass introduces the opinion that the layout
|
/// The [RenderBox] subclass introduces the opinion that the layout
|
||||||
/// system uses Cartesian coordinates.
|
/// system uses Cartesian coordinates.
|
||||||
///
|
///
|
||||||
/// ## Lifecycle
|
|
||||||
///
|
|
||||||
/// A [RenderObject] must [dispose] when it is no longer needed. The creator
|
|
||||||
/// of the object is responsible for disposing of it. Typically, the creator is
|
|
||||||
/// a [RenderObjectElement], and that element will dispose the object it creates
|
|
||||||
/// when it is unmounted.
|
|
||||||
///
|
|
||||||
/// [RenderObject]s are responsible for cleaning up any expensive resources
|
|
||||||
/// they hold when [dispose] is called, such as [Picture] or [Image] objects.
|
|
||||||
/// This includes any [Layer]s that the render object has directly created. The
|
|
||||||
/// base implementation of dispose will nullify the [layer] property. Subclasses
|
|
||||||
/// must also nullify any other layer(s) it directly creates.
|
|
||||||
///
|
|
||||||
/// ## Writing a RenderObject subclass
|
/// ## Writing a RenderObject subclass
|
||||||
///
|
///
|
||||||
/// In most cases, subclassing [RenderObject] itself is overkill, and
|
/// In most cases, subclassing [RenderObject] itself is overkill, and
|
||||||
@ -1243,50 +1230,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether this has been disposed.
|
|
||||||
///
|
|
||||||
/// If asserts are disabled, this property is always null.
|
|
||||||
bool? get debugDisposed {
|
|
||||||
bool? disposed;
|
|
||||||
assert(() {
|
|
||||||
disposed = _debugDisposed;
|
|
||||||
return true;
|
|
||||||
}());
|
|
||||||
return disposed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _debugDisposed = false;
|
|
||||||
|
|
||||||
/// Release any resources held by this render object.
|
|
||||||
///
|
|
||||||
/// The object that creates a RenderObject is in charge of disposing it.
|
|
||||||
/// If this render object has created any children directly, it must dispose
|
|
||||||
/// of those children in this method as well. It must not dispose of any
|
|
||||||
/// children that were created by some other object, such as
|
|
||||||
/// a [RenderObjectElement]. Those children will be disposed when that
|
|
||||||
/// element unmounts, which may be delayed if the element is moved to another
|
|
||||||
/// part of the tree.
|
|
||||||
///
|
|
||||||
/// Implementations of this method must end with a call to the inherited
|
|
||||||
/// method, as in `super.dispose()`.
|
|
||||||
///
|
|
||||||
/// The object is no longer usable after calling dispose.
|
|
||||||
@mustCallSuper
|
|
||||||
void dispose() {
|
|
||||||
assert(!_debugDisposed);
|
|
||||||
_layer = null;
|
|
||||||
assert(() {
|
|
||||||
visitChildren((RenderObject child) {
|
|
||||||
assert(
|
|
||||||
child.debugDisposed!,
|
|
||||||
'${child.runtimeType} (child of $runtimeType) must be disposed before calling super.dispose().',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
_debugDisposed = true;
|
|
||||||
return true;
|
|
||||||
}());
|
|
||||||
}
|
|
||||||
|
|
||||||
// LAYOUT
|
// LAYOUT
|
||||||
|
|
||||||
/// Data for use by the parent render object.
|
/// Data for use by the parent render object.
|
||||||
@ -1424,10 +1367,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
bool get _debugCanPerformMutations {
|
bool get _debugCanPerformMutations {
|
||||||
late bool result;
|
late bool result;
|
||||||
assert(() {
|
assert(() {
|
||||||
if (_debugDisposed) {
|
|
||||||
result = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (owner != null && !owner!.debugDoingLayout) {
|
if (owner != null && !owner!.debugDoingLayout) {
|
||||||
result = true;
|
result = true;
|
||||||
return true;
|
return true;
|
||||||
@ -1462,7 +1401,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void attach(PipelineOwner owner) {
|
void attach(PipelineOwner owner) {
|
||||||
assert(!_debugDisposed);
|
|
||||||
super.attach(owner);
|
super.attach(owner);
|
||||||
// If the node was dirtied in some way while unattached, make sure to add
|
// If the node was dirtied in some way while unattached, make sure to add
|
||||||
// it to the appropriate dirty list now that an owner is available
|
// it to the appropriate dirty list now that an owner is available
|
||||||
@ -1674,7 +1612,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
///
|
///
|
||||||
/// See [RenderView] for an example of how this function is used.
|
/// See [RenderView] for an example of how this function is used.
|
||||||
void scheduleInitialLayout() {
|
void scheduleInitialLayout() {
|
||||||
assert(!_debugDisposed);
|
|
||||||
assert(attached);
|
assert(attached);
|
||||||
assert(parent is! RenderObject);
|
assert(parent is! RenderObject);
|
||||||
assert(!owner!._debugDoingLayout);
|
assert(!owner!._debugDoingLayout);
|
||||||
@ -1744,7 +1681,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
/// work to update its layout information.
|
/// work to update its layout information.
|
||||||
@pragma('vm:notify-debugger-on-exception')
|
@pragma('vm:notify-debugger-on-exception')
|
||||||
void layout(Constraints constraints, { bool parentUsesSize = false }) {
|
void layout(Constraints constraints, { bool parentUsesSize = false }) {
|
||||||
assert(!_debugDisposed);
|
|
||||||
if (!kReleaseMode && debugProfileLayoutsEnabled)
|
if (!kReleaseMode && debugProfileLayoutsEnabled)
|
||||||
Timeline.startSync('$runtimeType', arguments: timelineArgumentsIndicatingLandmarkEvent);
|
Timeline.startSync('$runtimeType', arguments: timelineArgumentsIndicatingLandmarkEvent);
|
||||||
|
|
||||||
@ -2104,7 +2040,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
/// it cannot be the case that _only_ the compositing bits changed,
|
/// it cannot be the case that _only_ the compositing bits changed,
|
||||||
/// something else will have scheduled a frame for us.
|
/// something else will have scheduled a frame for us.
|
||||||
void markNeedsCompositingBitsUpdate() {
|
void markNeedsCompositingBitsUpdate() {
|
||||||
assert(!_debugDisposed);
|
|
||||||
if (_needsCompositingBitsUpdate)
|
if (_needsCompositingBitsUpdate)
|
||||||
return;
|
return;
|
||||||
_needsCompositingBitsUpdate = true;
|
_needsCompositingBitsUpdate = true;
|
||||||
@ -2203,7 +2138,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
/// layer, thus limiting the number of nodes that [markNeedsPaint] must mark
|
/// layer, thus limiting the number of nodes that [markNeedsPaint] must mark
|
||||||
/// dirty.
|
/// dirty.
|
||||||
void markNeedsPaint() {
|
void markNeedsPaint() {
|
||||||
assert(!_debugDisposed);
|
|
||||||
assert(owner == null || !owner!.debugDoingPaint);
|
assert(owner == null || !owner!.debugDoingPaint);
|
||||||
if (_needsPaint)
|
if (_needsPaint)
|
||||||
return;
|
return;
|
||||||
@ -2288,7 +2222,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
///
|
///
|
||||||
/// This might be called if, e.g., the device pixel ratio changed.
|
/// This might be called if, e.g., the device pixel ratio changed.
|
||||||
void replaceRootLayer(OffsetLayer rootLayer) {
|
void replaceRootLayer(OffsetLayer rootLayer) {
|
||||||
assert(!_debugDisposed);
|
|
||||||
assert(rootLayer.attached);
|
assert(rootLayer.attached);
|
||||||
assert(attached);
|
assert(attached);
|
||||||
assert(parent is! RenderObject);
|
assert(parent is! RenderObject);
|
||||||
@ -2301,7 +2234,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _paintWithContext(PaintingContext context, Offset offset) {
|
void _paintWithContext(PaintingContext context, Offset offset) {
|
||||||
assert(!_debugDisposed);
|
|
||||||
assert(() {
|
assert(() {
|
||||||
if (_debugDoingThisPaint) {
|
if (_debugDoingThisPaint) {
|
||||||
throw FlutterError.fromParts(<DiagnosticsNode>[
|
throw FlutterError.fromParts(<DiagnosticsNode>[
|
||||||
@ -2525,7 +2457,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
///
|
///
|
||||||
/// See [RendererBinding] for an example of how this function is used.
|
/// See [RendererBinding] for an example of how this function is used.
|
||||||
void scheduleInitialSemantics() {
|
void scheduleInitialSemantics() {
|
||||||
assert(!_debugDisposed);
|
|
||||||
assert(attached);
|
assert(attached);
|
||||||
assert(parent is! RenderObject);
|
assert(parent is! RenderObject);
|
||||||
assert(!owner!._debugDoingSemantics);
|
assert(!owner!._debugDoingSemantics);
|
||||||
@ -2648,7 +2579,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
/// [RenderObject] as annotated by [describeSemanticsConfiguration] changes in
|
/// [RenderObject] as annotated by [describeSemanticsConfiguration] changes in
|
||||||
/// any way to update the semantics tree.
|
/// any way to update the semantics tree.
|
||||||
void markNeedsSemanticsUpdate() {
|
void markNeedsSemanticsUpdate() {
|
||||||
assert(!_debugDisposed);
|
|
||||||
assert(!attached || !owner!._debugDoingSemantics);
|
assert(!attached || !owner!._debugDoingSemantics);
|
||||||
if (!attached || owner!._semanticsOwner == null) {
|
if (!attached || owner!._semanticsOwner == null) {
|
||||||
_cachedSemanticsConfiguration = null;
|
_cachedSemanticsConfiguration = null;
|
||||||
@ -2894,10 +2824,6 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
|||||||
@override
|
@override
|
||||||
String toStringShort() {
|
String toStringShort() {
|
||||||
String header = describeIdentity(this);
|
String header = describeIdentity(this);
|
||||||
if (_debugDisposed) {
|
|
||||||
header += ' DISPOSED';
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
if (_relayoutBoundary != null && _relayoutBoundary != this) {
|
if (_relayoutBoundary != null && _relayoutBoundary != this) {
|
||||||
int count = 1;
|
int count = 1;
|
||||||
RenderObject? target = parent as RenderObject?;
|
RenderObject? target = parent as RenderObject?;
|
||||||
@ -3283,7 +3209,6 @@ mixin ContainerRenderObjectMixin<ChildType extends RenderObject, ParentDataType
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert child into this render object's child list after the given child.
|
/// Insert child into this render object's child list after the given child.
|
||||||
///
|
///
|
||||||
/// If `after` is null, then this inserts the child at the start of the list,
|
/// If `after` is null, then this inserts the child at the start of the list,
|
||||||
|
@ -3152,6 +3152,7 @@ class RenderRepaintBoundary extends RenderProxyBox {
|
|||||||
return offsetLayer.toImage(Offset.zero & size, pixelRatio: pixelRatio);
|
return offsetLayer.toImage(Offset.zero & size, pixelRatio: pixelRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// The number of times that this render object repainted at the same time as
|
/// The number of times that this render object repainted at the same time as
|
||||||
/// its parent. Repaint boundaries are only useful when the parent and child
|
/// its parent. Repaint boundaries are only useful when the parent and child
|
||||||
/// paint at different times. When both paint at the same time, the repaint
|
/// paint at different times. When both paint at the same time, the repaint
|
||||||
|
@ -6232,11 +6232,6 @@ class DefaultAssetBundle extends InheritedWidget {
|
|||||||
/// A given render object can be placed at most once in the widget tree. This
|
/// A given render object can be placed at most once in the widget tree. This
|
||||||
/// widget enforces that restriction by keying itself using a [GlobalObjectKey]
|
/// widget enforces that restriction by keying itself using a [GlobalObjectKey]
|
||||||
/// for the given render object.
|
/// for the given render object.
|
||||||
///
|
|
||||||
/// This widget will call [RenderObject.dispose] on the [renderBox] when it is
|
|
||||||
/// unmounted. After that point, the [renderBox] will be unusable. If any
|
|
||||||
/// children have been added to the [renderBox], they must be disposed in the
|
|
||||||
/// [onUnmount] callback.
|
|
||||||
class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget {
|
class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget {
|
||||||
/// Creates an adapter for placing a specific [RenderBox] in the widget tree.
|
/// Creates an adapter for placing a specific [RenderBox] in the widget tree.
|
||||||
///
|
///
|
||||||
@ -6244,7 +6239,6 @@ class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget {
|
|||||||
WidgetToRenderBoxAdapter({
|
WidgetToRenderBoxAdapter({
|
||||||
required this.renderBox,
|
required this.renderBox,
|
||||||
this.onBuild,
|
this.onBuild,
|
||||||
this.onUnmount,
|
|
||||||
}) : assert(renderBox != null),
|
}) : assert(renderBox != null),
|
||||||
// WidgetToRenderBoxAdapter objects are keyed to their render box. This
|
// WidgetToRenderBoxAdapter objects are keyed to their render box. This
|
||||||
// prevents the widget being used in the widget hierarchy in two different
|
// prevents the widget being used in the widget hierarchy in two different
|
||||||
@ -6253,9 +6247,6 @@ class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget {
|
|||||||
super(key: GlobalObjectKey(renderBox));
|
super(key: GlobalObjectKey(renderBox));
|
||||||
|
|
||||||
/// The render box to place in the widget tree.
|
/// The render box to place in the widget tree.
|
||||||
///
|
|
||||||
/// This widget takes ownership of the render object. When it is unmounted,
|
|
||||||
/// it also calls [RenderObject.dispose].
|
|
||||||
final RenderBox renderBox;
|
final RenderBox renderBox;
|
||||||
|
|
||||||
/// Called when it is safe to update the render box and its descendants. If
|
/// Called when it is safe to update the render box and its descendants. If
|
||||||
@ -6264,25 +6255,6 @@ class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget {
|
|||||||
/// tree will be dirty.
|
/// tree will be dirty.
|
||||||
final VoidCallback? onBuild;
|
final VoidCallback? onBuild;
|
||||||
|
|
||||||
/// Called when it is safe to dispose of children that were manually added to
|
|
||||||
/// the [renderBox].
|
|
||||||
///
|
|
||||||
/// Do not dispose the [renderBox] itself, as it will be disposed by the
|
|
||||||
/// framework automatically. However, during that process the framework will
|
|
||||||
/// check that all children of the [renderBox] have also been disposed.
|
|
||||||
/// Typically, child [RenderObject]s are disposed by corresponding [Element]s
|
|
||||||
/// when they are unmounted. However, child render objects that were manually
|
|
||||||
/// added do not have corresponding [Element]s to manage their lifecycle, and
|
|
||||||
/// need to be manually disposed here.
|
|
||||||
///
|
|
||||||
/// See also:
|
|
||||||
///
|
|
||||||
/// * [RenderObjectElement.unmount], which invokes this callback before
|
|
||||||
/// disposing of its render object.
|
|
||||||
/// * [RenderObject.dispose], which instructs a render object to release
|
|
||||||
/// any resources it may be holding.
|
|
||||||
final VoidCallback? onUnmount;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
RenderBox createRenderObject(BuildContext context) => renderBox;
|
RenderBox createRenderObject(BuildContext context) => renderBox;
|
||||||
|
|
||||||
@ -6290,12 +6262,6 @@ class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget {
|
|||||||
void updateRenderObject(BuildContext context, RenderBox renderObject) {
|
void updateRenderObject(BuildContext context, RenderBox renderObject) {
|
||||||
onBuild?.call();
|
onBuild?.call();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void didUnmountRenderObject(RenderObject renderObject) {
|
|
||||||
assert(renderObject == renderBox);
|
|
||||||
onUnmount?.call();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3199,13 +3199,10 @@ abstract class Element extends DiagnosticableTree implements BuildContext {
|
|||||||
RenderObject? result;
|
RenderObject? result;
|
||||||
void visit(Element element) {
|
void visit(Element element) {
|
||||||
assert(result == null); // this verifies that there's only one child
|
assert(result == null); // this verifies that there's only one child
|
||||||
if (element._lifecycleState == _ElementLifecycle.defunct) {
|
if (element is RenderObjectElement)
|
||||||
return;
|
|
||||||
} else if (element is RenderObjectElement) {
|
|
||||||
result = element.renderObject;
|
result = element.renderObject;
|
||||||
} else {
|
else
|
||||||
element.visitChildren(visit);
|
element.visitChildren(visit);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
visit(this);
|
visit(this);
|
||||||
return result;
|
return result;
|
||||||
@ -3844,10 +3841,6 @@ abstract class Element extends DiagnosticableTree implements BuildContext {
|
|||||||
/// After this function is called, the element will not be incorporated into
|
/// After this function is called, the element will not be incorporated into
|
||||||
/// the tree again.
|
/// the tree again.
|
||||||
///
|
///
|
||||||
/// Any resources this element holds should be released at this point. For
|
|
||||||
/// example, [RenderObjectElement.unmount] calls [RenderObject.dispose] and
|
|
||||||
/// nulls out its reference to the render object.
|
|
||||||
///
|
|
||||||
/// See the lifecycle documentation for [Element] for additional information.
|
/// See the lifecycle documentation for [Element] for additional information.
|
||||||
///
|
///
|
||||||
/// Implementations of this method should end with a call to the inherited
|
/// Implementations of this method should end with a call to the inherited
|
||||||
@ -5429,13 +5422,8 @@ abstract class RenderObjectElement extends Element {
|
|||||||
RenderObjectWidget get widget => super.widget as RenderObjectWidget;
|
RenderObjectWidget get widget => super.widget as RenderObjectWidget;
|
||||||
|
|
||||||
/// The underlying [RenderObject] for this element.
|
/// The underlying [RenderObject] for this element.
|
||||||
///
|
|
||||||
/// If this element has been [unmount]ed, this getter will throw.
|
|
||||||
@override
|
@override
|
||||||
RenderObject get renderObject {
|
RenderObject get renderObject => _renderObject!;
|
||||||
assert(_renderObject != null, '$runtimeType unmounted');
|
|
||||||
return _renderObject!;
|
|
||||||
}
|
|
||||||
RenderObject? _renderObject;
|
RenderObject? _renderObject;
|
||||||
|
|
||||||
bool _debugDoingBuild = false;
|
bool _debugDoingBuild = false;
|
||||||
@ -5503,7 +5491,6 @@ abstract class RenderObjectElement extends Element {
|
|||||||
return true;
|
return true;
|
||||||
}());
|
}());
|
||||||
_renderObject = widget.createRenderObject(this);
|
_renderObject = widget.createRenderObject(this);
|
||||||
assert(!_renderObject!.debugDisposed!);
|
|
||||||
assert(() {
|
assert(() {
|
||||||
_debugDoingBuild = false;
|
_debugDoingBuild = false;
|
||||||
return true;
|
return true;
|
||||||
@ -5781,11 +5768,6 @@ abstract class RenderObjectElement extends Element {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void unmount() {
|
void unmount() {
|
||||||
assert(
|
|
||||||
!renderObject.debugDisposed!,
|
|
||||||
'A RenderObject was disposed prior to its owning element being unmounted: '
|
|
||||||
'$renderObject',
|
|
||||||
);
|
|
||||||
final RenderObjectWidget oldWidget = widget;
|
final RenderObjectWidget oldWidget = widget;
|
||||||
super.unmount();
|
super.unmount();
|
||||||
assert(
|
assert(
|
||||||
@ -5794,8 +5776,6 @@ abstract class RenderObjectElement extends Element {
|
|||||||
'RenderObjectElement: $renderObject',
|
'RenderObjectElement: $renderObject',
|
||||||
);
|
);
|
||||||
oldWidget.didUnmountRenderObject(renderObject);
|
oldWidget.didUnmountRenderObject(renderObject);
|
||||||
_renderObject!.dispose();
|
|
||||||
_renderObject = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateParentData(ParentDataWidget<ParentData> parentDataWidget) {
|
void _updateParentData(ParentDataWidget<ParentData> parentDataWidget) {
|
||||||
|
@ -268,8 +268,8 @@ class _SliverPersistentHeaderElement extends RenderObjectElement {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void unmount() {
|
void unmount() {
|
||||||
renderObject._element = null;
|
|
||||||
super.unmount();
|
super.unmount();
|
||||||
|
renderObject._element = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -175,7 +175,7 @@ Future<void> main() async {
|
|||||||
expect(image.colorBlendMode, BlendMode.color);
|
expect(image.colorBlendMode, BlendMode.color);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('RenderImage disposes its image', () async {
|
test('Render image disposes its image', () async {
|
||||||
final ui.Image image = await createTestImage(width: 10, height: 10, cache: false);
|
final ui.Image image = await createTestImage(width: 10, height: 10, cache: false);
|
||||||
expect(image.debugGetOpenHandleStackTraces()!.length, 1);
|
expect(image.debugGetOpenHandleStackTraces()!.length, 1);
|
||||||
|
|
||||||
@ -192,7 +192,7 @@ Future<void> main() async {
|
|||||||
expect(image.debugGetOpenHandleStackTraces()!.length, 0);
|
expect(image.debugGetOpenHandleStackTraces()!.length, 0);
|
||||||
}, skip: kIsWeb); // Web doesn't track open image handles.
|
}, skip: kIsWeb); // Web doesn't track open image handles.
|
||||||
|
|
||||||
test('RenderImage does not dispose its image if setting the same image twice', () async {
|
test('Render image does not dispose its image if setting the same image twice', () async {
|
||||||
final ui.Image image = await createTestImage(width: 10, height: 10, cache: false);
|
final ui.Image image = await createTestImage(width: 10, height: 10, cache: false);
|
||||||
expect(image.debugGetOpenHandleStackTraces()!.length, 1);
|
expect(image.debugGetOpenHandleStackTraces()!.length, 1);
|
||||||
|
|
||||||
@ -208,19 +208,4 @@ Future<void> main() async {
|
|||||||
image.dispose();
|
image.dispose();
|
||||||
expect(image.debugGetOpenHandleStackTraces()!.length, 0);
|
expect(image.debugGetOpenHandleStackTraces()!.length, 0);
|
||||||
}, skip: kIsWeb); // Web doesn't track open image handles.
|
}, skip: kIsWeb); // Web doesn't track open image handles.
|
||||||
|
|
||||||
test('Render image disposes its image when it is disposed', () async {
|
|
||||||
final ui.Image image = await createTestImage(width: 10, height: 10, cache: false);
|
|
||||||
expect(image.debugGetOpenHandleStackTraces()!.length, 1);
|
|
||||||
|
|
||||||
final RenderImage renderImage = RenderImage(image: image.clone());
|
|
||||||
expect(image.debugGetOpenHandleStackTraces()!.length, 2);
|
|
||||||
|
|
||||||
renderImage.dispose();
|
|
||||||
expect(image.debugGetOpenHandleStackTraces()!.length, 1);
|
|
||||||
expect(renderImage.image, null);
|
|
||||||
|
|
||||||
image.dispose();
|
|
||||||
expect(image.debugGetOpenHandleStackTraces()!.length, 0);
|
|
||||||
}, skip: kIsWeb); // Web doesn't track open image handles.
|
|
||||||
}
|
}
|
||||||
|
@ -144,38 +144,6 @@ void main() {
|
|||||||
return context.pushOpacity(offset, 100, painter, oldLayer: oldLayer as OpacityLayer?);
|
return context.pushOpacity(offset, 100, painter, oldLayer: oldLayer as OpacityLayer?);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('RenderObject.dispose sets debugDisposed to true', () {
|
|
||||||
final TestRenderObject renderObject = TestRenderObject();
|
|
||||||
expect(renderObject.debugDisposed, false);
|
|
||||||
renderObject.dispose();
|
|
||||||
expect(renderObject.debugDisposed, true);
|
|
||||||
expect(renderObject.toStringShort(), contains('DISPOSED'));
|
|
||||||
});
|
|
||||||
|
|
||||||
test('RenderObject.dispose null the layer on repaint boundaries', () {
|
|
||||||
final TestRenderObject renderObject = TestRenderObject(allowPaintBounds: true);
|
|
||||||
// Force a layer to get set.
|
|
||||||
renderObject.isRepaintBoundary = true;
|
|
||||||
PaintingContext.repaintCompositedChild(renderObject, debugAlsoPaintedParent: true);
|
|
||||||
expect(renderObject.debugLayer, isA<OffsetLayer>());
|
|
||||||
|
|
||||||
// Dispose with repaint boundary still being true.
|
|
||||||
renderObject.dispose();
|
|
||||||
expect(renderObject.debugLayer, null);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('RenderObject.dispose nulls the layer on non-repaint boundaries', () {
|
|
||||||
final TestRenderObject renderObject = TestRenderObject(allowPaintBounds: true);
|
|
||||||
// Force a layer to get set.
|
|
||||||
renderObject.isRepaintBoundary = true;
|
|
||||||
PaintingContext.repaintCompositedChild(renderObject, debugAlsoPaintedParent: true);
|
|
||||||
|
|
||||||
// Dispose with repaint boundary being false.
|
|
||||||
renderObject.isRepaintBoundary = false;
|
|
||||||
renderObject.dispose();
|
|
||||||
expect(renderObject.debugLayer, null);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests the create-update cycle by pumping two frames. The first frame has no
|
// Tests the create-update cycle by pumping two frames. The first frame has no
|
||||||
@ -220,19 +188,12 @@ class _TestCustomLayerBox extends RenderBox {
|
|||||||
class TestParentData extends ParentData with ContainerParentDataMixin<RenderBox> { }
|
class TestParentData extends ParentData with ContainerParentDataMixin<RenderBox> { }
|
||||||
|
|
||||||
class TestRenderObject extends RenderObject {
|
class TestRenderObject extends RenderObject {
|
||||||
TestRenderObject({this.allowPaintBounds = false});
|
|
||||||
|
|
||||||
final bool allowPaintBounds;
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool isRepaintBoundary = false;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void debugAssertDoesMeetConstraints() { }
|
void debugAssertDoesMeetConstraints() { }
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Rect get paintBounds {
|
Rect get paintBounds {
|
||||||
assert(allowPaintBounds); // For some tests, this should not get called.
|
assert(false); // The test shouldn't call this.
|
||||||
return Rect.zero;
|
return Rect.zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1619,18 +1619,6 @@ void main() {
|
|||||||
await pumpWidget(Container());
|
await pumpWidget(Container());
|
||||||
expect(states, <String>['deactivate', 'dispose']);
|
expect(states, <String>['deactivate', 'dispose']);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('RenderObjectElement.unmount dispsoes of its renderObject', (WidgetTester tester) async {
|
|
||||||
await tester.pumpWidget(const Placeholder());
|
|
||||||
final RenderObjectElement element = tester.allElements.whereType<RenderObjectElement>().first;
|
|
||||||
final RenderObject renderObject = element.renderObject;
|
|
||||||
expect(renderObject.debugDisposed, false);
|
|
||||||
|
|
||||||
await tester.pumpWidget(Container());
|
|
||||||
|
|
||||||
expect(() => element.renderObject, throwsAssertionError);
|
|
||||||
expect(renderObject.debugDisposed, true);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _WidgetWithNoVisitChildren extends StatelessWidget {
|
class _WidgetWithNoVisitChildren extends StatelessWidget {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user