///|
fn AppLifecycle::new() -> AppLifecycle {
AppLifecycle::{ state: Constructing }
}
///|
fn AppLifecycle::begin_starting(self : AppLifecycle) -> Unit {
match self.state {
Constructing => self.state = Starting
_ => abort("invalid application lifecycle transition to Starting")
}
}
///|
fn AppLifecycle::begin_running(self : AppLifecycle) -> Unit {
match self.state {
Starting => self.state = Running
_ => abort("invalid application lifecycle transition to Running")
}
}
///|
fn AppLifecycle::observe_window_closed(self : AppLifecycle) -> Unit {
self.begin_closing()
}
///|
fn AppLifecycle::begin_closing(self : AppLifecycle) -> Unit {
match self.state {
Constructing | Starting | Running => self.state = Closing
Closing | Draining | Destroying | Closed => ()
}
}
///|
fn AppLifecycle::begin_draining(self : AppLifecycle) -> Unit {
self.begin_closing()
match self.state {
Closing => self.state = Draining
Draining | Destroying | Closed => ()
_ => abort("invalid application lifecycle transition to Draining")
}
}
///|
fn AppLifecycle::begin_destroying(self : AppLifecycle) -> Unit {
self.begin_draining()
match self.state {
Draining => self.state = Destroying
Destroying | Closed => ()
_ => abort("invalid application lifecycle transition to Destroying")
}
}
///|
fn AppLifecycle::finish(self : AppLifecycle) -> Unit {
match self.state {
Destroying => self.state = Closed
Closed => ()
_ => abort("invalid application lifecycle transition to Closed")
}
}
///|
fn app_cleanup(
lifecycle : AppLifecycle,
runtime : @native.Runtime,
windows : Array[RunningWindow],
command_host : CommandHostRuntime?,
lifecycle_failures? : Array[AppCleanupError] = [],
) -> Array[AppCleanupError] {
lifecycle.begin_draining()
let failures = lifecycle_failures.copy()
for error in close_command_host(command_host) {
failures.push(CommandExtension(error))
}
lifecycle.begin_destroying()
for running in windows {
running.window.destroy() catch {
error => failures.push(WindowDestroy(error))
}
}
let failure_count = failures.length()
runtime.destroy() catch {
error => failures.push(RuntimeDestroy(error))
}
if failures.length() == failure_count {
lifecycle.finish()
}
failures
}
///|
fn cleanup_run_error(
primary : AppRunError?,
failures : Array[AppCleanupError],
) -> AppRunError? {
if failures.length() == 0 {
return primary
}
Some(
CleanupFailed(
primary=match primary {
Some(error) => Some(error.message())
None => None
},
failures~,
),
)
}