#![doc(html_logo_url = "https://relm4.org/icons/relm4_logo.svg")]
#![doc(html_favicon_url = "https://relm4.org/icons/relm4_org.svg")]
#![warn(
missing_debug_implementations,
missing_docs,
rust_2018_idioms,
unreachable_pub,
unused_qualifications,
clippy::cargo,
clippy::must_use_candidate,
clippy::used_underscore_binding
)]
#![allow(clippy::multiple_crate_versions)]
#![cfg_attr(docsrs, feature(doc_cfg))]
mod app;
mod channel;
mod extensions;
pub(crate) mod late_initialization;
mod runtime_util;
pub mod abstractions;
pub mod actions;
pub mod binding;
pub mod component;
pub mod factory;
pub mod loading_widgets;
pub mod shared_state;
pub mod typed_view;
pub use channel::ComponentSender;
pub use channel::*;
pub use component::worker::{Worker, WorkerController, WorkerHandle};
pub use component::{
Component, ComponentBuilder, ComponentController, ComponentParts, Controller, MessageBroker,
SimpleComponent,
};
pub use extensions::*;
pub use shared_state::{Reducer, Reducible, SharedState};
pub use shutdown::ShutdownReceiver;
pub use app::RelmApp;
pub use tokio::task::JoinHandle;
use gtk::prelude::{Cast, IsA};
use once_cell::sync::{Lazy, OnceCell};
use runtime_util::{GuardedReceiver, RuntimeSenders, ShutdownOnDrop};
use std::cell::Cell;
use std::future::Future;
use tokio::runtime::Runtime;
pub static RELM_THREADS: OnceCell<usize> = OnceCell::new();
pub static RELM_BLOCKING_THREADS: OnceCell<usize> = OnceCell::new();
pub mod prelude;
pub use gtk;
#[cfg(feature = "macros")]
#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
pub use relm4_macros::*;
#[cfg(feature = "libadwaita")]
#[cfg_attr(docsrs, doc(cfg(feature = "libadwaita")))]
pub use adw;
#[cfg(feature = "libpanel")]
#[cfg_attr(docsrs, doc(cfg(feature = "libpanel")))]
pub use panel;
pub use once_cell;
pub use tokio;
thread_local! {
static MAIN_APPLICATION: Cell<Option<gtk::Application>> = Cell::default();
}
fn set_main_application(app: impl IsA<gtk::Application>) {
MAIN_APPLICATION.with(move |cell| cell.set(Some(app.upcast())));
}
fn init() {
gtk::init().unwrap();
#[cfg(feature = "libadwaita")]
adw::init().unwrap();
}
#[must_use]
pub fn main_application() -> gtk::Application {
#[cfg(feature = "libadwaita")]
fn new_application() -> gtk::Application {
adw::Application::default().upcast()
}
#[cfg(not(feature = "libadwaita"))]
fn new_application() -> gtk::Application {
gtk::Application::default()
}
MAIN_APPLICATION.with(|cell| {
let app = cell.take().unwrap_or_else(new_application);
cell.set(Some(app.clone()));
app
})
}
#[cfg(feature = "libadwaita")]
#[cfg_attr(docsrs, doc(cfg(feature = "libadwaita")))]
#[must_use]
pub fn main_adw_application() -> adw::Application {
main_application().downcast().unwrap()
}
pub fn spawn_local<F, Out>(func: F) -> gtk::glib::JoinHandle<Out>
where
F: Future<Output = Out> + 'static,
Out: 'static,
{
gtk::glib::MainContext::ref_thread_default().spawn_local(func)
}
pub fn spawn_local_with_priority<F, Out>(
priority: gtk::glib::Priority,
func: F,
) -> gtk::glib::JoinHandle<Out>
where
F: Future<Output = Out> + 'static,
Out: 'static,
{
gtk::glib::MainContext::ref_thread_default().spawn_local_with_priority(priority, func)
}
static RUNTIME: Lazy<Runtime> = Lazy::new(|| {
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.worker_threads(*RELM_THREADS.get_or_init(|| 1))
.max_blocking_threads(*RELM_BLOCKING_THREADS.get_or_init(|| 512))
.build()
.unwrap()
});
pub fn spawn<F>(future: F) -> JoinHandle<F::Output>
where
F: Future + Send + 'static,
F::Output: Send + 'static,
{
RUNTIME.spawn(future)
}
pub fn spawn_blocking<F, R>(func: F) -> JoinHandle<R>
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
RUNTIME.spawn_blocking(func)
}