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

Expose frame synced event callback #430

Open
asaworld opened this issue Nov 1, 2024 · 2 comments
Open

Expose frame synced event callback #430

asaworld opened this issue Nov 1, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@asaworld
Copy link

asaworld commented Nov 1, 2024

Description

An event listener added using addEventListener is being called from within a paint loop. I have a button in a rive file which triggers an event. I then have code listening to this. It is failing because the event occurs within the paint loop so I cannot setState

Steps To Reproduce

void _onAnimationInit(Artboard artboard) {
StateMachineController controller = StateMachineController.fromArtboard(artboard, "Default", onStateChange: _onAnimationStateChange)!;
artboard.addController(controller);
_controller.addEventListener(_onAnimationEvent);
}

Expected behavior

Event listeners should only be called outside the paint loop

Screenshots

image

Device & Versions (please complete the following information)

  • Device: Android phone
    Flutter 3.24.4 • channel stable • https://github.com/flutter/flutter.git
    Framework • revision 603104015d (8 days ago) • 2024-10-24 08:01:25 -0700
    Engine • revision db49896cf2
    Tools • Dart 3.5.4 • DevTools 2.37.3
@asaworld asaworld added the bug Something isn't working label Nov 1, 2024
@HayesGordon
Copy link
Contributor

Hi @asaworld the documentation mentions that this may occur. It's a trade-off for having the event immediately available, which is desirable in some situations.

The burden to step around this is on you. We could maybe look into exposing a frame sync listener. Here is an example of how to only call setState when ready to step around this for now:

void onRiveEvent(RiveEvent event) {
    // Access custom properties defined on the event
    var rating = event.properties['rating'] as double;
    // Schedule the setState for the next frame, as an event can be
    // triggered during a current frame update
    WidgetsBinding.instance.addPostFrameCallback((_) {
      setState(() {
        ratingValue = 'Rating: $rating';
      });
    });
  }

I'll change the issue name to reflect the needed change we can consider for the future.

@HayesGordon HayesGordon changed the title Event Listener being called in the paint loop Expose frame synced event callback Nov 15, 2024
@HayesGordon HayesGordon added enhancement New feature or request and removed bug Something isn't working labels Nov 15, 2024
@asaworld
Copy link
Author

Thank for the update. This is how I solved it.

I do expect event listeners to be called outside the build loop and that would probably make a far better default. Calling event handlers inside the paint call is asking for inconsistent rendering or controller updates mid paint loop. You could add an immediate callback for those who might possibly want it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants