Improve UI-thread animation performance (#159288)
The following PR (https://github.com/flutter/flutter/pull/138481) got split in 2, this is part 2. We now have the microbenchmarks to compare this change against (and hopefully see improvements). Close: https://github.com/flutter/flutter/issues/146211 Part 1: https://github.com/flutter/flutter/pull/153368 --------- Co-authored-by: Nate Wilson <nathan.wilson1232@gmail.com>
This commit is contained in:
parent
61d7d0ed23
commit
c1a6c5500c
@ -91,7 +91,7 @@ mixin AnimationEagerListenerMixin {
|
|||||||
/// and [didUnregisterListener]. Implementations of these methods can be obtained
|
/// and [didUnregisterListener]. Implementations of these methods can be obtained
|
||||||
/// by mixing in another mixin from this library, such as [AnimationLazyListenerMixin].
|
/// by mixing in another mixin from this library, such as [AnimationLazyListenerMixin].
|
||||||
mixin AnimationLocalListenersMixin {
|
mixin AnimationLocalListenersMixin {
|
||||||
final ObserverList<VoidCallback> _listeners = ObserverList<VoidCallback>();
|
final HashedObserverList<VoidCallback> _listeners = HashedObserverList<VoidCallback>();
|
||||||
|
|
||||||
/// Called immediately before a listener is added via [addListener].
|
/// Called immediately before a listener is added via [addListener].
|
||||||
///
|
///
|
||||||
|
@ -43,12 +43,15 @@ class ObserverList<T> extends Iterable<T> {
|
|||||||
///
|
///
|
||||||
/// Returns whether the item was present in the list.
|
/// Returns whether the item was present in the list.
|
||||||
bool remove(T item) {
|
bool remove(T item) {
|
||||||
|
final bool removed = _list.remove(item);
|
||||||
|
if (removed) {
|
||||||
_isDirty = true;
|
_isDirty = true;
|
||||||
_set.clear(); // Clear the set so that we don't leak items.
|
_set.clear(); // Clear the set so that we don't leak items.
|
||||||
return _list.remove(item);
|
}
|
||||||
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes all items from the list.
|
/// Removes all items from the [ObserverList].
|
||||||
void clear() {
|
void clear() {
|
||||||
_isDirty = false;
|
_isDirty = false;
|
||||||
_list.clear();
|
_list.clear();
|
||||||
@ -78,6 +81,10 @@ class ObserverList<T> extends Iterable<T> {
|
|||||||
@override
|
@override
|
||||||
bool get isNotEmpty => _list.isNotEmpty;
|
bool get isNotEmpty => _list.isNotEmpty;
|
||||||
|
|
||||||
|
/// Creates a List containing the elements of the [ObserverList].
|
||||||
|
///
|
||||||
|
/// Overrides the default implementation of the [Iterable] to reduce number
|
||||||
|
/// of allocations.
|
||||||
@override
|
@override
|
||||||
List<T> toList({bool growable = true}) {
|
List<T> toList({bool growable = true}) {
|
||||||
return _list.toList(growable: growable);
|
return _list.toList(growable: growable);
|
||||||
@ -126,6 +133,9 @@ class HashedObserverList<T> extends Iterable<T> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes all items from the [HashedObserverList].
|
||||||
|
void clear() => _map.clear();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool contains(Object? element) => _map.containsKey(element);
|
bool contains(Object? element) => _map.containsKey(element);
|
||||||
|
|
||||||
@ -137,4 +147,18 @@ class HashedObserverList<T> extends Iterable<T> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
bool get isNotEmpty => _map.isNotEmpty;
|
bool get isNotEmpty => _map.isNotEmpty;
|
||||||
|
|
||||||
|
/// Creates a List containing the elements of the [HashedObserverList].
|
||||||
|
///
|
||||||
|
/// Overrides the default implementation of [Iterable] to reduce number of
|
||||||
|
/// allocations.
|
||||||
|
@override
|
||||||
|
List<T> toList({bool growable = true}) {
|
||||||
|
final Iterator<T> iterator = _map.keys.iterator;
|
||||||
|
return List<T>.generate(
|
||||||
|
_map.length,
|
||||||
|
(_) => (iterator..moveNext()).current,
|
||||||
|
growable: growable,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ void main() {
|
|||||||
log.clear();
|
log.clear();
|
||||||
|
|
||||||
controller.value = 0.4;
|
controller.value = 0.4;
|
||||||
expect(log, <String>['listener2', 'listener4', 'listener4']);
|
expect(log, <String>['listener2', 'listener4']);
|
||||||
log.clear();
|
log.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user