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(target_family = "wasm")]
32pub use gpui_web::WebBackendPreference;
33
34#[cfg(target_os = "windows")]
39pub use gpui_windows::{DirectXImportedTexture, DirectXRenderer, DirectXTextureExt};
40
41#[cfg(target_os = "macos")]
46pub use gpui_macos::MetalTextureExt;
47
48#[cfg(any(target_os = "linux", target_os = "freebsd"))]
53pub use gpui_linux::ImportedTextureExt;
54
55#[cfg(target_family = "wasm")]
56pub fn application_with_web_backend(backend_preference: WebBackendPreference) -> Application {
57 let platform = Rc::new(gpui_web::WebPlatform::new_with_backend(
58 true,
59 backend_preference,
60 ));
61 let http_client = std::sync::Arc::new(platform.fetch_http_client());
62 Application::with_platform(platform).with_http_client(http_client)
63}
64
65#[cfg(target_family = "wasm")]
67pub fn single_threaded_web() -> Application {
68 let platform = Rc::new(gpui_web::WebPlatform::new(false));
69 let http_client = std::sync::Arc::new(platform.fetch_http_client());
70 Application::with_platform(platform).with_http_client(http_client)
71}
72
73#[cfg(target_family = "wasm")]
77pub fn web_init() {
78 gpui_web::init_logging();
79}
80
81pub fn current_platform(headless: bool) -> Rc<dyn Platform> {
83 #[cfg(target_os = "macos")]
84 {
85 Rc::new(gpui_macos::MacPlatform::new(headless))
86 }
87
88 #[cfg(target_os = "windows")]
89 {
90 Rc::new(
91 gpui_windows::WindowsPlatform::new(headless)
92 .expect("failed to initialize Windows platform"),
93 )
94 }
95
96 #[cfg(any(target_os = "linux", target_os = "freebsd"))]
97 {
98 gpui_linux::current_platform(headless)
99 }
100
101 #[cfg(target_family = "wasm")]
102 {
103 let _ = headless;
104 Rc::new(gpui_web::WebPlatform::new(true))
105 }
106}
107
108#[cfg(any(feature = "bench-support", feature = "test-support"))]
110pub fn current_headless_renderer() -> anyhow::Result<Option<Box<dyn crate::SceneRenderer>>> {
111 #[cfg(all(feature = "platform", any(target_os = "linux", target_os = "freebsd")))]
112 {
113 current_headless_renderer_with(
117 gpui_linux::gpu_preference_from_env().unwrap_or(crate::GpuPreference::Auto),
118 )
119 }
120
121 #[cfg(not(all(feature = "platform", any(target_os = "linux", target_os = "freebsd"))))]
122 {
123 current_headless_renderer_with(crate::GpuPreference::Auto)
124 }
125}
126
127#[cfg(any(feature = "bench-support", feature = "test-support"))]
134pub fn current_headless_renderer_with(
135 gpu_preference: crate::GpuPreference,
136) -> anyhow::Result<Option<Box<dyn crate::SceneRenderer>>> {
137 let _ = &gpu_preference;
138
139 #[cfg(target_os = "macos")]
140 {
141 Ok(Some(Box::new(
142 gpui_macos::metal_renderer::MetalHeadlessRenderer::new(),
143 )))
144 }
145
146 #[cfg(all(feature = "platform", any(target_os = "linux", target_os = "freebsd")))]
147 {
148 gpui_linux::WgpuHeadlessRenderer::with_gpu_preference(gpu_preference)
151 .map(|renderer| Some(Box::new(renderer) as Box<dyn crate::SceneRenderer>))
152 }
153
154 #[cfg(not(any(
155 target_os = "macos",
156 all(feature = "platform", any(target_os = "linux", target_os = "freebsd")),
157 )))]
158 {
159 Ok(None)
160 }
161}
162
163#[cfg(feature = "bench-support")]
171pub fn bench_text_system() -> std::sync::Arc<dyn crate::PlatformTextSystem> {
172 thread_local! {
173 static TEXT_SYSTEM: std::sync::Arc<dyn crate::PlatformTextSystem> =
174 current_platform(true).text_system();
175 }
176 TEXT_SYSTEM.with(|text_system| text_system.clone())
177}
178
179#[cfg(all(test, target_os = "macos"))]
180mod tests {
181 use super::*;
182 use crate::{AppContext, Empty, VisualTestAppContext};
183 use std::cell::RefCell;
184 use std::time::Duration;
185
186 #[test]
194 #[ignore] fn test_foreground_tasks_run_with_run_until_parked() {
196 let mut cx = VisualTestAppContext::new(current_platform(false));
197
198 let task_ran = Rc::new(RefCell::new(false));
199
200 {
203 let task_ran = task_ran.clone();
204 cx.update(|cx| {
205 cx.spawn(async move |_| {
206 *task_ran.borrow_mut() = true;
207 })
208 .detach();
209 });
210 }
211
212 assert!(!*task_ran.borrow());
214
215 cx.run_until_parked();
217
218 assert!(*task_ran.borrow());
220 }
221
222 #[test]
223 #[ignore] fn test_advance_clock_triggers_delayed_tasks() {
225 let mut cx = VisualTestAppContext::new(current_platform(false));
226
227 let task_ran = Rc::new(RefCell::new(false));
228
229 {
231 let task_ran = task_ran.clone();
232 let executor = cx.background_executor.clone();
233 cx.update(|cx| {
234 cx.spawn(async move |_| {
235 executor.timer(Duration::from_millis(500)).await;
236 *task_ran.borrow_mut() = true;
237 })
238 .detach();
239 });
240 }
241
242 cx.run_until_parked();
244 assert!(!*task_ran.borrow());
245
246 cx.advance_clock(Duration::from_millis(600));
248
249 assert!(*task_ran.borrow());
251 }
252
253 #[test]
254 #[ignore] fn test_window_spawn_uses_test_dispatcher() {
256 let mut cx = VisualTestAppContext::new(current_platform(false));
257
258 let task_ran = Rc::new(RefCell::new(false));
259
260 let window = cx
261 .open_offscreen_window_default(|_, cx| cx.new(|_| Empty))
262 .expect("Failed to open window");
263
264 {
267 let task_ran = task_ran.clone();
268 cx.update_window(window.into(), |_, window, cx| {
269 window
270 .spawn(cx, async move |_| {
271 *task_ran.borrow_mut() = true;
272 })
273 .detach();
274 })
275 .ok();
276 }
277
278 assert!(!*task_ran.borrow());
280
281 cx.run_until_parked();
283
284 assert!(*task_ran.borrow());
286 }
287}