Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Unified Diff: sky/sdk/lib/rendering/object.dart

Issue 1229793002: Provide an API that allows a RenderObject's performLayout() function to call a callback that mutate… (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sky/sdk/lib/rendering/box.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/sdk/lib/rendering/object.dart
diff --git a/sky/sdk/lib/rendering/object.dart b/sky/sdk/lib/rendering/object.dart
index d8a67890f0abcb466e23556adaf2da371fc8ef8f..2b80f396b49aeb99b589c608a1bf536e474eb509 100644
--- a/sky/sdk/lib/rendering/object.dart
+++ b/sky/sdk/lib/rendering/object.dart
@@ -46,6 +46,8 @@ abstract class Constraints {
bool get isTight;
}
+typedef void LayoutCallback(Constraints constraints);
+
abstract class RenderObject extends AbstractNode implements HitTestTarget {
// LAYOUT
@@ -56,24 +58,21 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
dynamic parentData; // TODO(ianh): change the type of this back to ParentData once the analyzer is cleverer
void setupParentData(RenderObject child) {
// override this to setup .parentData correctly for your class
- assert(!debugDoingLayout);
- assert(!debugDoingPaint);
+ assert(debugCanPerformMutations);
if (child.parentData is! ParentData)
child.parentData = new ParentData();
}
void adoptChild(RenderObject child) { // only for use by subclasses
// call this whenever you decide a node is a child
- assert(!debugDoingLayout);
- assert(!debugDoingPaint);
+ assert(debugCanPerformMutations);
assert(child != null);
setupParentData(child);
super.adoptChild(child);
markNeedsLayout();
}
void dropChild(RenderObject child) { // only for use by subclasses
- assert(!debugDoingLayout);
- assert(!debugDoingPaint);
+ assert(debugCanPerformMutations);
assert(child != null);
assert(child.parentData != null);
child._cleanRelayoutSubtreeRoot();
@@ -82,7 +81,6 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
markNeedsLayout();
}
- static List<RenderObject> _nodesNeedingLayout = new List<RenderObject>();
static bool _debugDoingLayout = false;
static bool get debugDoingLayout => _debugDoingLayout;
bool _debugDoingThisResize = false;
@@ -91,8 +89,24 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
bool get debugDoingThisLayout => _debugDoingThisLayout;
static RenderObject _debugActiveLayout = null;
static RenderObject get debugActiveLayout => _debugActiveLayout;
+ bool _debugDoingThisLayoutWithCallback = false;
+ bool _debugMutationsLocked = false;
bool _debugCanParentUseSize;
bool get debugCanParentUseSize => _debugCanParentUseSize;
+ bool get debugCanPerformMutations {
+ RenderObject node = this;
+ while (true) {
+ if (node._debugDoingThisLayoutWithCallback)
+ return true;
+ if (node._debugMutationsLocked)
+ return false;
+ if (node.parent is! RenderObject)
+ return true;
+ node = node.parent;
+ }
+ }
+
+ static List<RenderObject> _nodesNeedingLayout = new List<RenderObject>();
bool _needsLayout = true;
bool get needsLayout => _needsLayout;
RenderObject _relayoutSubtreeRoot;
@@ -114,8 +128,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
return true;
}
void markNeedsLayout() {
- assert(!debugDoingLayout);
- assert(!debugDoingPaint);
+ assert(debugCanPerformMutations);
if (_needsLayout) {
assert(debugAncestorsAlreadyMarkedNeedsLayout());
return;
@@ -167,14 +180,25 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
void layoutWithoutResize() {
try {
assert(_relayoutSubtreeRoot == this);
- _debugCanParentUseSize = false;
- _debugDoingThisLayout = true;
- RenderObject debugPreviousActiveLayout = _debugActiveLayout;
- _debugActiveLayout = this;
+ RenderObject debugPreviousActiveLayout;
+ assert(!_debugMutationsLocked);
+ assert(!_debugDoingThisLayoutWithCallback);
+ assert(() {
+ _debugMutationsLocked = true;
+ _debugCanParentUseSize = false;
+ _debugDoingThisLayout = true;
+ debugPreviousActiveLayout = _debugActiveLayout;
+ _debugActiveLayout = this;
+ return true;
+ });
performLayout();
- _debugActiveLayout = debugPreviousActiveLayout;
- _debugDoingThisLayout = false;
- _debugCanParentUseSize = null;
+ assert(() {
+ _debugActiveLayout = debugPreviousActiveLayout;
+ _debugDoingThisLayout = false;
+ _debugCanParentUseSize = null;
+ _debugMutationsLocked = false;
+ return true;
+ });
} catch (e) {
print('Exception raised during layout:\n${e}\nContext:\n${this}');
return;
@@ -194,19 +218,33 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
return;
_constraints = constraints;
_relayoutSubtreeRoot = relayoutSubtreeRoot;
- _debugCanParentUseSize = parentUsesSize;
+ assert(!_debugMutationsLocked);
+ assert(!_debugDoingThisLayoutWithCallback);
+ assert(() {
+ _debugMutationsLocked = true;
+ _debugCanParentUseSize = parentUsesSize;
+ return true;
+ });
if (sizedByParent) {
- _debugDoingThisResize = true;
+ assert(() { _debugDoingThisResize = true; return true; });
performResize();
- _debugDoingThisResize = false;
+ assert(() { _debugDoingThisResize = false; return true; });
}
- _debugDoingThisLayout = true;
- RenderObject debugPreviousActiveLayout = _debugActiveLayout;
- _debugActiveLayout = this;
+ RenderObject debugPreviousActiveLayout;
+ assert(() {
+ _debugDoingThisLayout = true;
+ debugPreviousActiveLayout = _debugActiveLayout;
+ _debugActiveLayout = this;
+ return true;
+ });
performLayout();
- _debugActiveLayout = debugPreviousActiveLayout;
- _debugDoingThisLayout = false;
- _debugCanParentUseSize = null;
+ assert(() {
+ _debugActiveLayout = debugPreviousActiveLayout;
+ _debugDoingThisLayout = false;
+ _debugCanParentUseSize = null;
+ _debugMutationsLocked = false;
+ return true;
+ });
assert(debugDoesMeetConstraints());
_needsLayout = false;
markNeedsPaint();
@@ -226,6 +264,20 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
// When calling layout() on your children, pass in
// "parentUsesSize: true" if your size or layout is dependent on
// your child's size or intrinsic dimensions.
+ void invokeLayoutCallback(LayoutCallback callback) {
+ assert(_debugMutationsLocked);
+ assert(_debugDoingThisLayout);
+ assert(!_debugDoingThisLayoutWithCallback);
+ assert(() {
+ _debugDoingThisLayoutWithCallback = true;
+ return true;
+ });
+ callback(constraints);
+ assert(() {
+ _debugDoingThisLayoutWithCallback = false;
+ return true;
+ });
+ }
// when the parent has rotated (e.g. when the screen has been turned
// 90 degrees), immediately prior to layout() being called for the
@@ -535,7 +587,6 @@ abstract class ContainerRenderObjectMixin<ChildType extends RenderObject, Parent
assert(child.parentData is ParentDataType);
assert(_debugUltimatePreviousSiblingOf(child, equals: _firstChild));
assert(_debugUltimateNextSiblingOf(child, equals: _lastChild));
- _childCount -= 1;
assert(_childCount >= 0);
if (child.parentData.previousSibling == null) {
assert(_firstChild == child);
@@ -553,11 +604,26 @@ abstract class ContainerRenderObjectMixin<ChildType extends RenderObject, Parent
}
child.parentData.previousSibling = null;
child.parentData.nextSibling = null;
+ _childCount -= 1;
}
void remove(ChildType child) {
_removeFromChildList(child);
dropChild(child);
}
+ void removeAll() {
+ ChildType child = _firstChild;
+ while (child != null) {
+ assert(child.parentData is ParentDataType);
+ ChildType next = child.parentData.nextSibling;
+ child.parentData.previousSibling = null;
+ child.parentData.nextSibling = null;
+ dropChild(child);
+ child = next;
+ }
+ _firstChild = null;
+ _lastChild = null;
+ _childCount = 0;
+ }
void move(ChildType child, { ChildType before }) {
assert(child != this);
assert(before != this);
« no previous file with comments | « sky/sdk/lib/rendering/box.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698