Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
16e6be8b
Unverified
Commit
16e6be8b
authored
Jun 14, 2023
by
Michael Goderbauer
Committed by
GitHub
Jun 14, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Inline AbstractNode into SemanticsNode and Layer (#128467)
parent
40bb615b
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
204 additions
and
49 deletions
+204
-49
layer.dart
packages/flutter/lib/src/rendering/layer.dart
+133
-30
semantics.dart
packages/flutter/lib/src/semantics/semantics.dart
+70
-17
layers_test.dart
packages/flutter/test/rendering/layers_test.dart
+1
-2
No files found.
packages/flutter/lib/src/rendering/layer.dart
View file @
16e6be8b
...
...
@@ -136,7 +136,7 @@ const String _flutterRenderingLibrary = 'package:flutter/rendering.dart';
///
/// * [RenderView.compositeFrame], which implements this recomposition protocol
/// for painting [RenderObject] trees on the display.
abstract
class
Layer
extends
AbstractNode
with
DiagnosticableTreeMixin
{
abstract
class
Layer
with
DiagnosticableTreeMixin
{
/// Creates an instance of Layer.
Layer
()
{
if
(
kFlutterMemoryAllocationsEnabled
)
{
...
...
@@ -344,8 +344,8 @@ abstract class Layer extends AbstractNode with DiagnosticableTreeMixin {
///
/// Only subclasses of [ContainerLayer] can have children in the layer tree.
/// All other layer classes are used for leaves in the layer tree.
@override
ContainerLayer
?
get
parent
=>
super
.
parent
as
ContainerLayer
?
;
ContainerLayer
?
get
parent
=>
_parent
;
ContainerLayer
?
_parent
;
// Whether this layer has any changes since its last call to [addToScene].
//
...
...
@@ -495,6 +495,71 @@ abstract class Layer extends AbstractNode with DiagnosticableTreeMixin {
_needsAddToScene
=
_needsAddToScene
||
alwaysNeedsAddToScene
;
}
/// The owner for this node (null if unattached).
///
/// The entire subtree that this node belongs to will have the same owner.
Object
?
get
owner
=>
_owner
;
Object
?
_owner
;
/// Whether this node is in a tree whose root is attached to something.
///
/// This becomes true during the call to [attach].
///
/// This becomes false during the call to [detach].
bool
get
attached
=>
_owner
!=
null
;
/// Mark this node as attached to the given owner.
///
/// Typically called only from the [parent]'s [attach] method, and by the
/// [owner] to mark the root of a tree as attached.
///
/// Subclasses with children should override this method to first call their
/// inherited [attach] method, and then [attach] all their children to the
/// same [owner].
///
/// Implementations of this method should start with a call to the inherited
/// method, as in `super.attach(owner)`.
@mustCallSuper
void
attach
(
covariant
Object
owner
)
{
assert
(
_owner
==
null
);
_owner
=
owner
;
}
/// Mark this node as detached.
///
/// Typically called only from the [parent]'s [detach], and by the [owner] to
/// mark the root of a tree as detached.
///
/// Subclasses with children should override this method to first call their
/// inherited [detach] method, and then [detach] all their children.
///
/// Implementations of this method should end with a call to the inherited
/// method, as in `super.detach()`.
@mustCallSuper
void
detach
()
{
assert
(
_owner
!=
null
);
_owner
=
null
;
assert
(
parent
==
null
||
attached
==
parent
!.
attached
);
}
/// The depth of this node in the tree.
///
/// The depth of nodes in a tree monotonically increases as you traverse down
/// the tree.
int
get
depth
=>
_depth
;
int
_depth
=
0
;
/// Adjust the [depth] of this node's children, if any.
///
/// Override this method in subclasses with child nodes to call
/// [ContainerLayer.redepthChild] for each child. Do not call this method
/// directly.
@protected
void
redepthChildren
()
{
// ContainerLayer provides an implementation since its the only one that
// can actually have children.
}
/// This layer's next sibling in the parent layer's child list.
Layer
?
get
nextSibling
=>
_nextSibling
;
Layer
?
_nextSibling
;
...
...
@@ -503,30 +568,6 @@ abstract class Layer extends AbstractNode with DiagnosticableTreeMixin {
Layer
?
get
previousSibling
=>
_previousSibling
;
Layer
?
_previousSibling
;
@override
void
dropChild
(
Layer
child
)
{
assert
(!
_debugMutationsLocked
);
if
(!
alwaysNeedsAddToScene
)
{
markNeedsAddToScene
();
}
if
(
child
.
_compositionCallbackCount
!=
0
)
{
_updateSubtreeCompositionObserverCount
(-
child
.
_compositionCallbackCount
);
}
super
.
dropChild
(
child
);
}
@override
void
adoptChild
(
Layer
child
)
{
assert
(!
_debugMutationsLocked
);
if
(!
alwaysNeedsAddToScene
)
{
markNeedsAddToScene
();
}
if
(
child
.
_compositionCallbackCount
!=
0
)
{
_updateSubtreeCompositionObserverCount
(
child
.
_compositionCallbackCount
);
}
super
.
adoptChild
(
child
);
}
/// Removes this layer from its parent layer's child list.
///
/// This has no effect if the layer's parent is already null.
...
...
@@ -1198,7 +1239,7 @@ class ContainerLayer extends Layer {
assert
(
node
!=
child
);
// indicates we are about to create a cycle
return
true
;
}());
adoptChild
(
child
);
_
adoptChild
(
child
);
child
.
_previousSibling
=
lastChild
;
if
(
lastChild
!=
null
)
{
lastChild
!.
_nextSibling
=
child
;
...
...
@@ -1209,6 +1250,52 @@ class ContainerLayer extends Layer {
assert
(
child
.
attached
==
attached
);
}
void
_adoptChild
(
Layer
child
)
{
assert
(!
_debugMutationsLocked
);
if
(!
alwaysNeedsAddToScene
)
{
markNeedsAddToScene
();
}
if
(
child
.
_compositionCallbackCount
!=
0
)
{
_updateSubtreeCompositionObserverCount
(
child
.
_compositionCallbackCount
);
}
assert
(
child
.
_parent
==
null
);
assert
(()
{
Layer
node
=
this
;
while
(
node
.
parent
!=
null
)
{
node
=
node
.
parent
!;
}
assert
(
node
!=
child
);
// indicates we are about to create a cycle
return
true
;
}());
child
.
_parent
=
this
;
if
(
attached
)
{
child
.
attach
(
_owner
!);
}
redepthChild
(
child
);
}
@override
void
redepthChildren
()
{
Layer
?
child
=
firstChild
;
while
(
child
!=
null
)
{
redepthChild
(
child
);
child
=
child
.
nextSibling
;
}
}
/// Adjust the [depth] of the given [child] to be greater than this node's own
/// [depth].
///
/// Only call this method from overrides of [redepthChildren].
@protected
void
redepthChild
(
Layer
child
)
{
assert
(
child
.
owner
==
owner
);
if
(
child
.
_depth
<=
_depth
)
{
child
.
_depth
=
_depth
+
1
;
child
.
redepthChildren
();
}
}
// Implementation of [Layer.remove].
void
_removeChild
(
Layer
child
)
{
assert
(
child
.
parent
==
this
);
...
...
@@ -1235,11 +1322,27 @@ class ContainerLayer extends Layer {
assert
(
lastChild
==
null
||
_debugUltimatePreviousSiblingOf
(
lastChild
!,
equals:
firstChild
));
child
.
_previousSibling
=
null
;
child
.
_nextSibling
=
null
;
dropChild
(
child
);
_
dropChild
(
child
);
child
.
_parentHandle
.
layer
=
null
;
assert
(!
child
.
attached
);
}
void
_dropChild
(
Layer
child
)
{
assert
(!
_debugMutationsLocked
);
if
(!
alwaysNeedsAddToScene
)
{
markNeedsAddToScene
();
}
if
(
child
.
_compositionCallbackCount
!=
0
)
{
_updateSubtreeCompositionObserverCount
(-
child
.
_compositionCallbackCount
);
}
assert
(
child
.
_parent
==
this
);
assert
(
child
.
attached
==
attached
);
child
.
_parent
=
null
;
if
(
attached
)
{
child
.
detach
();
}
}
/// Removes all of this layer's children from its child list.
void
removeAllChildren
()
{
assert
(!
_debugMutationsLocked
);
...
...
@@ -1249,7 +1352,7 @@ class ContainerLayer extends Layer {
child
.
_previousSibling
=
null
;
child
.
_nextSibling
=
null
;
assert
(
child
.
attached
==
attached
);
dropChild
(
child
);
_
dropChild
(
child
);
child
.
_parentHandle
.
layer
=
null
;
child
=
next
;
}
...
...
packages/flutter/lib/src/semantics/semantics.dart
View file @
16e6be8b
...
...
@@ -1646,7 +1646,7 @@ void debugResetSemanticsIdCounter() {
/// (i.e., during [PipelineOwner.flushSemantics]), which happens after
/// compositing. The semantics tree is then uploaded into the engine for use
/// by assistive technology.
class
SemanticsNode
extends
AbstractNode
with
DiagnosticableTreeMixin
{
class
SemanticsNode
with
DiagnosticableTreeMixin
{
/// Creates a semantic node.
///
/// Each semantic node has a unique identifier that is assigned when the node
...
...
@@ -1923,7 +1923,7 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
if
(
child
.
parent
==
this
)
{
// we might have already had our child stolen from us by
// another node that is deeper in the tree.
dropChild
(
child
);
_
dropChild
(
child
);
}
sawChange
=
true
;
}
...
...
@@ -1937,10 +1937,10 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
// ancestors. In that case, we drop the child eagerly here.
// TODO(ianh): Find a way to assert that the same node didn't
// actually appear in the tree in two places.
child
.
parent
?.
dropChild
(
child
);
child
.
parent
?.
_
dropChild
(
child
);
}
assert
(!
child
.
attached
);
adoptChild
(
child
);
_
adoptChild
(
child
);
sawChange
=
true
;
}
}
...
...
@@ -1998,22 +1998,73 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
return
true
;
}
// AbstractNode OVERRIDES
/// The owner for this node (null if unattached).
///
/// The entire subtree that this node belongs to will have the same owner.
SemanticsOwner
?
get
owner
=>
_owner
;
SemanticsOwner
?
_owner
;
@override
SemanticsOwner
?
get
owner
=>
super
.
owner
as
SemanticsOwner
?;
/// Whether this node is in a tree whose root is attached to something.
///
/// This becomes true during the call to [attach].
///
/// This becomes false during the call to [detach].
bool
get
attached
=>
_owner
!=
null
;
@override
SemanticsNode
?
get
parent
=>
super
.
parent
as
SemanticsNode
?;
/// The parent of this node in the tree.
SemanticsNode
?
get
parent
=>
_parent
;
SemanticsNode
?
_parent
;
@override
void
redepthChildren
()
{
_children
?.
forEach
(
redepthChild
);
/// The depth of this node in the tree.
///
/// The depth of nodes in a tree monotonically increases as you traverse down
/// the tree.
int
get
depth
=>
_depth
;
int
_depth
=
0
;
void
_redepthChild
(
SemanticsNode
child
)
{
assert
(
child
.
owner
==
owner
);
if
(
child
.
_depth
<=
_depth
)
{
child
.
_depth
=
_depth
+
1
;
child
.
_redepthChildren
();
}
}
@override
void
_redepthChildren
()
{
_children
?.
forEach
(
_redepthChild
);
}
void
_adoptChild
(
SemanticsNode
child
)
{
assert
(
child
.
_parent
==
null
);
assert
(()
{
SemanticsNode
node
=
this
;
while
(
node
.
parent
!=
null
)
{
node
=
node
.
parent
!;
}
assert
(
node
!=
child
);
// indicates we are about to create a cycle
return
true
;
}());
child
.
_parent
=
this
;
if
(
attached
)
{
child
.
attach
(
_owner
!);
}
_redepthChild
(
child
);
}
void
_dropChild
(
SemanticsNode
child
)
{
assert
(
child
.
_parent
==
this
);
assert
(
child
.
attached
==
attached
);
child
.
_parent
=
null
;
if
(
attached
)
{
child
.
detach
();
}
}
/// Mark this node as attached to the given owner.
@visibleForTesting
void
attach
(
SemanticsOwner
owner
)
{
super
.
attach
(
owner
);
assert
(
_owner
==
null
);
_owner
=
owner
;
while
(
owner
.
_nodes
.
containsKey
(
id
))
{
// Ids may repeat if the Flutter has generated > 2^16 ids. We need to keep
// regenerating the id until we found an id that is not used.
...
...
@@ -2032,14 +2083,16 @@ class SemanticsNode extends AbstractNode with DiagnosticableTreeMixin {
}
}
@override
/// Mark this node as detached.
@visibleForTesting
void
detach
()
{
assert
(
_owner
!=
null
);
assert
(
owner
!.
_nodes
.
containsKey
(
id
));
assert
(!
owner
!.
_detachedNodes
.
contains
(
this
));
owner
!.
_nodes
.
remove
(
id
);
owner
!.
_detachedNodes
.
add
(
this
);
super
.
detach
()
;
assert
(
owner
==
null
);
_owner
=
null
;
assert
(
parent
==
null
||
attached
==
parent
!.
attached
);
if
(
_children
!=
null
)
{
for
(
final
SemanticsNode
child
in
_children
!)
{
// The list of children may be stale and may contain nodes that have
...
...
packages/flutter/test/rendering/layers_test.dart
View file @
16e6be8b
...
...
@@ -899,8 +899,7 @@ void main() {
expect
(()
=>
layer
.
markNeedsAddToScene
(),
throwsAssertionError
);
expect
(()
=>
layer
.
debugMarkClean
(),
throwsAssertionError
);
expect
(()
=>
layer
.
updateSubtreeNeedsAddToScene
(),
throwsAssertionError
);
expect
(()
=>
layer
.
dropChild
(
ContainerLayer
()),
throwsAssertionError
);
expect
(()
=>
layer
.
adoptChild
(
ContainerLayer
()),
throwsAssertionError
);
expect
(()
=>
layer
.
remove
(),
throwsAssertionError
);
expect
(()
=>
(
layer
as
ContainerLayer
).
append
(
ContainerLayer
()),
throwsAssertionError
);
expect
(()
=>
layer
.
engineLayer
=
null
,
throwsAssertionError
);
compositedB1
=
true
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment