1use crate::{Application, BackgroundExecutor, Platform};
8use std::rc::Rc;
9
10pub fn background_executor() -> BackgroundExecutor {
12 current_platform(true).background_executor()
13}
14
15pub fn application() -> Application {
17 #[cfg(target_family = "wasm")]
18 {
19 application_with_web_backend(gpui_web::WebBackendPreference::Auto)
20 }
21
22 #[cfg(not(target_family = "wasm"))]
23 Application::with_platform(current_platform(false))
24}
25
26pub fn headless() -> Application {
28 Application::with_platform(current_platform(true))
29}
30
31#[cfg(any(target_os = "linux", target_os = "freebsd"))]
37pub fn linux(allowed_modes: gpui::WindowingModes) -> gpui::Application {
38 gpui::Application::with_platform(gpui_linux::linux_platform(allowed_modes))
39}
40
41#[cfg(target_family = "wasm")]
42pub use gpui_web::WebBackendPreference;
43
44#[cfg(target_os = "windows")]
49pub use gpui_windows::{DirectXImportedTexture, DirectXRenderer, DirectXTextureExt};
50
51#[cfg(target_os = "macos")]
56pub use gpui_macos::MetalTextureExt;
57
58#[cfg(any(target_os = "linux", target_os = "freebsd"))]
63pub use gpui_linux::ImportedTextureExt;
64
65#[cfg(target_family = "wasm")]
66pub fn application_with_web_backend(backend_preference: WebBackendPreference) -> Application {
67 let platform = Rc::new(gpui_web::WebPlatform::new_with_backend(
68 true,
69 backend_preference,
70 ));
71 let http_client = std::sync::Arc::new(platform.fetch_http_client());
72 Application::with_platform(platform).with_http_client(http_client)
73}
74
75#[cfg(target_family = "wasm")]
77pub fn single_threaded_web() -> Application {
78 let platform = Rc::new(gpui_web::WebPlatform::new(false));
79 let http_client = std::sync::Arc::new(platform.fetch_http_client());
80 Application::with_platform(platform).with_http_client(http_client)
81}
82
83#[cfg(target_family = "wasm")]
87pub fn web_init() {
88 gpui_web::init_logging();
89}
90
91pub fn current_platform(headless: bool) -> Rc<dyn Platform> {
93 #[cfg(target_os = "macos")]
94 {
95 Rc::new(gpui_macos::MacPlatform::new(headless))
96 }
97
98 #[cfg(target_os = "windows")]
99 {
100 Rc::new(
101 gpui_windows::WindowsPlatform::new(headless)
102 .expect("failed to initialize Windows platform"),
103 )
104 }
105
106 #[cfg(any(target_os = "linux", target_os = "freebsd"))]
107 {
108 gpui_linux::current_platform(headless)
109 }
110
111 #[cfg(target_family = "wasm")]
112 {
113 let _ = headless;
114 Rc::new(gpui_web::WebPlatform::new(true))
115 }
116}
117
118#[cfg(any(feature = "bench-support", feature = "test-support"))]
120pub fn current_headless_renderer() -> anyhow::Result<Option<Box<dyn crate::SceneRenderer>>> {
121 #[cfg(all(feature = "platform", any(target_os = "linux", target_os = "freebsd")))]
122 {
123 current_headless_renderer_with(
127 gpui_linux::gpu_preference_from_env().unwrap_or(crate::GpuPreference::Auto),
128 )
129 }
130
131 #[cfg(not(all(feature = "platform", any(target_os = "linux", target_os = "freebsd"))))]
132 {
133 current_headless_renderer_with(crate::GpuPreference::Auto)
134 }
135}
136
137#[cfg(any(feature = "bench-support", feature = "test-support"))]
144pub fn current_headless_renderer_with(
145 gpu_preference: crate::GpuPreference,
146) -> anyhow::Result<Option<Box<dyn crate::SceneRenderer>>> {
147 let _ = &gpu_preference;
148
149 #[cfg(target_os = "macos")]
150 {
151 Ok(Some(Box::new(
152 gpui_macos::metal_renderer::MetalHeadlessRenderer::new(),
153 )))
154 }
155
156 #[cfg(all(feature = "platform", any(target_os = "linux", target_os = "freebsd")))]
157 {
158 gpui_linux::WgpuHeadlessRenderer::with_gpu_preference(gpu_preference)
161 .map(|renderer| Some(Box::new(renderer) as Box<dyn crate::SceneRenderer>))
162 }
163
164 #[cfg(not(any(
165 target_os = "macos",
166 all(feature = "platform", any(target_os = "linux", target_os = "freebsd")),
167 )))]
168 {
169 Ok(None)
170 }
171}
172
173#[cfg(feature = "bench-support")]
181pub fn bench_text_system() -> std::sync::Arc<dyn crate::PlatformTextSystem> {
182 thread_local! {
183 static TEXT_SYSTEM: std::sync::Arc<dyn crate::PlatformTextSystem> =
184 current_platform(true).text_system();
185 }
186 TEXT_SYSTEM.with(|text_system| text_system.clone())
187}
188
189#[cfg(all(test, target_os = "macos"))]
190mod tests {
191 use super::*;
192 use crate::{AppContext, Empty, VisualTestAppContext};
193 use std::cell::RefCell;
194 use std::time::Duration;
195
196 #[test]
204 #[ignore] fn test_foreground_tasks_run_with_run_until_parked() {
206 let mut cx = VisualTestAppContext::new(current_platform(false));
207
208 let task_ran = Rc::new(RefCell::new(false));
209
210 {
213 let task_ran = task_ran.clone();
214 cx.update(|cx| {
215 cx.spawn(async move |_| {
216 *task_ran.borrow_mut() = true;
217 })
218 .detach();
219 });
220 }
221
222 assert!(!*task_ran.borrow());
224
225 cx.run_until_parked();
227
228 assert!(*task_ran.borrow());
230 }
231
232 #[test]
233 #[ignore] fn test_advance_clock_triggers_delayed_tasks() {
235 let mut cx = VisualTestAppContext::new(current_platform(false));
236
237 let task_ran = Rc::new(RefCell::new(false));
238
239 {
241 let task_ran = task_ran.clone();
242 let executor = cx.background_executor.clone();
243 cx.update(|cx| {
244 cx.spawn(async move |_| {
245 executor.timer(Duration::from_millis(500)).await;
246 *task_ran.borrow_mut() = true;
247 })
248 .detach();
249 });
250 }
251
252 cx.run_until_parked();
254 assert!(!*task_ran.borrow());
255
256 cx.advance_clock(Duration::from_millis(600));
258
259 assert!(*task_ran.borrow());
261 }
262
263 #[test]
264 #[ignore] fn test_window_spawn_uses_test_dispatcher() {
266 let mut cx = VisualTestAppContext::new(current_platform(false));
267
268 let task_ran = Rc::new(RefCell::new(false));
269
270 let window = cx
271 .open_offscreen_window_default(|_, cx| cx.new(|_| Empty))
272 .expect("Failed to open window");
273
274 {
277 let task_ran = task_ran.clone();
278 cx.update_window(window.into(), |_, window, cx| {
279 window
280 .spawn(cx, async move |_| {
281 *task_ran.borrow_mut() = true;
282 })
283 .detach();
284 })
285 .ok();
286 }
287
288 assert!(!*task_ran.borrow());
290
291 cx.run_until_parked();
293
294 assert!(*task_ran.borrow());
296 }
297}