gpui_platform/
gpui_platform.rs1pub use gpui::Platform;
5
6use std::rc::Rc;
7
8pub fn background_executor() -> gpui::BackgroundExecutor {
10 current_platform(true).background_executor()
11}
12
13pub fn application() -> gpui::Application {
14 #[cfg(target_family = "wasm")]
15 {
16 application_with_web_backend(gpui_web::WebBackendPreference::Auto)
17 }
18
19 #[cfg(not(target_family = "wasm"))]
20 gpui::Application::with_platform(current_platform(false))
21}
22
23pub fn headless() -> gpui::Application {
24 gpui::Application::with_platform(current_platform(true))
25}
26
27#[cfg(any(target_os = "linux", target_os = "freebsd"))]
33pub fn linux(allowed_modes: gpui::WindowingModes) -> gpui::Application {
34 gpui::Application::with_platform(gpui_linux::linux_platform(allowed_modes))
35}
36
37#[cfg(target_family = "wasm")]
38pub use gpui_web::WebBackendPreference;
39
40#[cfg(target_family = "wasm")]
41pub fn application_with_web_backend(backend_preference: WebBackendPreference) -> gpui::Application {
42 let platform = Rc::new(gpui_web::WebPlatform::new_with_backend(
43 true,
44 backend_preference,
45 ));
46 let http_client = std::sync::Arc::new(platform.fetch_http_client());
47 gpui::Application::with_platform(platform).with_http_client(http_client)
48}
49
50#[cfg(target_family = "wasm")]
52pub fn single_threaded_web() -> gpui::Application {
53 let platform = Rc::new(gpui_web::WebPlatform::new(false));
54 let http_client = std::sync::Arc::new(platform.fetch_http_client());
55 gpui::Application::with_platform(platform).with_http_client(http_client)
56}
57
58#[cfg(target_family = "wasm")]
61pub fn web_init() {
62 console_error_panic_hook::set_once();
63 gpui_web::init_logging();
64}
65
66pub fn current_platform(headless: bool) -> Rc<dyn Platform> {
68 #[cfg(target_os = "ios")]
69 {
70 gpui_ios::current_platform(headless)
71 }
72
73 #[cfg(target_os = "macos")]
74 {
75 Rc::new(gpui_macos::MacPlatform::new(headless))
76 }
77
78 #[cfg(target_os = "windows")]
79 {
80 Rc::new(
81 gpui_windows::WindowsPlatform::new(headless)
82 .expect("failed to initialize Windows platform"),
83 )
84 }
85
86 #[cfg(any(target_os = "linux", target_os = "freebsd"))]
87 {
88 gpui_linux::current_platform(headless)
89 }
90
91 #[cfg(target_family = "wasm")]
92 {
93 let _ = headless;
94 Rc::new(gpui_web::WebPlatform::new(true))
95 }
96}
97
98#[cfg(feature = "bench-support")]
106pub fn bench_text_system() -> std::sync::Arc<dyn gpui::PlatformTextSystem> {
107 thread_local! {
108 static TEXT_SYSTEM: std::sync::Arc<dyn gpui::PlatformTextSystem> =
109 current_platform(true).text_system();
110 }
111 TEXT_SYSTEM.with(|text_system| text_system.clone())
112}
113
114#[cfg(any(feature = "bench-support", feature = "test-support"))]
116pub fn current_headless_renderer() -> anyhow::Result<Option<Box<dyn gpui::PlatformHeadlessRenderer>>>
117{
118 #[cfg(target_os = "macos")]
119 {
120 Ok(Some(Box::new(
121 gpui_macos::metal_renderer::MetalHeadlessRenderer::new(),
122 )))
123 }
124
125 #[cfg(target_os = "linux")]
126 {
127 gpui_wgpu::WgpuHeadlessRenderer::new()
128 .map(|renderer| Some(Box::new(renderer) as Box<dyn gpui::PlatformHeadlessRenderer>))
129 }
130
131 #[cfg(target_os = "windows")]
132 {
133 Ok(Some(Box::new(gpui_windows::Dx11HeadlessRenderer::new()?)))
134 }
135
136 #[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
137 {
138 Ok(None)
139 }
140}
141
142#[cfg(all(test, target_os = "macos"))]
143mod tests {
144 use super::*;
145 use gpui::{AppContext, Empty, VisualTestAppContext};
146 use std::cell::RefCell;
147 use std::time::Duration;
148
149 #[test]
157 #[ignore] fn test_foreground_tasks_run_with_run_until_parked() {
159 let mut cx = VisualTestAppContext::new(current_platform(false));
160
161 let task_ran = Rc::new(RefCell::new(false));
162
163 {
166 let task_ran = task_ran.clone();
167 cx.update(|cx| {
168 cx.spawn(async move |_| {
169 *task_ran.borrow_mut() = true;
170 })
171 .detach();
172 });
173 }
174
175 assert!(!*task_ran.borrow());
177
178 cx.run_until_parked();
180
181 assert!(*task_ran.borrow());
183 }
184
185 #[test]
186 #[ignore] fn test_advance_clock_triggers_delayed_tasks() {
188 let mut cx = VisualTestAppContext::new(current_platform(false));
189
190 let task_ran = Rc::new(RefCell::new(false));
191
192 {
194 let task_ran = task_ran.clone();
195 let executor = cx.background_executor.clone();
196 cx.update(|cx| {
197 cx.spawn(async move |_| {
198 executor.timer(Duration::from_millis(500)).await;
199 *task_ran.borrow_mut() = true;
200 })
201 .detach();
202 });
203 }
204
205 cx.run_until_parked();
207 assert!(!*task_ran.borrow());
208
209 cx.advance_clock(Duration::from_millis(600));
211
212 assert!(*task_ran.borrow());
214 }
215
216 #[test]
217 #[ignore] fn test_window_spawn_uses_test_dispatcher() {
219 let mut cx = VisualTestAppContext::new(current_platform(false));
220
221 let task_ran = Rc::new(RefCell::new(false));
222
223 let window = cx
224 .open_offscreen_window_default(|_, cx| cx.new(|_| Empty))
225 .expect("Failed to open window");
226
227 {
230 let task_ran = task_ran.clone();
231 cx.update_window(window.into(), |_, window, cx| {
232 window
233 .spawn(cx, async move |_| {
234 *task_ran.borrow_mut() = true;
235 })
236 .detach();
237 })
238 .ok();
239 }
240
241 assert!(!*task_ran.borrow());
243
244 cx.run_until_parked();
246
247 assert!(*task_ran.borrow());
249 }
250}