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

Rive texts error with font: LateInitializationError: Field '_makeFont' has not been initialized #370

Open
marchacio opened this issue Mar 20, 2024 · 8 comments
Labels
bug Something isn't working

Comments

@marchacio
Copy link

marchacio commented Mar 20, 2024

Hi everyone.
I created a file on Rive that uses Texts using the "Inter" style.

In my flutter app I use a manually imported font in the pubspec.yaml file called "ProductSans" which is not present in google fonts, so I didn't import the google_fonts package into my app.

The problem arises when I run animation in my app;
During the screen building phase this error is caused: Error: LateInitializationError: Field '_makeFont' has not been initialized.

@marchacio marchacio added the bug Something isn't working label Mar 20, 2024
@marchacio
Copy link
Author

This is my debug:

Error: LateInitializationError: Field '_makeFont' has not been initialized.
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 297:3  throw_
packages/rive_common/src/rive_text_wasm.dart 15:20                           get _makeFont
packages/rive_common/src/rive_text_wasm.dart 647:23                          decodeFont
packages/rive_common/rive_text.dart 478:12                                   decode
packages/rive/src/rive_core/assets/font_asset.dart 63:17                     parseBytes
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54           runBody
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 127:5           _async
packages/rive/src/rive_core/assets/font_asset.dart 62:34                     parseBytes
packages/rive/src/rive_core/assets/font_asset.dart 59:18                     decode
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54           runBody
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 127:5           _async
packages/rive/src/rive_core/assets/font_asset.dart 58:22                     decode
packages/rive/src/core/importers/file_asset_importer.dart 32:9               <fn>
dart-sdk/lib/async/zone.dart 1661:54                                         runUnary
dart-sdk/lib/async/future_impl.dart 162:18                                   handleValue
dart-sdk/lib/async/future_impl.dart 838:44                                   handleValueCallback
dart-sdk/lib/async/future_impl.dart 867:13                                   _propagateToListeners
dart-sdk/lib/async/future_impl.dart 643:5                                    [_completeWithValue]
dart-sdk/lib/async/future_impl.dart 713:7                                    callback
dart-sdk/lib/async/schedule_microtask.dart 40:11                             _microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5                              _startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:7           <fn>

@marchacio
Copy link
Author

marchacio commented Mar 20, 2024

Update

the problem arises ONLY when the Rive.assets(...) widget (containing the text) is built immediately after the initstate.

Some examples:

  • if the Rive.asset(...) containing the text is the first image you see when you access the app, the error is thrown.
  • If the Rive.asset(...) containing the text is NOT shown immediately in the first screen but you have to, for example, scroll a ListView before seeing it, then no exception arises.

Bypass

I got around the problem by modifying my UI and inserting the animation with the text later in a ListView, but this is a very limiting problem.

@jezell
Copy link

jezell commented Mar 21, 2024

Same issue here

@jezell
Copy link

jezell commented Mar 21, 2024

@marchacio

HACK wrapper, add asset blank.riv with transparent BG and text, then wrap your animation in this dumb component:

class _RiveLoader extends StatefulWidget {
  const _RiveLoader({required this.child});
  final Widget child;

  @override
  State createState() => _RiveLoaderState();
}

class _RiveLoaderState extends State<_RiveLoader> {
  static bool initialized = false;

  bool init = initialized;

  @override
  void initState() {
    super.initState();
    tryLoad();
  }

  void tryLoad() async {
    try {
      await rive.FontAsset.parseBytes(Uint8List.fromList([]));
    } catch (e) {
      final message = e.toString();
      print(message);
      if (message.contains("LateInitializationError")) {
        await Future.delayed(const Duration(milliseconds: 100), () {
          tryLoad();
        });
      } else {
        setState(() {
          initialized = true;
          init = true;
        });
      }
    }
    setState(() {
      init = true;
      initialized = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (init) {
      return widget.child;
    }
    return const Center(child: rive.RiveAnimation.asset("rive/blank.riv"));
  }
}

@marchacio
Copy link
Author

marchacio commented Mar 21, 2024

@marchacio

HACK wrapper, add asset blank.riv with transparent BG and text, then wrap your animation in this dumb component:

class _RiveLoader extends StatefulWidget {
  const _RiveLoader({required this.child});
  final Widget child;

  @override
  State createState() => _RiveLoaderState();
}

class _RiveLoaderState extends State<_RiveLoader> {
  static bool initialized = false;

  bool init = initialized;

  @override
  void initState() {
    super.initState();
    tryLoad();
  }

  void tryLoad() async {
    try {
      await rive.FontAsset.parseBytes(Uint8List.fromList([]));
    } catch (e) {
      final message = e.toString();
      print(message);
      if (message.contains("LateInitializationError")) {
        await Future.delayed(const Duration(milliseconds: 100), () {
          tryLoad();
        });
      } else {
        setState(() {
          initialized = true;
          init = true;
        });
      }
    }
    setState(() {
      init = true;
      initialized = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (init) {
      return widget.child;
    }
    return const Center(child: rive.RiveAnimation.asset("rive/blank.riv"));
  }
}

@jezell
Not working.
Can you explain better please?

@jezell
Copy link

jezell commented Mar 21, 2024

@jezell did you add a blank asset with text in there (and also in your pubspec.yaml) to load and put your animation as the child? If you don't have text in the blank asset it won't work properly. The component just forces it to load the dummy asset to warm up the wasm module, then as soon as it stops failing to be able to parse fonts it will render the child. It will throw the error once inside that component, but it should continue on and render the child when it's ready so it doesn't attempt to play the child before fonts are ready to be rendered.

I should probably just put together a pull request to fix the bug. Looks like what's happening is the component kicks off some portions before the WASM module is initialized if the first thing you try to play is an animation with text in it.

@HayesGordon
Copy link
Contributor

Hi all, could you try calling await RiveFile.initializeText() before showing any Rive content.

This should only be needed if you're manually parsing the Rive file or using RiveFile.import. The initialization of the text engine is encapsulated in RiveFile.asset, RiveFile.file, and RiveFile.network. Which I recommend using.

If you're still running into issues please share a reproducible example with you .riv file and the code used for us to investigate. Also be sure to use the latest versions of the runtime.

@jezell
Copy link

jezell commented Mar 29, 2024

@HayesGordon seems to work here, but seems like if using RiveAnimation.network like we were it should also handle the initialization of the text engine before it displays the file. Extra step is confusing.

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

No branches or pull requests

3 participants