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
|
||||
/// by mixing in another mixin from this library, such as [AnimationLazyListenerMixin].
|
||||
mixin AnimationLocalListenersMixin {
|
||||
final ObserverList<VoidCallback> _listeners = ObserverList<VoidCallback>();
|
||||
final HashedObserverList<VoidCallback> _listeners = HashedObserverList<VoidCallback>();
|
||||
|
||||
/// 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.
|
||||
bool remove(T item) {
|
||||
_isDirty = true;
|
||||
_set.clear(); // Clear the set so that we don't leak items.
|
||||
return _list.remove(item);
|
||||
final bool removed = _list.remove(item);
|
||||
if (removed) {
|
||||
_isDirty = true;
|
||||
_set.clear(); // Clear the set so that we don't leak items.
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
/// Removes all items from the list.
|
||||
/// Removes all items from the [ObserverList].
|
||||
void clear() {
|
||||
_isDirty = false;
|
||||
_list.clear();
|
||||
@ -78,6 +81,10 @@ class ObserverList<T> extends Iterable<T> {
|
||||
@override
|
||||
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
|
||||
List<T> toList({bool growable = true}) {
|
||||
return _list.toList(growable: growable);
|
||||
@ -126,6 +133,9 @@ class HashedObserverList<T> extends Iterable<T> {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Removes all items from the [HashedObserverList].
|
||||
void clear() => _map.clear();
|
||||
|
||||
@override
|
||||
bool contains(Object? element) => _map.containsKey(element);
|
||||
|
||||
@ -137,4 +147,18 @@ class HashedObserverList<T> extends Iterable<T> {
|
||||
|
||||
@override
|
||||
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();
|
||||
|
||||
controller.value = 0.4;
|
||||
expect(log, <String>['listener2', 'listener4', 'listener4']);
|
||||
expect(log, <String>['listener2', 'listener4']);
|
||||
log.clear();
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user