initRuntimeLogging static method
- SynheartCoreFFI? ffi,
- String? envFilter,
- void onLine(
- String line
- bool preferBuffered = true,
Initialize Runtime tracing once per process (call before create if you
need a custom filter or sink). See the book: book/src/abi/logging.md.
Prefers buffered (pull-based) mode: the runtime formats lines into an
internal ring buffer and this bridge polls them on a Timer.periodic, so
no function pointer crosses FFI. This is the fix for the Flutter
hot-restart crash (Callback invoked after it has been deleted) — the
dying isolate can't invalidate a pointer the runtime never held.
Falls back to the legacy push-callback path automatically when the running runtime is too old to export the buffered symbols, so a lagging vendored native lib still logs (it just keeps the old crash exposure on hot restart until the lib is updated).
onLine receives each decoded line in either mode. Returns 0 on
success, 1 if already initialized, negative on failure.
Implementation
static int initRuntimeLogging({
SynheartCoreFFI? ffi,
String? envFilter,
void Function(String line)? onLine,
bool preferBuffered = true,
}) {
if (_loggingInstalled) return 1;
final lib = ffi ?? SynheartCoreFFI.load();
if (lib == null) return -2;
if (preferBuffered) {
final rc = _initRuntimeLoggingBuffered(lib, envFilter, onLine);
// null => buffered symbols unavailable on this runtime; fall through.
if (rc != null) return rc;
if (kDebugMode) {
debugPrint(
'[synheart] buffered logging unavailable on this runtime; '
'falling back to callback mode (hot-restart crash exposure remains)',
);
}
}
return _initRuntimeLoggingCallback(lib, envFilter, onLine);
}