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
244fdab0
Commit
244fdab0
authored
Sep 22, 2015
by
Adam Barth
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1279 from Hixie/fn3
More dartdocs for fn3, refactor buildDirtyElements
parents
963fb413
de62f1b6
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
105 additions
and
79 deletions
+105
-79
framework.dart
packages/flutter/lib/src/fn3/framework.dart
+105
-79
No files found.
packages/flutter/lib/src/fn3/framework.dart
View file @
244fdab0
...
...
@@ -179,6 +179,7 @@ abstract class Element<T extends Widget> {
dynamic
_slot
;
/// An integer that is guaranteed to be greater than the parent's, if any.
/// The element at the root of the tree must have a depth greater than 0.
int
_depth
;
/// The configuration for this element.
...
...
@@ -258,7 +259,7 @@ abstract class Element<T extends Widget> {
assert
(
_depth
==
null
);
_parent
=
parent
;
_slot
=
slot
;
_depth
=
_parent
!=
null
?
_parent
.
_depth
+
1
:
0
;
_depth
=
_parent
!=
null
?
_parent
.
_depth
+
1
:
1
;
assert
(()
{
_debugLifecycleState
=
_ElementLifecycle
.
mounted
;
return
true
;
});
}
...
...
@@ -328,64 +329,20 @@ abstract class Element<T extends Widget> {
void
unmount
()
{
assert
(
_debugLifecycleState
==
_ElementLifecycle
.
mounted
);
assert
(
_widget
!=
null
);
assert
(
_slot
==
null
);
assert
(
_depth
!=
null
);
assert
(()
{
_debugLifecycleState
=
_ElementLifecycle
.
defunct
;
return
true
;
});
}
// TODO(ianh): Merge this into the binding, expose for tests
static
void
flushBuild
()
{
_buildScheduler
.
buildDirtyElements
();
}
}
class
_BuildScheduler
{
final
Set
<
BuildableElement
>
_dirtyElements
=
new
Set
<
BuildableElement
>();
bool
_inBuildDirtyElements
=
false
;
void
schedule
(
BuildableElement
element
)
{
if
(
_dirtyElements
.
isEmpty
)
scheduler
.
ensureVisualUpdate
();
_dirtyElements
.
add
(
element
);
}
void
_absorbDirtyElements
(
List
<
BuildableElement
>
list
)
{
list
.
addAll
(
_dirtyElements
);
_dirtyElements
.
clear
();
list
.
sort
((
BuildableElement
a
,
BuildableElement
b
)
=>
a
.
_depth
-
b
.
_depth
);
}
void
buildDirtyElements
()
{
if
(
_dirtyElements
.
isEmpty
)
return
;
_inBuildDirtyElements
=
true
;
try
{
while
(!
_dirtyElements
.
isEmpty
)
{
List
<
BuildableElement
>
sortedDirtyElements
=
new
List
<
BuildableElement
>();
_absorbDirtyElements
(
sortedDirtyElements
);
int
index
=
0
;
while
(
index
<
sortedDirtyElements
.
length
)
{
sortedDirtyElements
[
index
].
_rebuildIfNeeded
();
if
(!
_dirtyElements
.
isEmpty
)
{
assert
(
_dirtyElements
.
every
((
Element
element
)
=>
!
sortedDirtyElements
.
contains
(
element
)));
_absorbDirtyElements
(
sortedDirtyElements
);
index
=
0
;
}
else
{
index
+=
1
;
}
}
}
}
finally
{
_inBuildDirtyElements
=
false
;
}
assert
(
_dirtyElements
.
isEmpty
);
}
}
final
_BuildScheduler
_buildScheduler
=
new
_BuildScheduler
();
typedef
Widget
WidgetBuilder
(
);
/// Base class for the instantiation of StatelessComponent and StatefulComponent
/// widgets.
abstract
class
BuildableElement
<
T
extends
Widget
>
extends
Element
<
T
>
{
BuildableElement
(
T
widget
)
:
super
(
widget
);
...
...
@@ -393,6 +350,14 @@ abstract class BuildableElement<T extends Widget> extends Element<T> {
Element
_child
;
bool
_dirty
=
true
;
void
mount
(
Element
parent
,
dynamic
slot
)
{
super
.
mount
(
parent
,
slot
);
assert
(
_child
==
null
);
_rebuild
();
assert
(
_child
!=
null
);
}
// This is also called for the first build
void
_rebuild
()
{
assert
(
_debugLifecycleState
==
_ElementLifecycle
.
mounted
);
_dirty
=
false
;
...
...
@@ -406,18 +371,25 @@ abstract class BuildableElement<T extends Widget> extends Element<T> {
_child
=
_updateChild
(
_child
,
built
,
_slot
);
}
/// Called by the binding when scheduleBuild() has been called to mark this element dirty.
void
_rebuildIfNeeded
()
{
if
(
_dirty
)
_rebuild
();
}
/// Marks the element as dirty and adds it to the global list of widgets to
/// rebuild in the next frame.
///
/// Since it is inefficient to build an element twice in one frame,
/// applications and components should be structured so as to only mark
/// components dirty during event handlers before the frame begins, not during
/// the build itself.
void
scheduleBuild
()
{
assert
(
_debugLifecycleState
==
_ElementLifecycle
.
mounted
);
if
(
_dirty
)
return
;
_dirty
=
true
;
_buildScheduler
.
schedule
(
this
);
// TODO(abarth): Implement rebuilding.
}
void
visitChildren
(
ElementVisitor
visitor
)
{
...
...
@@ -425,22 +397,16 @@ abstract class BuildableElement<T extends Widget> extends Element<T> {
visitor
(
_child
);
}
void
mount
(
Element
parent
,
dynamic
slot
)
{
super
.
mount
(
parent
,
slot
);
assert
(
_child
==
null
);
_rebuild
();
assert
(
_child
!=
null
);
}
void
unmount
()
{
super
.
unmount
();
_dirty
=
false
;
_dirty
=
false
;
// so that we don't get rebuilt even if we're already marked dirty
}
}
/// Instantiation of StatelessComponent widgets.
class
StatelessComponentElement
extends
BuildableElement
<
StatelessComponent
>
{
StatelessComponentElement
(
StatelessComponent
component
)
:
super
(
componen
t
)
{
_builder
=
componen
t
.
build
;
StatelessComponentElement
(
StatelessComponent
widget
)
:
super
(
widge
t
)
{
_builder
=
_widge
t
.
build
;
}
void
update
(
StatelessComponent
newWidget
)
{
...
...
@@ -451,10 +417,11 @@ class StatelessComponentElement extends BuildableElement<StatelessComponent> {
}
}
/// Instantiation of StatefulComponent widgets.
class
StatefulComponentElement
extends
BuildableElement
<
StatefulComponent
>
{
StatefulComponentElement
(
StatefulComponent
configuration
)
:
_state
=
configuration
.
createState
(),
super
(
configuration
)
{
assert
(
_state
.
_config
==
configuration
);
StatefulComponentElement
(
StatefulComponent
widget
)
:
_state
=
widget
.
createState
(),
super
(
widget
)
{
assert
(
_state
.
_config
==
widget
);
_state
.
_element
=
this
;
_builder
=
_state
.
build
;
}
...
...
@@ -478,25 +445,27 @@ class StatefulComponentElement extends BuildableElement<StatefulComponent> {
}
}
RenderObjectElement
_findAncestorRenderObjectElement
(
Element
ancestor
)
{
while
(
ancestor
!=
null
&&
ancestor
is
!
RenderObjectElement
)
ancestor
=
ancestor
.
_parent
;
return
ancestor
;
}
class
RenderObjectElement
<
T
extends
RenderObjectWidget
>
extends
Element
<
T
>
{
/// Base class for instantiations of RenderObjectWidget subclasses
abstract
class
RenderObjectElement
<
T
extends
RenderObjectWidget
>
extends
Element
<
T
>
{
RenderObjectElement
(
T
widget
)
:
renderObject
=
widget
.
createRenderObject
(),
super
(
widget
);
/// The underlying [RenderObject] for this element
final
RenderObject
renderObject
;
RenderObjectElement
_ancestorRenderObjectElement
;
RenderObjectElement
_findAncestorRenderObjectElement
()
{
Element
ancestor
=
_parent
;
while
(
ancestor
!=
null
&&
ancestor
is
!
RenderObjectElement
)
ancestor
=
ancestor
.
_parent
;
return
ancestor
;
}
void
mount
(
Element
parent
,
dynamic
slot
)
{
super
.
mount
(
parent
,
slot
);
assert
(
_ancestorRenderObjectElement
==
null
);
_ancestorRenderObjectElement
=
_findAncestorRenderObjectElement
(
_parent
);
if
(
_ancestorRenderObjectElement
!=
null
)
_ancestorRenderObjectElement
.
insertChildRenderObject
(
renderObject
,
slot
);
_ancestorRenderObjectElement
=
_findAncestorRenderObjectElement
();
_ancestorRenderObjectElement
?.
insertChildRenderObject
(
renderObject
,
slot
);
}
void
update
(
T
newWidget
)
{
...
...
@@ -512,6 +481,15 @@ class RenderObjectElement<T extends RenderObjectWidget> extends Element<T> {
}
}
void
insertChildRenderObject
(
RenderObject
child
,
dynamic
slot
);
void
removeChildRenderObject
(
RenderObject
child
);
}
/// Instantiation of RenderObjectWidgets that have no children
class
LeafRenderObjectElement
<
T
extends
RenderObjectWidget
>
extends
RenderObjectElement
<
T
>
{
LeafRenderObjectElement
(
T
widget
):
super
(
widget
);
void
insertChildRenderObject
(
RenderObject
child
,
dynamic
slot
)
{
assert
(
false
);
}
...
...
@@ -521,10 +499,7 @@ class RenderObjectElement<T extends RenderObjectWidget> extends Element<T> {
}
}
class
LeafRenderObjectElement
<
T
extends
RenderObjectWidget
>
extends
RenderObjectElement
<
T
>
{
LeafRenderObjectElement
(
T
widget
):
super
(
widget
);
}
/// Instantiation of RenderObjectWidgets that have up to one child
class
OneChildRenderObjectElement
<
T
extends
OneChildRenderObjectWidget
>
extends
RenderObjectElement
<
T
>
{
OneChildRenderObjectElement
(
T
widget
)
:
super
(
widget
);
...
...
@@ -537,19 +512,19 @@ class OneChildRenderObjectElement<T extends OneChildRenderObjectWidget> extends
void
mount
(
Element
parent
,
dynamic
slot
)
{
super
.
mount
(
parent
,
slot
);
_child
=
_updateChild
(
_child
,
_widget
.
child
,
uniqueChild
);
_child
=
_updateChild
(
_child
,
_widget
.
child
,
_
uniqueChild
);
}
void
update
(
T
newWidget
)
{
super
.
update
(
newWidget
);
assert
(
_widget
==
newWidget
);
_child
=
_updateChild
(
_child
,
_widget
.
child
,
uniqueChild
);
_child
=
_updateChild
(
_child
,
_widget
.
child
,
_
uniqueChild
);
}
void
insertChildRenderObject
(
RenderObject
child
,
dynamic
slot
)
{
final
renderObject
=
this
.
renderObject
;
// TODO(ianh): Remove this once the analyzer is cleverer
assert
(
renderObject
is
RenderObjectWithChildMixin
);
assert
(
slot
==
uniqueChild
);
assert
(
slot
==
_
uniqueChild
);
renderObject
.
child
=
child
;
assert
(
renderObject
==
this
.
renderObject
);
// TODO(ianh): Remove this once the analyzer is cleverer
}
...
...
@@ -563,10 +538,61 @@ class OneChildRenderObjectElement<T extends OneChildRenderObjectWidget> extends
}
}
/// Instantiation of RenderObjectWidgets that can have a list of children
class
MultiChildRenderObjectElement
<
T
extends
MultiChildRenderObjectWidget
>
extends
RenderObjectElement
<
T
>
{
MultiChildRenderObjectElement
(
T
widget
)
:
super
(
widget
);
// TODO(ianh): implement
}
class
_BuildScheduler
{
final
List
<
BuildableElement
>
_dirtyElements
=
new
List
<
BuildableElement
>();
int
_debugBuildingAtDepth
;
void
schedule
(
BuildableElement
element
)
{
assert
(
_debugBuildingAtDepth
==
null
||
element
.
_depth
>
_debugBuildingAtDepth
);
assert
(!
_dirtyElements
.
contains
(
element
));
if
(
_dirtyElements
.
isEmpty
)
scheduler
.
ensureVisualUpdate
();
_dirtyElements
.
add
(
element
);
}
void
_absorbDirtyElements
(
List
<
BuildableElement
>
list
)
{
assert
(
_debugBuildingAtDepth
!=
null
);
assert
(!
_dirtyElements
.
any
((
element
)
=>
element
.
_depth
<=
_debugBuildingAtDepth
));
_dirtyElements
.
sort
((
BuildableElement
a
,
BuildableElement
b
)
=>
a
.
_depth
-
b
.
_depth
);
list
.
addAll
(
_dirtyElements
);
_dirtyElements
.
clear
();
}
/// Builds all the elements that were marked as dirty using schedule(), in depth order.
/// If elements are marked as dirty while this runs, they must be deeper than the algorithm
/// has yet reached.
void
buildDirtyElements
()
{
assert
(
_debugBuildingAtDepth
==
null
);
if
(
_dirtyElements
.
isEmpty
)
return
;
assert
(()
{
_debugBuildingAtDepth
=
0
;
return
true
;
});
List
<
BuildableElement
>
sortedDirtyElements
=
new
List
<
BuildableElement
>();
int
index
=
0
;
do
{
_absorbDirtyElements
(
sortedDirtyElements
);
for
(;
index
<
sortedDirtyElements
.
length
;
index
+=
1
)
{
BuildableElement
element
=
sortedDirtyElements
[
index
];
assert
(()
{
if
(
element
.
_depth
>
_debugBuildingAtDepth
)
_debugBuildingAtDepth
=
element
.
_depth
;
return
element
.
_depth
==
_debugBuildingAtDepth
;
});
element
.
_rebuildIfNeeded
();
}
}
while
(
_dirtyElements
.
isNotEmpty
);
assert
(()
{
_debugBuildingAtDepth
=
null
;
return
true
;
});
}
}
final
_BuildScheduler
_buildScheduler
=
new
_BuildScheduler
();
typedef
void
WidgetsExceptionHandler
(
String
context
,
dynamic
exception
,
StackTrace
stack
);
...
...
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