mirror of
https://github.com/danbulant/appit
synced 2026-06-24 17:11:54 +00:00
Refactored app init
This commit is contained in:
parent
516401f48c
commit
4cab6aedd1
3 changed files with 29 additions and 14 deletions
|
|
@ -1 +0,0 @@
|
||||||
pub struct App {}
|
|
||||||
39
src/lib.rs
39
src/lib.rs
|
|
@ -10,6 +10,7 @@ mod window;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{mpsc, Arc, Mutex, PoisonError};
|
use std::sync::{mpsc, Arc, Mutex, PoisonError};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
|
@ -18,6 +19,7 @@ pub use window::{Run, RunningWindow, Window, WindowAttributes, WindowBehavior, W
|
||||||
pub use winit;
|
pub use winit;
|
||||||
use winit::application::ApplicationHandler;
|
use winit::application::ApplicationHandler;
|
||||||
use winit::error::{EventLoopError, OsError};
|
use winit::error::{EventLoopError, OsError};
|
||||||
|
use winit::event::StartCause;
|
||||||
use winit::event_loop::{
|
use winit::event_loop::{
|
||||||
ActiveEventLoop, ControlFlow, EventLoop, EventLoopProxy, OwnedDisplayHandle,
|
ActiveEventLoop, ControlFlow, EventLoop, EventLoopProxy, OwnedDisplayHandle,
|
||||||
};
|
};
|
||||||
|
|
@ -136,6 +138,7 @@ where
|
||||||
event_loop: EventLoop<EventLoopMessage<AppMessage>>,
|
event_loop: EventLoop<EventLoopMessage<AppMessage>>,
|
||||||
message_callback: BoxedEventCallback<AppMessage>,
|
message_callback: BoxedEventCallback<AppMessage>,
|
||||||
running: App<AppMessage>,
|
running: App<AppMessage>,
|
||||||
|
on_startup: Vec<Box<StartupClosure<AppMessage>>>,
|
||||||
pending_windows: Vec<PendingWindow<AppMessage>>,
|
pending_windows: Vec<PendingWindow<AppMessage>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -186,8 +189,10 @@ where
|
||||||
running: App {
|
running: App {
|
||||||
proxy,
|
proxy,
|
||||||
windows: Windows::default(),
|
windows: Windows::default(),
|
||||||
|
started: Arc::new(AtomicBool::new(false)),
|
||||||
},
|
},
|
||||||
message_callback: Box::new(event_callback),
|
message_callback: Box::new(event_callback),
|
||||||
|
on_startup: Vec::new(),
|
||||||
pending_windows: Vec::new(),
|
pending_windows: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -198,11 +203,11 @@ where
|
||||||
/// available after the event loop has started. For example, to enter an
|
/// available after the event loop has started. For example, to enter an
|
||||||
/// exclusive full screen mode, monitor information must be accessed which
|
/// exclusive full screen mode, monitor information must be accessed which
|
||||||
/// requires the event loop to have been started.
|
/// requires the event loop to have been started.
|
||||||
pub fn on_startup<F>(&self, on_startup: F)
|
pub fn on_startup<F>(&mut self, on_startup: F)
|
||||||
where
|
where
|
||||||
F: FnOnce(ExecutingApp<'_, AppMessage>) + Send + 'static,
|
F: FnOnce(ExecutingApp<'_, AppMessage>) + Send + 'static,
|
||||||
{
|
{
|
||||||
self.running.push_on_startup(Box::new(on_startup));
|
self.on_startup.push(Box::new(on_startup));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Begins running the application.
|
/// Begins running the application.
|
||||||
|
|
@ -218,11 +223,13 @@ where
|
||||||
event_loop,
|
event_loop,
|
||||||
message_callback,
|
message_callback,
|
||||||
running,
|
running,
|
||||||
|
on_startup,
|
||||||
pending_windows,
|
pending_windows,
|
||||||
} = self;
|
} = self;
|
||||||
event_loop.run_app(&mut RunningApp::<AppMessage> {
|
event_loop.run_app(&mut RunningApp::<AppMessage> {
|
||||||
message_callback,
|
message_callback,
|
||||||
running,
|
running,
|
||||||
|
on_startup,
|
||||||
pending_windows,
|
pending_windows,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -234,6 +241,7 @@ where
|
||||||
{
|
{
|
||||||
message_callback: BoxedEventCallback<AppMessage>,
|
message_callback: BoxedEventCallback<AppMessage>,
|
||||||
running: App<AppMessage>,
|
running: App<AppMessage>,
|
||||||
|
on_startup: Vec<Box<StartupClosure<AppMessage>>>,
|
||||||
pending_windows: Vec<PendingWindow<AppMessage>>,
|
pending_windows: Vec<PendingWindow<AppMessage>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -241,8 +249,11 @@ impl<AppMessage> ApplicationHandler<EventLoopMessage<AppMessage>> for RunningApp
|
||||||
where
|
where
|
||||||
AppMessage: Message,
|
AppMessage: Message,
|
||||||
{
|
{
|
||||||
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
|
fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: StartCause) {
|
||||||
event_loop.set_control_flow(ControlFlow::Wait);
|
let StartCause::Init = cause else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
self.running.started.store(true, Ordering::Relaxed);
|
||||||
for PendingWindow {
|
for PendingWindow {
|
||||||
window,
|
window,
|
||||||
sender,
|
sender,
|
||||||
|
|
@ -257,6 +268,13 @@ where
|
||||||
.expect("error spawning initial window");
|
.expect("error spawning initial window");
|
||||||
spawner(window);
|
spawner(window);
|
||||||
}
|
}
|
||||||
|
for on_startup in self.on_startup.drain(..) {
|
||||||
|
on_startup(ExecutingApp::new(&self.running.windows, event_loop));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
|
||||||
|
event_loop.set_control_flow(ControlFlow::Wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn window_event(
|
fn window_event(
|
||||||
|
|
@ -276,9 +294,6 @@ where
|
||||||
|
|
||||||
fn user_event(&mut self, event_loop: &ActiveEventLoop, message: EventLoopMessage<AppMessage>) {
|
fn user_event(&mut self, event_loop: &ActiveEventLoop, message: EventLoopMessage<AppMessage>) {
|
||||||
match message {
|
match message {
|
||||||
EventLoopMessage::Execute(closure) => {
|
|
||||||
closure(ExecutingApp::new(&self.running.windows, event_loop));
|
|
||||||
}
|
|
||||||
EventLoopMessage::CloseWindow(window_id) => {
|
EventLoopMessage::CloseWindow(window_id) => {
|
||||||
if self.running.windows.close(window_id) {
|
if self.running.windows.close(window_id) {
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
@ -323,6 +338,7 @@ where
|
||||||
{
|
{
|
||||||
proxy: EventLoopProxy<EventLoopMessage<AppMessage>>,
|
proxy: EventLoopProxy<EventLoopMessage<AppMessage>>,
|
||||||
windows: Windows<AppMessage::Window>,
|
windows: Windows<AppMessage::Window>,
|
||||||
|
started: Arc<AtomicBool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<AppMessage> App<AppMessage>
|
impl<AppMessage> App<AppMessage>
|
||||||
|
|
@ -336,6 +352,10 @@ where
|
||||||
/// running. Otherwise, this function will block until the result of the
|
/// running. Otherwise, this function will block until the result of the
|
||||||
/// callback has been received.
|
/// callback has been received.
|
||||||
pub fn send(&self, message: AppMessage) -> Option<AppMessage::Response> {
|
pub fn send(&self, message: AppMessage) -> Option<AppMessage::Response> {
|
||||||
|
if !self.started.load(Ordering::Relaxed) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let (response_sender, response_receiver) = mpsc::sync_channel(1);
|
let (response_sender, response_receiver) = mpsc::sync_channel(1);
|
||||||
self.proxy
|
self.proxy
|
||||||
.send_event(EventLoopMessage::User {
|
.send_event(EventLoopMessage::User {
|
||||||
|
|
@ -345,10 +365,6 @@ where
|
||||||
.ok()?;
|
.ok()?;
|
||||||
response_receiver.recv().ok()
|
response_receiver.recv().ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_on_startup(&self, on_startup: Box<StartupClosure<AppMessage>>) {
|
|
||||||
let _ = self.proxy.send_event(EventLoopMessage::Execute(on_startup));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<AppMessage> Clone for App<AppMessage>
|
impl<AppMessage> Clone for App<AppMessage>
|
||||||
|
|
@ -359,6 +375,7 @@ where
|
||||||
Self {
|
Self {
|
||||||
proxy: self.proxy.clone(),
|
proxy: self.proxy.clone(),
|
||||||
windows: self.windows.clone(),
|
windows: self.windows.clone(),
|
||||||
|
started: self.started.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use winit::event_loop::AsyncRequestSerial;
|
||||||
use winit::window::{ActivationToken, Theme, WindowId};
|
use winit::window::{ActivationToken, Theme, WindowId};
|
||||||
|
|
||||||
use crate::window::WindowAttributes;
|
use crate::window::WindowAttributes;
|
||||||
use crate::{Message, StartupClosure};
|
use crate::Message;
|
||||||
|
|
||||||
pub type WindowSpawner = Box<dyn FnOnce(OpenedWindow) + Send + 'static>;
|
pub type WindowSpawner = Box<dyn FnOnce(OpenedWindow) + Send + 'static>;
|
||||||
|
|
||||||
|
|
@ -48,7 +48,6 @@ pub enum EventLoopMessage<AppMessage>
|
||||||
where
|
where
|
||||||
AppMessage: Message,
|
AppMessage: Message,
|
||||||
{
|
{
|
||||||
Execute(Box<StartupClosure<AppMessage>>),
|
|
||||||
OpenWindow {
|
OpenWindow {
|
||||||
attrs: WindowAttributes,
|
attrs: WindowAttributes,
|
||||||
sender: Arc<mpsc::SyncSender<WindowMessage<AppMessage::Window>>>,
|
sender: Arc<mpsc::SyncSender<WindowMessage<AppMessage::Window>>>,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue