///|
priv struct HostWindowCompletionHandler {
token : Int
handle : (@backend_host.WindowRequestCompletion) -> Unit
}
///|
pub struct WindowRequestQueue {
mut requests : Array[@backend_host.WindowRequest]
mut completed : Array[@backend_host.WindowRequestCompletion]
priv mut next_completion_handler : Int
priv mut completion_handlers : Array[HostWindowCompletionHandler]
}
///|
pub fn WindowRequestQueue::new() -> WindowRequestQueue {
{
requests: [],
completed: [],
next_completion_handler: 1,
completion_handlers: [],
}
}
///|
/// Erase queue storage behind the root backend request protocol.
pub fn WindowRequestQueue::requests(
self : WindowRequestQueue,
) -> @backend_host.WindowRequests {
@backend_host.WindowRequests::new(
push=request => self.push(request),
pending_count=() => self.pending_count(),
completed_count=() => self.completed_count(),
drain=() => self.drain(),
record_result=fn(request, result) { self.record_result(request, result) },
subscribe_completed=handle => self.subscribe_completed(handle),
)
}
///|
pub fn WindowRequestQueue::pending_count(self : WindowRequestQueue) -> Int {
self.requests.length()
}
///|
pub fn WindowRequestQueue::completed_count(self : WindowRequestQueue) -> Int {
self.completed.length()
}
///|
pub fn WindowRequestQueue::is_empty(self : WindowRequestQueue) -> Bool {
self.requests.is_empty()
}
///|
pub fn WindowRequestQueue::push(
self : WindowRequestQueue,
request : @backend_host.WindowRequest,
) -> Unit {
self.requests.push(request)
}
///|
pub fn WindowRequestQueue::open_window(
self : WindowRequestQueue,
title~ : String,
scene? : @backend_host.WindowScene = @backend_host.WindowScene::main(),
metrics~ : @core.SurfaceMetrics,
primary? : Bool = false,
) -> Unit {
self.push(
OpenWindow(
@backend_host.WindowOpenRequest::new(title~, scene~, metrics~, primary~),
),
)
}
///|
pub fn WindowRequestQueue::focus_window(
self : WindowRequestQueue,
id : @backend_host.WindowId,
) -> Unit {
self.push(FocusWindow(id))
}
///|
pub fn WindowRequestQueue::close_window(
self : WindowRequestQueue,
id : @backend_host.WindowId,
) -> Unit {
self.push(CloseWindow(id))
}
///|
pub fn WindowRequestQueue::resize_window(
self : WindowRequestQueue,
id : @backend_host.WindowId,
metrics : @core.SurfaceMetrics,
) -> Unit {
self.push(ResizeWindow(id, metrics))
}
///|
pub fn WindowRequestQueue::minimize_window(
self : WindowRequestQueue,
id : @backend_host.WindowId,
) -> Unit {
self.push(MinimizeWindow(id))
}
///|
pub fn WindowRequestQueue::show_window(
self : WindowRequestQueue,
id : @backend_host.WindowId,
) -> Unit {
self.push(ShowWindow(id))
}
///|
pub fn WindowRequestQueue::set_primary_window(
self : WindowRequestQueue,
id : @backend_host.WindowId,
) -> Unit {
self.push(SetPrimaryWindow(id))
}
///|
pub fn WindowRequestQueue::drain(
self : WindowRequestQueue,
) -> Array[@backend_host.WindowRequest] {
let requests = self.requests
self.requests = []
requests
}
///|
pub fn WindowRequestQueue::record_result(
self : WindowRequestQueue,
request : @backend_host.WindowRequest,
result : @backend_host.WindowRequestResult,
) -> Unit {
self.record_completion({ request, result, })
}
///|
/// Observe request completions without consuming the diagnostic completion
/// queue. The returned callback removes the observer.
pub fn WindowRequestQueue::subscribe_completed(
self : WindowRequestQueue,
handle : (@backend_host.WindowRequestCompletion) -> Unit,
) -> () -> Unit {
let token = self.next_completion_handler
self.next_completion_handler = token + 1
self.completion_handlers.push({ token, handle, })
() => ignore(self.remove_completion_handler(token))
}
///|
pub fn WindowRequestQueue::drain_with_handler(
self : WindowRequestQueue,
handle : (@backend_host.WindowRequest) -> @backend_host.WindowRequestResult,
) -> Array[@backend_host.WindowRequestCompletion] {
let completions = []
for request in self.drain() {
let result = handle(request)
let completion = @backend_host.WindowRequestCompletion::{ request, result, }
self.record_completion(completion)
completions.push(completion)
}
completions
}
///|
pub fn WindowRequestQueue::drain_completed(
self : WindowRequestQueue,
) -> Array[@backend_host.WindowRequestCompletion] {
let completed = self.completed
self.completed = []
completed
}
///|
fn WindowRequestQueue::record_completion(
self : WindowRequestQueue,
completion : @backend_host.WindowRequestCompletion,
) -> Unit {
self.completed.push(completion)
for handler in self.completion_handlers.copy() {
(handler.handle)(completion)
}
}
///|
fn WindowRequestQueue::remove_completion_handler(
self : WindowRequestQueue,
token : Int,
) -> Bool {
let remaining = []
let mut removed = false
for handler in self.completion_handlers {
if handler.token == token {
removed = true
} else {
remaining.push(handler)
}
}
self.completion_handlers = remaining
removed
}