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(all(
33 any(target_os = "linux", target_os = "freebsd"),
34 not(target_env = "ohos")
35))]
36pub fn linux(allowed_modes: gpui::WindowingModes) -> gpui::Application {
37 gpui::Application::with_platform(gpui_linux::linux_platform(allowed_modes))
38}
39
40#[cfg(target_family = "wasm")]
41pub use gpui_web::WebBackendPreference;
42
43#[cfg(target_family = "wasm")]
44pub fn application_with_web_backend(backend_preference: WebBackendPreference) -> gpui::Application {
45 let platform = Rc::new(gpui_web::WebPlatform::new_with_backend(
46 true,
47 backend_preference,
48 ));
49 let http_client = std::sync::Arc::new(platform.fetch_http_client());
50 gpui::Application::with_platform(platform).with_http_client(http_client)
51}
52
53#[cfg(target_family = "wasm")]
55pub fn single_threaded_web() -> gpui::Application {
56 let platform = Rc::new(gpui_web::WebPlatform::new(false));
57 let http_client = std::sync::Arc::new(platform.fetch_http_client());
58 gpui::Application::with_platform(platform).with_http_client(http_client)
59}
60
61#[cfg(target_family = "wasm")]
64pub fn web_init() {
65 console_error_panic_hook::set_once();
66 gpui_web::init_logging();
67}
68
69pub fn current_platform(headless: bool) -> Rc<dyn Platform> {
71 #[cfg(target_os = "ios")]
72 {
73 gpui_ios::current_platform(headless)
74 }
75
76 #[cfg(target_os = "macos")]
77 {
78 Rc::new(gpui_macos::MacPlatform::new(headless))
79 }
80
81 #[cfg(target_os = "windows")]
82 {
83 Rc::new(
84 gpui_windows::WindowsPlatform::new(headless)
85 .expect("failed to initialize Windows platform"),
86 )
87 }
88
89 #[cfg(target_env = "ohos")]
90 {
91 let _ = headless;
92 panic!(
93 "gpui_platform does not select an OpenHarmony backend; inject gpui-ohos with Application::with_platform"
94 )
95 }
96
97 #[cfg(all(
98 any(target_os = "linux", target_os = "freebsd"),
99 not(target_env = "ohos")
100 ))]
101 {
102 gpui_linux::current_platform(headless)
103 }
104
105 #[cfg(target_family = "wasm")]
106 {
107 let _ = headless;
108 Rc::new(gpui_web::WebPlatform::new(true))
109 }
110}
111
112#[cfg(feature = "bench-support")]
120pub fn bench_text_system() -> std::sync::Arc<dyn gpui::PlatformTextSystem> {
121 thread_local! {
122 static TEXT_SYSTEM: std::sync::Arc<dyn gpui::PlatformTextSystem> =
123 current_platform(true).text_system();
124 }
125 TEXT_SYSTEM.with(|text_system| text_system.clone())
126}
127
128#[cfg(any(feature = "bench-support", feature = "test-support"))]
130pub fn current_headless_renderer() -> anyhow::Result<Option<Box<dyn gpui::PlatformHeadlessRenderer>>>
131{
132 #[cfg(target_os = "macos")]
133 {
134 Ok(Some(Box::new(
135 gpui_macos::metal_renderer::MetalHeadlessRenderer::new()?,
136 )))
137 }
138
139 #[cfg(target_os = "linux")]
140 {
141 gpui_wgpu::WgpuHeadlessRenderer::new()
142 .map(|renderer| Some(Box::new(renderer) as Box<dyn gpui::PlatformHeadlessRenderer>))
143 }
144
145 #[cfg(target_os = "windows")]
146 {
147 Ok(Some(Box::new(gpui_windows::Dx11HeadlessRenderer::new()?)))
148 }
149
150 #[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))]
151 {
152 Ok(None)
153 }
154}
155
156#[cfg(all(test, target_os = "macos"))]
157mod tests {
158 use super::*;
159 use gpui::{AppContext, Empty, VisualTestAppContext};
160 use std::cell::RefCell;
161 use std::time::Duration;
162
163 #[test]
171 #[ignore] fn test_foreground_tasks_run_with_run_until_parked() {
173 let mut cx = VisualTestAppContext::new(current_platform(false));
174
175 let task_ran = Rc::new(RefCell::new(false));
176
177 {
180 let task_ran = task_ran.clone();
181 cx.update(|cx| {
182 cx.spawn(async move |_| {
183 *task_ran.borrow_mut() = true;
184 })
185 .detach();
186 });
187 }
188
189 assert!(!*task_ran.borrow());
191
192 cx.run_until_parked();
194
195 assert!(*task_ran.borrow());
197 }
198
199 #[test]
200 #[ignore] fn test_advance_clock_triggers_delayed_tasks() {
202 let mut cx = VisualTestAppContext::new(current_platform(false));
203
204 let task_ran = Rc::new(RefCell::new(false));
205
206 {
208 let task_ran = task_ran.clone();
209 let executor = cx.background_executor.clone();
210 cx.update(|cx| {
211 cx.spawn(async move |_| {
212 executor.timer(Duration::from_millis(500)).await;
213 *task_ran.borrow_mut() = true;
214 })
215 .detach();
216 });
217 }
218
219 cx.run_until_parked();
221 assert!(!*task_ran.borrow());
222
223 cx.advance_clock(Duration::from_millis(600));
225
226 assert!(*task_ran.borrow());
228 }
229
230 #[test]
231 #[ignore] fn test_window_spawn_uses_test_dispatcher() {
233 let mut cx = VisualTestAppContext::new(current_platform(false));
234
235 let task_ran = Rc::new(RefCell::new(false));
236
237 let window = cx
238 .open_offscreen_window_default(|_, cx| cx.new(|_| Empty))
239 .expect("Failed to open window");
240
241 {
244 let task_ran = task_ran.clone();
245 cx.update_window(window.into(), |_, window, cx| {
246 window
247 .spawn(cx, async move |_| {
248 *task_ran.borrow_mut() = true;
249 })
250 .detach();
251 })
252 .ok();
253 }
254
255 assert!(!*task_ran.borrow());
257
258 cx.run_until_parked();
260
261 assert!(*task_ran.borrow());
263 }
264}