use anyhow::Result;
use gpui_authoring::{
App, AppCell, AssetSource, AsyncApp, BackgroundExecutor, ForegroundExecutor, FramePipeline,
GpuPreference, LayoutEngine, Platform, QuitMode, TextSystem, WindowId, WindowingRequest,
http_client::HttpClient,
};
use std::{ffi::OsString, path::PathBuf, rc::Rc, sync::Arc};
pub struct Application(Rc<AppCell>);
pub struct ApplicationHandle {
app: Rc<AppCell>,
}
impl ApplicationHandle {
pub fn update<R>(&self, f: impl FnOnce(&mut App) -> R) -> R {
let cx = &mut *self.app.borrow_mut();
f(cx)
}
pub fn to_async(&self) -> AsyncApp {
self.update(|cx| cx.to_async())
}
}
impl Application {
pub fn with_platform(platform: Rc<dyn Platform>) -> Self {
Self(App::new_app_for_platform(platform))
}
pub fn new_inaccessible(platform: Rc<dyn Platform>) -> Self {
let this = Self::with_platform(platform);
this.0.borrow_mut().set_accessibility_force_disabled(true);
this
}
pub fn with_assets(self, asset_source: impl AssetSource) -> Self {
self.0.borrow_mut().set_asset_source(Arc::new(asset_source));
self
}
pub fn with_restart_arguments(self, arguments: Vec<OsString>) -> Self {
self.0.borrow_mut().set_restart_arguments(arguments);
self
}
pub fn with_http_client(self, http_client: Arc<dyn HttpClient>) -> Self {
self.0.borrow_mut().set_http_client(http_client);
self
}
pub fn with_quit_mode(self, mode: QuitMode) -> Self {
self.0.borrow_mut().set_quit_mode(mode);
self
}
pub fn with_windowing(self, request: WindowingRequest) -> Self {
self.0.borrow_mut().set_initial_windowing(request);
self
}
pub fn with_gpu_preference(self, preference: GpuPreference) -> Self {
self.0.borrow().platform().set_gpu_preference(preference);
self
}
pub fn with_layout_engine(
self,
layout_engine: impl Fn() -> Box<dyn LayoutEngine> + 'static,
) -> Self {
self.0
.borrow_mut()
.set_layout_engine_factory(Rc::new(layout_engine));
self
}
pub fn with_frame_pipeline(
self,
frame_pipeline: impl Fn(WindowId) -> Box<dyn FramePipeline> + 'static,
) -> Self {
self.0
.borrow_mut()
.set_frame_pipeline_factory(Rc::new(frame_pipeline));
self
}
pub fn with_text_system(self, text_system: Arc<dyn TextSystem>) -> Self {
self.0.borrow_mut().set_text_system(text_system);
self
}
pub fn run<F>(self, on_finish_launching: F)
where
F: 'static + FnOnce(&mut App),
{
let this = self.0.clone();
let platform = self.0.borrow().platform();
platform.run(Box::new(move || {
let cx = &mut *this.borrow_mut();
on_finish_launching(cx);
}));
#[cfg(target_family = "wasm")]
std::mem::forget(self);
}
pub fn run_embedded<F>(self, on_finish_launching: F) -> ApplicationHandle
where
F: 'static + FnOnce(&mut App),
{
let this = self.0.clone();
let platform = self.0.borrow().platform();
platform.run(Box::new(move || {
let cx = &mut *this.borrow_mut();
on_finish_launching(cx);
}));
ApplicationHandle { app: self.0 }
}
pub fn on_open_urls<F>(&self, callback: F) -> &Self
where
F: 'static + FnMut(Vec<String>),
{
let platform = self.0.borrow().platform();
platform.on_open_urls(Box::new(callback));
self
}
pub fn on_reopen<F>(&self, mut callback: F) -> &Self
where
F: 'static + FnMut(&mut App),
{
let this = Rc::downgrade(&self.0);
let platform = self.0.borrow().platform();
platform.on_reopen(Box::new(move || {
if let Some(app) = this.upgrade() {
callback(&mut app.borrow_mut());
}
}));
self
}
pub fn background_executor(&self) -> BackgroundExecutor {
self.0.borrow().background_executor().clone()
}
pub fn foreground_executor(&self) -> ForegroundExecutor {
self.0.borrow().foreground_executor().clone()
}
pub fn text_system(&self) -> Arc<dyn TextSystem> {
self.0.borrow().text_system().clone()
}
pub fn path_for_auxiliary_executable(&self, name: &str) -> Result<PathBuf> {
self.0.borrow().path_for_auxiliary_executable(name)
}
}