///|
fn RuntimeEventPump::RuntimeEventPump(
runtime : @native.Runtime,
dialog_completions : DialogCompletionStore,
cookie_completions : CookieCompletionStore,
) -> RuntimeEventPump {
RuntimeEventPump::{
runtime,
dialog_completions,
cookie_completions,
session_events: [],
}
}
///|
/// Pulls every currently available native event into its single MoonBit owner.
/// Dialog completions wake their registered waiter; all other events remain
/// queued for the runtime session.
fn RuntimeEventPump::poll_native_events(
self : RuntimeEventPump,
) -> Bool raise AppRunError {
let mut did_work = false
let mut polling = true
while polling {
let event = self.runtime.poll_event() catch {
error => raise native_run_error("poll event", error)
}
match event {
None => polling = false
Some(event) => {
did_work = true
if !self.dialog_completions.route_completion(event.dialog_completion()) &&
!self.cookie_completions.route_completion(
event.cookie_get_completion(),
) {
self.session_events.push(event)
}
}
}
}
did_work
}
///|
/// Dispatches queued non-dialog events without allowing another component to
/// consume the native queue. The inbox is cleared only after the whole batch
/// dispatches successfully.
fn RuntimeEventPump::drain_session_events(
self : RuntimeEventPump,
dispatch : (@native.RuntimeEvent) -> Unit raise AppRunError,
) -> Bool raise AppRunError {
let did_work = self.poll_native_events()
guard !self.session_events.is_empty() else { return did_work }
let queued = self.session_events.copy()
for event in queued {
dispatch(event)
}
self.session_events.clear()
true
}