Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RiveRenderBox stopwatch keeps on going when in Visibility /w maintainState. Breaks when using reset #328

Closed
Snowcrash5 opened this issue Jun 24, 2023 · 2 comments
Labels
bug Something isn't working triage

Comments

@Snowcrash5
Copy link

Description

Hi, we are using RiveAnimation in a widget where it is wrapped within a Visibility widget. This widget has maintainState=true.
In our usecase, when the widget becomes visible again - the animation is sometimes reset using SimpleAnimation.reset().

The problem is, that when maintainState is true, RiveRenderBox._stopwatch keeps going, and starts calling advance() when the widget becomes visible again. If the widget was invisible for 3 seconds, then advance() will be called with 3 seconds.

So, since we called reset(), we expect the time be at 0, but suddenly we are at 3 seconds, because of the advance() that was called.
This either forces us to use a Visibility widget with maintainState=false, or wait for the next frame and reduce the few seconds that were added (forcing us to count them...) - neither are good solutions.

The RiveRenderBox stopwatch keeps going because render box detach() is not called when maintainState is true, and paint is not called either because visibility is false, leading to a huge advance() call when the widget becomes visible again.

There should be either a way to reset this timer, or stop it while maintaining state.
Thanks!

Steps To Reproduce

  1. Wrap RiveAnimation widget with Visibility widget that has maintainState=true. Use a SimpleAnimation controller.
  2. Set visiblity as false.
  3. Wait a few seconds.
  4. Set visibility as true and call reset() on the Rive controller. (Happens also with microtask, no difference).
  5. Animation playback position will now be at the amount of seconds widget was invisible.

Expected behavior

Rive animation time being at 0 when reset() is called

Flutter 3.10.4 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 682aa387cf (3 weeks ago) • 2023-06-05 18:04:56 -0500
Engine • revision 2a3401c9bb
Tools • Dart 3.0.3 • DevTools 2.23.1
@Snowcrash5 Snowcrash5 added the bug Something isn't working label Jun 24, 2023
@Snowcrash5
Copy link
Author

Hi,

  1. I just found out that under a Visibility widget with maintainState=false, each time visibility becomes false and then true, it seems that a RuntimeArtboard is leaking, according to the profiler. When it happens many times, RAM usage gets too high and app crashes. This does not happen with maintainState=true. Does this warrant a seperate issue?

  2. For the time being, I have bypassed this by extending SimpleAnimation and ignoring the big 'tick'

class BypassRiveSimpleAnimation extends SimpleAnimation {
  BypassRiveSimpleAnimation (super.animationName);

  @override
  void apply(RuntimeArtboard artboard, double elapsedSeconds) {
    // Ignore pauses longer than 0.5 seconds. This to fix
    // apply being called with the time item was hidden.
    // This means when stopping and playing will not work properly if under than 0.5  seconds delay

    if (elapsedSeconds >= 0.5) {
      return;
    }

    super.apply(artboard, elapsedSeconds);
  }
}

This works fine, though if stopping and starting in under 0.5 seconds, same problem will occur.

@HayesGordon
Copy link
Contributor

Hi @Snowcrash5, this should be resolved in v0.11.14

Thanks for reporting the issue. Closing this but please reopen if the issue still persists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working triage
Projects
None yet
Development

No branches or pull requests

2 participants