///|
pub(all) struct WindowRuntimeSlot {
id : @backend_host.WindowId
record : @backend_host.WindowRecord
driver : @runtime.HostRuntimeDriver
}
///|
pub struct WindowRuntimeSlots {
mut slots : Array[WindowRuntimeSlot]
}
///|
pub fn WindowRuntimeSlot::new(
record~ : @backend_host.WindowRecord,
runtime~ : @runtime.AppRuntime,
schedule_redraw~ : () -> Unit,
) -> WindowRuntimeSlot {
{
id: record.id,
record,
driver: @runtime.HostRuntimeDriver::new(runtime~, schedule_redraw~),
}
}
///|
pub fn WindowRuntimeSlot::from_driver(
record~ : @backend_host.WindowRecord,
driver~ : @runtime.HostRuntimeDriver,
) -> WindowRuntimeSlot {
{ id: record.id, record, driver, }
}
///|
pub fn WindowRuntimeSlot::from_resolved_open(
resolved : WindowResolvedOpen,
schedule_redraw~ : () -> Unit,
) -> WindowRuntimeSlot {
WindowRuntimeSlot::new(
record=resolved.record,
runtime=resolved.instance.runtime,
schedule_redraw~,
)
}
///|
pub fn WindowRuntimeSlots::new() -> WindowRuntimeSlots {
{ slots: [], }
}
///|
pub fn WindowRuntimeSlots::count(self : WindowRuntimeSlots) -> Int {
self.slots.length()
}
///|
pub fn WindowRuntimeSlots::is_empty(self : WindowRuntimeSlots) -> Bool {
self.slots.is_empty()
}
///|
pub fn WindowRuntimeSlots::insert(
self : WindowRuntimeSlots,
slot : WindowRuntimeSlot,
) -> Bool {
match self.lookup(slot.id) {
Some(_) => false
None => {
self.slots.push(slot)
true
}
}
}
///|
pub fn WindowRuntimeSlots::insert_from_registry(
self : WindowRuntimeSlots,
registry : WindowRegistry,
id : @backend_host.WindowId,
driver~ : @runtime.HostRuntimeDriver,
) -> Bool {
match registry.lookup(id) {
Some(record) =>
self.insert(WindowRuntimeSlot::from_driver(record~, driver~))
None => false
}
}
///|
pub fn WindowRuntimeSlots::lookup(
self : WindowRuntimeSlots,
id : @backend_host.WindowId,
) -> WindowRuntimeSlot? {
for slot in self.slots {
if slot.id == id {
return Some(slot)
}
}
None
}
///|
pub fn WindowRuntimeSlots::open_slots(
self : WindowRuntimeSlots,
) -> Array[WindowRuntimeSlot] {
self.slots.filter(slot => slot.record.phase != WindowClosed)
}
///|
pub fn WindowRuntimeSlots::primary_slot(
self : WindowRuntimeSlots,
) -> WindowRuntimeSlot? {
for slot in self.open_slots() {
if slot.record.primary {
return Some(slot)
}
}
None
}
///|
pub fn WindowRuntimeSlots::focused_slot(
self : WindowRuntimeSlots,
) -> WindowRuntimeSlot? {
for slot in self.open_slots() {
if slot.record.phase == WindowFocused {
return Some(slot)
}
}
None
}
///|
pub fn WindowRuntimeSlots::sync_record(
self : WindowRuntimeSlots,
record : @backend_host.WindowRecord,
) -> Bool {
let mut changed = false
self.slots = self.slots.map(slot => {
if slot.id == record.id {
changed = true
{ ..slot, record, }
} else {
slot
}
})
changed
}
///|
pub fn WindowRuntimeSlots::sync_from_registry(
self : WindowRuntimeSlots,
registry : WindowRegistry,
id : @backend_host.WindowId,
) -> Bool {
match registry.lookup(id) {
Some(record) => self.sync_record(record)
None => false
}
}
///|
pub fn WindowRuntimeSlots::sync_open_from_registry(
self : WindowRuntimeSlots,
registry : WindowRegistry,
) -> Int {
let mut synced = 0
for record in registry.open_windows() {
if self.sync_record(record) {
synced = synced + 1
}
}
synced
}
///|
pub fn WindowRuntimeSlots::apply_host_event(
self : WindowRuntimeSlots,
registry : WindowRegistry,
id : @backend_host.WindowId,
event : @backend_host.Event,
) -> Bool {
if registry.apply_host_event(id, event) {
ignore(self.sync_open_from_registry(registry))
true
} else {
false
}
}
///|
pub fn WindowRuntimeSlots::apply_request(
self : WindowRuntimeSlots,
registry : WindowRegistry,
request : @backend_host.WindowRequest,
) -> @backend_host.WindowRequestResult {
let result = registry.apply_request(request)
match result {
WindowOpened(_) | WindowUpdated(_) =>
ignore(self.sync_open_from_registry(registry))
WindowRejected(_) => ()
}
result
}
///|
pub fn WindowRuntimeSlots::remove(
self : WindowRuntimeSlots,
id : @backend_host.WindowId,
) -> WindowRuntimeSlot? {
let mut removed = None
let kept = []
for slot in self.slots {
if slot.id == id {
removed = Some(slot)
} else {
kept.push(slot)
}
}
self.slots = kept
removed
}
///|
pub fn WindowRuntimeSlots::remove_closed(self : WindowRuntimeSlots) -> Int {
let before = self.slots.length()
self.slots = self.slots.filter(slot => slot.record.phase != WindowClosed)
before - self.slots.length()
}
///|
pub fn drain_to_runtime_slots(
commands : WindowCommands,
registry : WindowRegistry,
slots : WindowRuntimeSlots,
) -> Array[@backend_host.WindowRequestCompletion] {
let completions = commands.drain_to_registry(registry)
for _ in completions {
ignore(slots.sync_open_from_registry(registry))
}
completions
}