use std::sync::{Arc, Mutex, MutexGuard};
use arboard::Clipboard;
use kludgine::app::{AppEvent, AsApplication};
use crate::utils::IgnorePoison;
use crate::window::sealed::WindowCommand;
use crate::window::WindowHandle;
pub struct PendingApp {
app: kludgine::app::PendingApp<WindowCommand>,
cushy: Cushy,
}
impl PendingApp {
pub const fn cushy(&self) -> &Cushy {
&self.cushy
}
}
impl Run for PendingApp {
fn run(self) -> crate::Result {
self.app.run()
}
}
impl Default for PendingApp {
fn default() -> Self {
Self {
app: kludgine::app::PendingApp::default(),
cushy: Cushy {
clipboard: Clipboard::new()
.ok()
.map(|clipboard| Arc::new(Mutex::new(clipboard))),
},
}
}
}
impl AsApplication<AppEvent<WindowCommand>> for PendingApp {
fn as_application(&self) -> &dyn kludgine::app::Application<AppEvent<WindowCommand>> {
self.app.as_application()
}
}
#[derive(Clone)]
pub struct Cushy {
pub(crate) clipboard: Option<Arc<Mutex<Clipboard>>>,
}
impl Cushy {
#[must_use]
pub fn clipboard_guard(&self) -> Option<MutexGuard<'_, Clipboard>> {
self.clipboard
.as_ref()
.map(|mutex| mutex.lock().ignore_poison())
}
}
pub trait Application: AsApplication<AppEvent<WindowCommand>> {
fn cushy(&self) -> &Cushy;
fn as_app(&self) -> App;
}
impl Application for PendingApp {
fn cushy(&self) -> &Cushy {
&self.cushy
}
fn as_app(&self) -> App {
App {
app: self.app.as_app(),
cushy: self.cushy.clone(),
}
}
}
#[derive(Clone)]
pub struct App {
app: kludgine::app::App<WindowCommand>,
cushy: Cushy,
}
impl Application for App {
fn cushy(&self) -> &Cushy {
&self.cushy
}
fn as_app(&self) -> App {
self.clone()
}
}
impl AsApplication<AppEvent<WindowCommand>> for App {
fn as_application(&self) -> &dyn kludgine::app::Application<AppEvent<WindowCommand>> {
self.app.as_application()
}
}
pub trait Run: Sized {
fn run(self) -> crate::Result;
}
pub trait Open: Sized {
fn open<App>(self, app: &App) -> crate::Result<Option<WindowHandle>>
where
App: Application;
fn run_in(self, app: PendingApp) -> crate::Result;
}