///|
pub struct LaunchPlan {
root : Cell
windows : Array[WindowConfig]
plugins : Array[Plugin]
capabilities : Array[Capability]
startup : Cmd
lifecycle_hooks : Array[LifecycleHook]
} derive(Debug, Eq)
///|
pub fn LaunchPlan::window_count(self : LaunchPlan) -> Int {
self.windows.length()
}
///|
pub fn LaunchPlan::windows(self : LaunchPlan) -> Array[WindowConfig] {
self.windows.copy()
}
///|
pub fn LaunchPlan::plugin_count(self : LaunchPlan) -> Int {
self.plugins.length()
}
///|
pub fn LaunchPlan::plugins(self : LaunchPlan) -> Array[Plugin] {
self.plugins.copy()
}
///|
pub fn LaunchPlan::capability_count(self : LaunchPlan) -> Int {
self.capabilities.length()
}
///|
pub fn LaunchPlan::capabilities(self : LaunchPlan) -> Array[Capability] {
self.capabilities.copy()
}
///|
pub fn LaunchPlan::command_routes(self : LaunchPlan) -> Array[String] {
let routes : Array[String] = []
for plugin in self.plugins {
for route in plugin.command_routes() {
routes.push(route)
}
}
routes
}
///|
pub fn LaunchPlan::startup(self : LaunchPlan) -> Cmd {
self.startup
}
///|
pub fn LaunchPlan::lifecycle_hooks(self : LaunchPlan) -> Array[LifecycleHook] {
self.lifecycle_hooks.copy()
}
///|
pub struct App {
root : Cell
windows : Array[WindowConfig]
plugins : Array[Plugin]
capabilities : Array[Capability]
startup : Cmd
lifecycle_hooks : Array[LifecycleHook]
} derive(Debug, Eq)
///|
pub fn new(root : Cell) -> App {
{
root,
windows: [],
plugins: [],
capabilities: [],
startup: None,
lifecycle_hooks: [],
}
}
///|
pub fn App::with_window(self : App, window : WindowConfig) -> App {
let windows = self.windows.copy()
windows.push(window)
{ ..self, windows, }
}
///|
pub fn App::window(
self : App,
label? : String = "main",
title? : String = "Lepusa",
width? : Int = 1000,
height? : Int = 720,
resizable? : Bool = true,
title_bar? : TitleBarStyle = Native,
source? : Source,
) -> App {
self.with_window(
WindowConfig::new(
label~,
title~,
width~,
height~,
resizable~,
title_bar~,
source?,
),
)
}
///|
pub fn App::with_plugin(self : App, plugin : Plugin) -> App {
let plugins = self.plugins.copy()
plugins.push(plugin)
{ ..self, plugins, }
}
///|
pub fn App::with_capability(self : App, capability : Capability) -> App {
let capabilities = self.capabilities.copy()
capabilities.push(capability)
{ ..self, capabilities, }
}
///|
pub fn App::with_startup(self : App, startup : Cmd) -> App {
{ ..self, startup, }
}
///|
pub fn App::with_lifecycle(
self : App,
event : LifecycleEvent,
command : Cmd,
) -> App {
let lifecycle_hooks = self.lifecycle_hooks.copy()
lifecycle_hooks.push(LifecycleHook::new(event, command))
{ ..self, lifecycle_hooks, }
}
///|
pub fn App::on_shutdown(self : App, command : Cmd) -> App {
self.with_lifecycle(AppWillExit, command)
}
///|
pub fn App::on_window_close_requested(
self : App,
label : String,
command : Cmd,
) -> App {
self.with_lifecycle(WindowCloseRequested(label), command)
}
///|
pub fn App::on_window_closed(self : App, label : String, command : Cmd) -> App {
self.with_lifecycle(WindowClosed(label), command)
}
///|
pub fn App::validate(self : App) -> Array[String] {
let problems : Array[String] = []
if self.windows.is_empty() {
problems.push("at least one window is required")
}
let windows = self.materialized_windows()
let labels : Array[String] = []
for window in windows {
for problem in window.validate_for_app() {
problems.push(problem)
}
let label = window.label()
if label != "" && labels.contains(label) {
problems.push("window label must be unique: \{label}")
} else {
labels.push(label)
}
}
for plugin in self.plugins {
for problem in plugin.validate() {
problems.push(problem)
}
}
self.validate_plugin_routes(problems)
for capability in self.capabilities {
for problem in capability.validate() {
problems.push(problem)
}
}
for hook in self.materialized_lifecycle_hooks() {
for problem in hook.event().validate(windows, plugins=self.plugins) {
problems.push(problem)
}
}
problems
}
///|
fn App::validate_plugin_routes(self : App, problems : Array[String]) -> Unit {
let plugin_names : Array[String] = []
let command_routes : Array[String] = []
for plugin in self.plugins {
let name = plugin.name()
if name != "" && plugin_names.contains(name) {
problems.push("plugin name must be unique: \{name}")
} else {
plugin_names.push(name)
}
for route in plugin.command_routes() {
if route != "." && command_routes.contains(route) {
problems.push("plugin command route must be unique: \{route}")
} else {
command_routes.push(route)
}
}
}
}
///|
pub fn App::launch_plan(self : App) -> Result[LaunchPlan, Array[String]] {
let problems = self.validate()
if problems.is_empty() {
Ok({
root: self.root,
windows: self.materialized_windows(),
plugins: self.plugins.copy(),
capabilities: self.capabilities.copy(),
startup: self.startup,
lifecycle_hooks: self.materialized_lifecycle_hooks(),
})
} else {
Err(problems)
}
}
///|
fn App::materialized_windows(self : App) -> Array[WindowConfig] {
let windows : Array[WindowConfig] = []
for window in self.windows {
windows.push(window.with_default_source(self.root))
}
windows
}
///|
fn App::materialized_lifecycle_hooks(self : App) -> Array[LifecycleHook] {
let hooks = self.lifecycle_hooks.copy()
for plugin in self.plugins {
for hook in plugin.lifecycle_hooks() {
hooks.push(hook)
}
}
hooks
}