mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Scheduler should be able to cancel a queued callback
Previously, once a callback was in the execution queue, it couldn't be canceled. Now we check whether the callback was canceled before executing it.
This commit is contained in:
parent
45bc387953
commit
7d5ef20bb1
@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:collection';
|
||||
import 'dart:sky' as sky;
|
||||
|
||||
import 'package:sky/base/debug.dart';
|
||||
@ -12,9 +13,10 @@ bool _haveScheduledVisualUpdate = false;
|
||||
int _nextCallbackId = 1;
|
||||
|
||||
final List<Callback> _persistentCallbacks = new List<Callback>();
|
||||
Map<int, Callback> _transientCallbacks = new Map<int, Callback>();
|
||||
Map<int, Callback> _transientCallbacks = new LinkedHashMap<int, Callback>();
|
||||
final Set<int> _removedIds = new Set<int>();
|
||||
|
||||
void _beginFrame(double timeStamp) {
|
||||
void beginFrame(double timeStamp) {
|
||||
timeStamp /= timeDilation;
|
||||
|
||||
_haveScheduledVisualUpdate = false;
|
||||
@ -23,15 +25,17 @@ void _beginFrame(double timeStamp) {
|
||||
_transientCallbacks = new Map<int, Callback>();
|
||||
|
||||
callbacks.forEach((id, callback) {
|
||||
callback(timeStamp);
|
||||
if (!_removedIds.contains(id))
|
||||
callback(timeStamp);
|
||||
});
|
||||
_removedIds.clear();
|
||||
|
||||
for (Callback callback in _persistentCallbacks)
|
||||
callback(timeStamp);
|
||||
}
|
||||
|
||||
void init() {
|
||||
sky.view.setFrameCallback(_beginFrame);
|
||||
sky.view.setFrameCallback(beginFrame);
|
||||
}
|
||||
|
||||
void addPersistentFrameCallback(Callback callback) {
|
||||
@ -47,6 +51,7 @@ int requestAnimationFrame(Callback callback) {
|
||||
|
||||
void cancelAnimationFrame(int id) {
|
||||
_transientCallbacks.remove(id);
|
||||
_removedIds.add(id);
|
||||
}
|
||||
|
||||
void ensureVisualUpdate() {
|
||||
|
||||
42
sky/unit/test/base/scheduler_test.dart
Normal file
42
sky/unit/test/base/scheduler_test.dart
Normal file
@ -0,0 +1,42 @@
|
||||
import 'package:sky/base/scheduler.dart' as scheduler;
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
test("Can cancel queued callback", () {
|
||||
int secondId;
|
||||
|
||||
bool firstCallbackRan = false;
|
||||
bool secondCallbackRan = false;
|
||||
|
||||
void firstCallback(double timeStamp) {
|
||||
expect(firstCallbackRan, isFalse);
|
||||
expect(secondCallbackRan, isFalse);
|
||||
expect(timeStamp, equals(16.0));
|
||||
firstCallbackRan = true;
|
||||
scheduler.cancelAnimationFrame(secondId);
|
||||
}
|
||||
|
||||
void secondCallback(double timeStamp) {
|
||||
expect(firstCallbackRan, isTrue);
|
||||
expect(secondCallbackRan, isFalse);
|
||||
expect(timeStamp, equals(16.0));
|
||||
secondCallbackRan = true;
|
||||
}
|
||||
|
||||
scheduler.requestAnimationFrame(firstCallback);
|
||||
secondId = scheduler.requestAnimationFrame(secondCallback);
|
||||
|
||||
scheduler.beginFrame(16.0);
|
||||
|
||||
expect(firstCallbackRan, isTrue);
|
||||
expect(secondCallbackRan, isFalse);
|
||||
|
||||
firstCallbackRan = false;
|
||||
secondCallbackRan = false;
|
||||
|
||||
scheduler.beginFrame(32.0);
|
||||
|
||||
expect(firstCallbackRan, isFalse);
|
||||
expect(secondCallbackRan, isFalse);
|
||||
});
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user