Unverified Commit 680a8192 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[framework] ensure ink sparkle is disposed (#104569)

parent 09987dc0
......@@ -135,7 +135,9 @@ class InkSparkle extends InteractiveInkFeature {
_animationController = AnimationController(
duration: _animationDuration,
vsync: controller.vsync,
)..addListener(controller.markNeedsPaint)..forward();
)..addListener(controller.markNeedsPaint)
..addStatusListener(_handleStatusChanged)
..forward();
_radiusScale = TweenSequence<double>(
<TweenSequenceItem<double>>[
......@@ -209,6 +211,11 @@ class InkSparkle extends InteractiveInkFeature {
_turbulenceSeed = turbulenceSeed ?? math.Random().nextDouble() * 1000.0;
}
void _handleStatusChanged(AnimationStatus status) {
if (status == AnimationStatus.completed)
dispose();
}
static const Duration _animationDuration = Duration(milliseconds: 617);
static const double _targetRadiusMultiplier = 2.3;
static const double _rotateRight = math.pi * 0.0078125;
......@@ -259,6 +266,8 @@ class InkSparkle extends InteractiveInkFeature {
@override
void paintFeature(Canvas canvas, Matrix4 transform) {
assert(_animationController.isAnimating);
// InkSparkle can only paint if its shader has been compiled.
if (_InkSparkleFactory._shaderManager == null) {
// Skipping paintFeature because the shader it relies on is not ready to
......
......@@ -557,6 +557,12 @@ class _RenderInkFeatures extends RenderProxyBox implements MaterialInkController
bool absorbHitTest;
@visibleForTesting
List<InkFeature>? get debugInkFeatures {
if (kDebugMode)
return _inkFeatures;
return null;
}
List<InkFeature>? _inkFeatures;
@override
......
......@@ -48,16 +48,23 @@ void main() {
final Finder buttonFinder = find.text('Sparkle!');
await tester.tap(buttonFinder);
await tester.pump();
await tester.pumpAndSettle();
await tester.pump(const Duration(milliseconds: 200));
final MaterialInkController material = Material.of(tester.element(buttonFinder))!;
await tester.pump(const Duration(milliseconds: 200));
expect(material, paintsExactlyCountTimes(#drawRect, 1));
// ignore: avoid_dynamic_calls
expect((material as dynamic).debugInkFeatures, hasLength(1));
await tester.pumpAndSettle();
// ink feature is disposed.
// ignore: avoid_dynamic_calls
expect((material as dynamic).debugInkFeatures, isEmpty);
},
skip: kIsWeb, // [intended] SPIR-V shaders are not yet supported for web.
);
testWidgets('InkSparkle default splashFactory paints with drawPaint when unbounded', (WidgetTester tester) async {
testWidgets('InkSparkle default splashFactory paints with drawPaint when unbounded', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: Scaffold(
body: Center(
......@@ -72,10 +79,9 @@ void main() {
final Finder buttonFinder = find.text('Sparkle!');
await tester.tap(buttonFinder);
await tester.pump();
await tester.pumpAndSettle();
await tester.pump(const Duration(milliseconds: 200));
final MaterialInkController material = Material.of(tester.element(buttonFinder))!;
await tester.pump(const Duration(milliseconds: 200));
expect(material, paintsExactlyCountTimes(#drawPaint, 1));
},
skip: kIsWeb, // [intended] SPIR-V shaders are not yet supported for web.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment