use std::sync::Arc;
use std::thread;
use crate::{
compat::{self, mpsc},
private, service, Error, Tray,
};
pub trait TrayMethods: Tray + private::Sealed {
fn spawn(self) -> Result<Handle<Self>, Error> {
self.spawn_with_name(true)
}
fn spawn_without_dbus_name(self) -> Result<Handle<Self>, Error> {
self.spawn_with_name(false)
}
#[doc(hidden)]
fn spawn_with_name(self, own_name: bool) -> Result<Handle<Self>, Error> {
let (handle_tx, handle_rx) = mpsc::unbounded_channel();
let service = service::Service::new(self);
let service_loop = compat::block_on(service::run(service.clone(), handle_rx, own_name))?;
thread::spawn(move || {
compat::block_on(service_loop);
});
Ok(Handle(crate::Handle {
service: Arc::downgrade(&service),
sender: handle_tx,
}))
}
}
impl<T: Tray> TrayMethods for T {}
pub struct Handle<T>(crate::Handle<T>);
impl<T> Handle<T> {
pub fn update<R, F: FnOnce(&mut T) -> R>(&self, f: F) -> Option<R> {
compat::block_on(self.0.update(f))
}
pub fn shutdown(&self) -> ShutdownAwaiter {
ShutdownAwaiter(self.0.shutdown())
}
pub fn is_closed(&self) -> bool {
self.0.is_closed()
}
}
pub struct ShutdownAwaiter(crate::ShutdownAwaiter);
impl ShutdownAwaiter {
pub fn wait(self) {
compat::block_on(self.0)
}
}
impl<T> Clone for Handle<T> {
fn clone(&self) -> Self {
Handle(self.0.clone())
}
}