use once_cell::sync::Lazy;
use std::sync::RwLock;
pub mod addr;
pub mod cancel;
pub mod ctx;
pub mod envelope;
pub mod flow;
pub mod traits;
pub use addr::*;
pub use cancel::*;
pub use ctx::*;
pub use envelope::*;
pub use traits::*;
pub mod event_bus;
pub mod registry;
pub mod shape;
pub type UiTask = Box<dyn FnOnce() + Send>;
pub trait UiDispatcher: Send + Sync {
fn init(&self);
fn dispatch(&self, task: UiTask);
}
static UI_DISPATCHER: Lazy<RwLock<Option<Box<dyn UiDispatcher>>>> = Lazy::new(|| RwLock::new(None));
pub fn set_ui_dispatcher(dispatcher: impl UiDispatcher + 'static) {
*UI_DISPATCHER.write().unwrap() = Some(Box::new(dispatcher));
}
#[derive(Clone)]
pub struct UiThreadToken(std::marker::PhantomData<*const ()>);
impl UiThreadToken {
pub fn dangerously_create_token_unchecked() -> Self {
Self(std::marker::PhantomData)
}
}
pub fn invoke_on_ui<F>(f: F)
where
F: FnOnce() + Send + 'static,
{
#[cfg(feature = "test-utils")]
{
if let Err(f) = crate::executor::queue_ui(Box::new(f)) {
crate::actor::event_bus::EventBus::queue_test_task(f);
}
}
#[cfg(not(feature = "test-utils"))]
{
if let Some(dispatcher) = UI_DISPATCHER.read().unwrap().as_ref() {
dispatcher.dispatch(Box::new(f));
} else {
panic!(
"UiDispatcher not initialized! Call guinea_core::actor::set_ui_dispatcher at startup."
);
}
}
}
pub fn try_invoke_on_ui<F>(f: F) -> Result<(), F>
where
F: FnOnce() + Send + 'static,
{
#[cfg(feature = "test-utils")]
{
if let Err(f) = crate::executor::queue_ui(Box::new(f)) {
crate::actor::event_bus::EventBus::queue_test_task(f);
}
Ok(())
}
#[cfg(not(feature = "test-utils"))]
{
match UI_DISPATCHER.read().unwrap().as_ref() {
Some(dispatcher) => {
dispatcher.dispatch(Box::new(f));
Ok(())
}
None => Err(f),
}
}
}
pub fn short_type_name<T: ?Sized>() -> &'static str {
let full = std::any::type_name::<T>();
let raw = full.split('<').next().unwrap_or(full);
let mut parts = raw.rsplitn(3, "::");
let raw = match (parts.next(), parts.next()) {
(Some(name), Some(ns)) => {
let ns_start = raw.len() - ns.len() - name.len() - "::".len();
&raw[ns_start..]
}
(Some(name), None) => name,
_ => raw,
};
raw.trim_end_matches('>')
}