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
9d86ac5e
Commit
9d86ac5e
authored
Dec 02, 2015
by
Florian Loitsch
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #664 from floitschG/scheduler.renames
Rename some of the functions from the scheduler.
parents
c13fe8eb
72821152
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
129 additions
and
89 deletions
+129
-89
ticker.dart
packages/flutter/lib/src/animation/ticker.dart
+2
-2
scheduler.dart
packages/flutter/lib/src/scheduler/scheduler.dart
+111
-72
hero_controller.dart
packages/flutter/lib/src/widgets/hero_controller.dart
+1
-1
sprite_box.dart
packages/flutter_sprites/lib/src/sprite_box.dart
+1
-1
widget_tester.dart
packages/flutter_test/lib/src/widget_tester.dart
+2
-1
animation_test.dart
packages/unit/test/scheduler/animation_test.dart
+5
-5
scheduler_test.dart
packages/unit/test/scheduler/scheduler_test.dart
+7
-7
No files found.
packages/flutter/lib/src/animation/ticker.dart
View file @
9d86ac5e
...
...
@@ -40,7 +40,7 @@ class Ticker {
_startTime
=
null
;
if
(
_animationId
!=
null
)
{
scheduler
.
cancel
AnimationFrame
(
_animationId
);
scheduler
.
cancel
FrameCallbackWithId
(
_animationId
);
_animationId
=
null
;
}
...
...
@@ -74,6 +74,6 @@ class Ticker {
void
_scheduleTick
()
{
assert
(
isTicking
);
assert
(
_animationId
==
null
);
_animationId
=
scheduler
.
requestAnimationFrame
(
_tick
);
_animationId
=
scheduler
.
scheduleFrameCallback
(
_tick
);
}
}
packages/flutter/lib/src/scheduler/scheduler.dart
View file @
9d86ac5e
...
...
@@ -17,7 +17,7 @@ double timeDilation = 1.0;
/// scheduler's epoch. Use timeStamp to determine how far to advance animation
/// timelines so that all the animations in the system are synchronized to a
/// common time base.
typedef
void
Scheduler
Callback
(
Duration
timeStamp
);
typedef
void
Frame
Callback
(
Duration
timeStamp
);
typedef
void
SchedulerExceptionHandler
(
dynamic
exception
,
StackTrace
stack
);
/// This callback is invoked whenever an exception is caught by the scheduler.
...
...
@@ -29,11 +29,11 @@ SchedulerExceptionHandler debugSchedulerExceptionHandler;
/// An entry in the scheduler's priority queue.
///
/// Combines the task and its priority.
class
_
Scheduler
Entry
{
class
_
Task
Entry
{
final
ui
.
VoidCallback
task
;
final
int
priority
;
const
_
Scheduler
Entry
(
this
.
task
,
this
.
priority
);
const
_
Task
Entry
(
this
.
task
,
this
.
priority
);
}
class
Priority
{
...
...
@@ -83,102 +83,138 @@ class Priority {
class
Scheduler
{
/// Requires clients to use the [scheduler] singleton
Scheduler
.
_
()
{
ui
.
window
.
onBeginFrame
=
b
eginFrame
;
ui
.
window
.
onBeginFrame
=
handleB
eginFrame
;
}
SchedulingStrategy
schedulingStrategy
=
new
DefaultSchedulingStrategy
();
final
PriorityQueue
_
queue
=
new
HeapPriorityQueue
<
_Scheduler
Entry
>(
(
_
SchedulerEntry
e1
,
_Scheduler
Entry
e2
)
{
final
PriorityQueue
_
taskQueue
=
new
HeapPriorityQueue
<
_Task
Entry
>(
(
_
TaskEntry
e1
,
_Task
Entry
e2
)
{
// Note that we inverse the priority.
return
-
e1
.
priority
.
compareTo
(
e2
.
priority
);
}
);
/// Wether this scheduler already requested to be woken up as soon as
/// possible.
bool
_wakingNow
=
false
;
/// Whether this scheduler already requested to be called from the event loop.
bool
_hasRequestedAnEventLoopCallback
=
false
;
/// Wether this scheduler already requested to be woken up in the next frame.
bool
_wakingNextFrame
=
false
;
/// Whether this scheduler already requested to be called at the beginning of
/// the next frame.
bool
_hasRequestedABeginFrameCallback
=
false
;
/// Schedules the given [task] with the given [priority].
void
scheduleTask
(
ui
.
VoidCallback
task
,
Priority
priority
)
{
bool
isFirstTask
=
_
q
ueue
.
isEmpty
;
_
queue
.
add
(
new
_Scheduler
Entry
(
task
,
priority
.
_value
));
bool
isFirstTask
=
_
taskQ
ueue
.
isEmpty
;
_
taskQueue
.
add
(
new
_Task
Entry
(
task
,
priority
.
_value
));
if
(
isFirstTask
)
_
wakeNow
();
_
ensureEventLoopCallback
();
}
/// Invoked by the system when there is time to run tasks.
void
tick
()
{
if
(
_queue
.
isEmpty
)
void
handleEventLoopCallback
()
{
_hasRequestedAnEventLoopCallback
=
false
;
_runTasks
();
}
void
_runTasks
()
{
if
(
_taskQueue
.
isEmpty
)
return
;
_
SchedulerEntry
entry
=
_q
ueue
.
first
;
_
TaskEntry
entry
=
_taskQ
ueue
.
first
;
if
(
schedulingStrategy
.
shouldRunTaskWithPriority
(
entry
.
priority
))
{
try
{
(
_
q
ueue
.
removeFirst
().
task
)();
(
_
taskQ
ueue
.
removeFirst
().
task
)();
}
finally
{
if
(
_
q
ueue
.
isNotEmpty
)
_
wakeNow
();
if
(
_
taskQ
ueue
.
isNotEmpty
)
_
ensureEventLoopCallback
();
}
}
else
{
_wakeNextFrame
();
// TODO(floitsch): we shouldn't need to request a frame. Just schedule
// an event-loop callback.
_ensureBeginFrameCallback
();
}
}
int
_nextFrameCallbackId
=
0
;
// positive
Map
<
int
,
SchedulerCallback
>
_transientCallbacks
=
<
int
,
Scheduler
Callback
>{};
Map
<
int
,
FrameCallback
>
_transientCallbacks
=
<
int
,
Frame
Callback
>{};
final
Set
<
int
>
_removedIds
=
new
Set
<
int
>();
int
get
transientCallbackCount
=>
_transientCallbacks
.
length
;
/// Schedules the given frame callback.
int
requestAnimationFrame
(
SchedulerCallback
callback
)
{
///
/// Adds the given callback to the list of frame-callbacks and ensures that a
/// frame is scheduled.
int
scheduleFrameCallback
(
FrameCallback
callback
)
{
_ensureBeginFrameCallback
();
return
addFrameCallback
(
callback
);
}
/// Adds a frame callback.
///
/// Frame callbacks are executed at the beginning of a frame (see
/// [handleBeginFrame]).
///
/// The registered callbacks are executed in the order in which they have been
/// registered.
int
addFrameCallback
(
FrameCallback
callback
)
{
_nextFrameCallbackId
+=
1
;
_transientCallbacks
[
_nextFrameCallbackId
]
=
callback
;
_wakeNextFrame
();
return
_nextFrameCallbackId
;
}
/// Cancels the callback of the given [id].
void
cancelAnimationFrame
(
int
id
)
{
///
/// Removes the given callback from the list of frame callbacks. If a frame
/// has been requested does *not* cancel that request.
void
cancelFrameCallbackWithId
(
int
id
)
{
assert
(
id
>
0
);
_transientCallbacks
.
remove
(
id
);
_removedIds
.
add
(
id
);
}
final
List
<
SchedulerCallback
>
_persistentCallbacks
=
new
List
<
Scheduler
Callback
>();
final
List
<
FrameCallback
>
_persistentCallbacks
=
new
List
<
Frame
Callback
>();
void
addPersistentFrameCallback
(
SchedulerCallback
callback
)
{
/// Adds a persistent frame callback.
///
/// Persistent callbacks are invoked after transient (non-persistent) frame
/// callbacks.
///
/// Does *not* request a new frame. Conceptually, persistent
/// frame-callbacks are thus observers of begin-frame events. Since they are
/// executed after the transient frame-callbacks they can drive the rendering
/// pipeline.
void
addPersistentFrameCallback
(
FrameCallback
callback
)
{
_persistentCallbacks
.
add
(
callback
);
}
final
List
<
SchedulerCallback
>
_postFrameCallbacks
=
new
List
<
Scheduler
Callback
>();
final
List
<
FrameCallback
>
_postFrameCallbacks
=
new
List
<
Frame
Callback
>();
/// Schedule a callback for the end of this frame.
///
/// If a frame is in progress, the callback will be run just after the main
/// rendering pipeline has been flushed. In this case, order is preserved (the
/// callbacks are run in registration order).
/// Does *not* request a new frame.
///
/// If no frame is in progress, it will be called at the start of the next
/// frame. In this case, the registration order is not preserved. Callbacks
/// are called in an arbitrary order.
void
requestPostFrameCallback
(
SchedulerCallback
callback
)
{
/// The callback is run just after the persistent frame-callbacks (which is
/// when the main rendering pipeline has been flushed). If a frame is
/// in progress, but post frame-callbacks haven't been executed yet, then the
/// registered callback is still executed during the frame. Otherwise,
/// the registered callback is executed during the next frame.
///
/// The registered callbacks are executed in the order in which they have been
/// registered.
void
addPostFrameCallback
(
FrameCallback
callback
)
{
_postFrameCallbacks
.
add
(
callback
);
}
bool
_inFrame
=
false
;
bool
_i
sI
nFrame
=
false
;
void
_invoke
Animation
Callbacks
(
Duration
timeStamp
)
{
void
_invoke
TransientFrame
Callbacks
(
Duration
timeStamp
)
{
Timeline
.
startSync
(
'Animate'
);
assert
(
_inFrame
);
Map
<
int
,
Scheduler
Callback
>
callbacks
=
_transientCallbacks
;
_transientCallbacks
=
new
Map
<
int
,
Scheduler
Callback
>();
callbacks
.
forEach
((
int
id
,
Scheduler
Callback
callback
)
{
assert
(
_i
sI
nFrame
);
Map
<
int
,
Frame
Callback
>
callbacks
=
_transientCallbacks
;
_transientCallbacks
=
new
Map
<
int
,
Frame
Callback
>();
callbacks
.
forEach
((
int
id
,
Frame
Callback
callback
)
{
if
(!
_removedIds
.
contains
(
id
))
invokeCallback
(
callback
,
timeStamp
);
invoke
Frame
Callback
(
callback
,
timeStamp
);
});
_removedIds
.
clear
();
Timeline
.
finishSync
();
...
...
@@ -187,35 +223,41 @@ class Scheduler {
/// Called by the engine to produce a new frame.
///
/// This function first calls all the callbacks registered by
/// [requestAnimationFrame], then calls all the callbacks registered by
/// [addPersistentFrameCallback], which typically drive the rendering pipeline,
/// and finally calls the callbacks registered by [requestPostFrameCallback].
void
beginFrame
(
Duration
rawTimeStamp
)
{
/// [scheduleFrameCallback]/[addFrameCallback], then calls all the callbacks
/// registered by [addPersistentFrameCallback], which typically drive the
/// rendering pipeline, and finally calls the callbacks registered by
/// [addPostFrameCallback].
void
handleBeginFrame
(
Duration
rawTimeStamp
)
{
Timeline
.
startSync
(
'Begin frame'
);
assert
(!
_inFrame
);
_inFrame
=
true
;
assert
(!
_i
sI
nFrame
);
_i
sI
nFrame
=
true
;
Duration
timeStamp
=
new
Duration
(
microseconds:
(
rawTimeStamp
.
inMicroseconds
/
timeDilation
).
round
());
_
wakingNextFrame
=
false
;
_invoke
Animation
Callbacks
(
timeStamp
);
_
hasRequestedABeginFrameCallback
=
false
;
_invoke
TransientFrame
Callbacks
(
timeStamp
);
for
(
Scheduler
Callback
callback
in
_persistentCallbacks
)
invokeCallback
(
callback
,
timeStamp
);
for
(
Frame
Callback
callback
in
_persistentCallbacks
)
invoke
Frame
Callback
(
callback
,
timeStamp
);
List
<
Scheduler
Callback
>
localPostFrameCallbacks
=
new
List
<
Scheduler
Callback
>.
from
(
_postFrameCallbacks
);
List
<
Frame
Callback
>
localPostFrameCallbacks
=
new
List
<
Frame
Callback
>.
from
(
_postFrameCallbacks
);
_postFrameCallbacks
.
clear
();
for
(
Scheduler
Callback
callback
in
localPostFrameCallbacks
)
invokeCallback
(
callback
,
timeStamp
);
for
(
Frame
Callback
callback
in
localPostFrameCallbacks
)
invoke
Frame
Callback
(
callback
,
timeStamp
);
_inFrame
=
false
;
_i
sI
nFrame
=
false
;
Timeline
.
finishSync
();
// All frame-related callbacks have been executed. Run lower-priority tasks.
tick
();
_runTasks
();
}
void
invokeCallback
(
SchedulerCallback
callback
,
Duration
timeStamp
)
{
/// Invokes the given [callback] with [timestamp] as argument.
///
/// Wraps the callback in a try/catch and forwards any error to
/// [debugSchedulerExceptionHandler], if set. If not set, then simply prints
/// the error.
void
invokeFrameCallback
(
FrameCallback
callback
,
Duration
timeStamp
)
{
assert
(
callback
!=
null
);
try
{
callback
(
timeStamp
);
...
...
@@ -231,28 +273,25 @@ class Scheduler {
}
}
/// Tells the system that the scheduler is awake and should be called as
/// soon a there is time.
void
_wakeNow
()
{
if
(
_wakingNow
)
/// Ensures that the scheduler is woken by the event loop.
void
_ensureEventLoopCallback
()
{
if
(
_hasRequestedAnEventLoopCallback
)
return
;
_wakingNow
=
true
;
Timer
.
run
(()
{
_wakingNow
=
false
;
tick
();
});
Timer
.
run
(
handleEventLoopCallback
);
_hasRequestedAnEventLoopCallback
=
true
;
}
// TODO(floitsch): "ensureVisualUpdate" doesn't really fit into the scheduler.
void
ensureVisualUpdate
()
{
_
wakeNextFrame
();
_
ensureBeginFrameCallback
();
}
/// Schedules a new frame.
void
_
wakeNextFrame
()
{
if
(
_
wakingNextFrame
)
void
_
ensureBeginFrameCallback
()
{
if
(
_
hasRequestedABeginFrameCallback
)
return
;
_wakingNextFrame
=
true
;
ui
.
window
.
scheduleFrame
();
_hasRequestedABeginFrameCallback
=
true
;
}
}
...
...
packages/flutter/lib/src/widgets/hero_controller.dart
View file @
9d86ac5e
...
...
@@ -55,7 +55,7 @@ class HeroController extends NavigatorObserver {
void
_checkForHeroQuest
()
{
if
(
_from
!=
null
&&
_to
!=
null
&&
_from
!=
_to
)
{
_to
.
offstage
=
_to
.
performance
.
status
!=
PerformanceStatus
.
completed
;
scheduler
.
request
PostFrameCallback
(
_updateQuest
);
scheduler
.
add
PostFrameCallback
(
_updateQuest
);
}
}
...
...
packages/flutter_sprites/lib/src/sprite_box.dart
View file @
9d86ac5e
...
...
@@ -361,7 +361,7 @@ class SpriteBox extends RenderBox {
// Updates
void
_scheduleTick
()
{
scheduler
.
requestAnimationFrame
(
_tick
);
scheduler
.
scheduleFrameCallback
(
_tick
);
}
void
_tick
(
Duration
timeStamp
)
{
...
...
packages/flutter_test/lib/src/widget_tester.dart
View file @
9d86ac5e
...
...
@@ -34,7 +34,8 @@ class WidgetTester {
void
pump
([
Duration
duration
])
{
if
(
duration
!=
null
)
async
.
elapse
(
duration
);
scheduler
.
beginFrame
(
new
Duration
(
milliseconds:
clock
.
now
().
millisecondsSinceEpoch
));
scheduler
.
handleBeginFrame
(
new
Duration
(
milliseconds:
clock
.
now
().
millisecondsSinceEpoch
));
async
.
flushMicrotasks
();
}
...
...
packages/unit/test/scheduler/animation_test.dart
View file @
9d86ac5e
...
...
@@ -17,7 +17,7 @@ void main() {
expect
(
secondCallbackRan
,
isFalse
);
expect
(
timeStamp
.
inMilliseconds
,
equals
(
16
));
firstCallbackRan
=
true
;
scheduler
.
cancel
AnimationFrame
(
secondId
);
scheduler
.
cancel
FrameCallbackWithId
(
secondId
);
}
void
secondCallback
(
Duration
timeStamp
)
{
...
...
@@ -27,10 +27,10 @@ void main() {
secondCallbackRan
=
true
;
}
scheduler
.
requestAnimationFrame
(
firstCallback
);
secondId
=
scheduler
.
requestAnimationFrame
(
secondCallback
);
scheduler
.
scheduleFrameCallback
(
firstCallback
);
secondId
=
scheduler
.
scheduleFrameCallback
(
secondCallback
);
scheduler
.
b
eginFrame
(
const
Duration
(
milliseconds:
16
));
scheduler
.
handleB
eginFrame
(
const
Duration
(
milliseconds:
16
));
expect
(
firstCallbackRan
,
isTrue
);
expect
(
secondCallbackRan
,
isFalse
);
...
...
@@ -38,7 +38,7 @@ void main() {
firstCallbackRan
=
false
;
secondCallbackRan
=
false
;
scheduler
.
b
eginFrame
(
const
Duration
(
milliseconds:
32
));
scheduler
.
handleB
eginFrame
(
const
Duration
(
milliseconds:
32
));
expect
(
firstCallbackRan
,
isFalse
);
expect
(
secondCallbackRan
,
isFalse
);
...
...
packages/unit/test/scheduler/scheduler_test.dart
View file @
9d86ac5e
...
...
@@ -28,17 +28,17 @@ void main() {
scheduleAddingTask
(
x
);
}
strategy
.
allowedPriority
=
100
;
for
(
int
i
=
0
;
i
<
3
;
i
++)
scheduler
.
ti
ck
();
for
(
int
i
=
0
;
i
<
3
;
i
++)
scheduler
.
handleEventLoopCallba
ck
();
expect
(
executedTasks
.
isEmpty
,
isTrue
);
strategy
.
allowedPriority
=
50
;
for
(
int
i
=
0
;
i
<
3
;
i
++)
scheduler
.
ti
ck
();
for
(
int
i
=
0
;
i
<
3
;
i
++)
scheduler
.
handleEventLoopCallba
ck
();
expect
(
executedTasks
.
length
,
equals
(
1
));
expect
(
executedTasks
.
single
,
equals
(
80
));
executedTasks
.
clear
();
strategy
.
allowedPriority
=
20
;
for
(
int
i
=
0
;
i
<
3
;
i
++)
scheduler
.
ti
ck
();
for
(
int
i
=
0
;
i
<
3
;
i
++)
scheduler
.
handleEventLoopCallba
ck
();
expect
(
executedTasks
.
length
,
equals
(
2
));
expect
(
executedTasks
[
0
],
equals
(
23
));
expect
(
executedTasks
[
1
],
equals
(
23
));
...
...
@@ -48,21 +48,21 @@ void main() {
scheduleAddingTask
(
19
);
scheduleAddingTask
(
5
);
scheduleAddingTask
(
97
);
for
(
int
i
=
0
;
i
<
3
;
i
++)
scheduler
.
ti
ck
();
for
(
int
i
=
0
;
i
<
3
;
i
++)
scheduler
.
handleEventLoopCallba
ck
();
expect
(
executedTasks
.
length
,
equals
(
2
));
expect
(
executedTasks
[
0
],
equals
(
99
));
expect
(
executedTasks
[
1
],
equals
(
97
));
executedTasks
.
clear
();
strategy
.
allowedPriority
=
10
;
for
(
int
i
=
0
;
i
<
3
;
i
++)
scheduler
.
ti
ck
();
for
(
int
i
=
0
;
i
<
3
;
i
++)
scheduler
.
handleEventLoopCallba
ck
();
expect
(
executedTasks
.
length
,
equals
(
2
));
expect
(
executedTasks
[
0
],
equals
(
19
));
expect
(
executedTasks
[
1
],
equals
(
11
));
executedTasks
.
clear
();
strategy
.
allowedPriority
=
1
;
for
(
int
i
=
0
;
i
<
4
;
i
++)
scheduler
.
ti
ck
();
for
(
int
i
=
0
;
i
<
4
;
i
++)
scheduler
.
handleEventLoopCallba
ck
();
expect
(
executedTasks
.
length
,
equals
(
3
));
expect
(
executedTasks
[
0
],
equals
(
5
));
expect
(
executedTasks
[
1
],
equals
(
3
));
...
...
@@ -70,7 +70,7 @@ void main() {
executedTasks
.
clear
();
strategy
.
allowedPriority
=
0
;
scheduler
.
ti
ck
();
scheduler
.
handleEventLoopCallba
ck
();
expect
(
executedTasks
.
length
,
equals
(
1
));
expect
(
executedTasks
[
0
],
equals
(
0
));
});
...
...
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