surround frame request hooks with try/catch, and add a check to avoid concurrency exceptions when adding/removing hooks

This commit is contained in:
Nick Fisher
2025-06-04 11:13:15 +08:00
parent cc99905eb8
commit aa2f19442b

View File

@@ -619,6 +619,9 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
/// ///
@override @override
Future registerRequestFrameHook(Future Function() hook) async { Future registerRequestFrameHook(Future Function() hook) async {
while (_requesting) {
await Future.delayed(Duration(milliseconds: 1));
}
if (!_hooks.contains(hook)) { if (!_hooks.contains(hook)) {
_hooks.add(hook); _hooks.add(hook);
} }
@@ -629,20 +632,30 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
/// ///
@override @override
Future unregisterRequestFrameHook(Future Function() hook) async { Future unregisterRequestFrameHook(Future Function() hook) async {
while (_requesting) {
await Future.delayed(Duration(milliseconds: 1));
}
if (_hooks.contains(hook)) { if (_hooks.contains(hook)) {
_hooks.remove(hook); _hooks.remove(hook);
} }
} }
bool _requesting = false;
/// ///
/// ///
/// ///
@override @override
Future requestFrame() async { Future requestFrame() async {
for (final hook in _hooks) { _requesting = true;
await hook.call(); try {
for (final hook in _hooks) {
await hook.call();
}
} catch (err) {
_logger.severe(err);
} }
_requesting = false;
RenderThread_requestFrameAsync(); RenderThread_requestFrameAsync();
} }