gpui2.rs

  1mod action;
  2mod app;
  3mod assets;
  4mod color;
  5mod element;
  6mod elements;
  7mod executor;
  8mod focusable;
  9mod geometry;
 10mod image_cache;
 11mod interactive;
 12mod keymap;
 13mod platform;
 14mod scene;
 15mod style;
 16mod styled;
 17mod subscription;
 18mod svg_renderer;
 19mod taffy;
 20#[cfg(any(test, feature = "test-support"))]
 21mod test;
 22mod text_system;
 23mod util;
 24mod view;
 25mod window;
 26
 27mod private {
 28    /// A mechanism for restricting implementations of a trait to only those in GPUI.
 29    /// See: https://predr.ag/blog/definitive-guide-to-sealed-traits-in-rust/
 30    pub trait Sealed {}
 31}
 32
 33pub use action::*;
 34pub use anyhow::Result;
 35pub use app::*;
 36pub use assets::*;
 37pub use color::*;
 38pub use element::*;
 39pub use elements::*;
 40pub use executor::*;
 41pub use focusable::*;
 42pub use geometry::*;
 43pub use gpui2_macros::*;
 44pub use image_cache::*;
 45pub use interactive::*;
 46pub use keymap::*;
 47pub use platform::*;
 48use private::Sealed;
 49pub use refineable::*;
 50pub use scene::*;
 51pub use serde;
 52pub use serde_json;
 53pub use smallvec;
 54pub use smol::Timer;
 55pub use style::*;
 56pub use styled::*;
 57pub use subscription::*;
 58pub use svg_renderer::*;
 59pub use taffy::{AvailableSpace, LayoutId};
 60#[cfg(any(test, feature = "test-support"))]
 61pub use test::*;
 62pub use text_system::*;
 63pub use util::arc_cow::ArcCow;
 64pub use view::*;
 65pub use window::*;
 66
 67use derive_more::{Deref, DerefMut};
 68use std::{
 69    any::{Any, TypeId},
 70    borrow::{Borrow, BorrowMut},
 71    mem,
 72    ops::{Deref, DerefMut},
 73    sync::Arc,
 74};
 75use taffy::TaffyLayoutEngine;
 76
 77type AnyBox = Box<dyn Any + Send>;
 78
 79pub trait Context {
 80    type WindowContext<'a>: UpdateView;
 81    type ModelContext<'a, T>;
 82    type Result<T>;
 83
 84    fn build_model<T>(
 85        &mut self,
 86        build_model: impl FnOnce(&mut Self::ModelContext<'_, T>) -> T,
 87    ) -> Self::Result<Model<T>>
 88    where
 89        T: 'static + Send;
 90
 91    fn update_model<T, R>(
 92        &mut self,
 93        handle: &Model<T>,
 94        update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R,
 95    ) -> Self::Result<R>
 96    where
 97        T: 'static;
 98
 99    fn update_window<T, F>(&mut self, window: AnyWindowHandle, f: F) -> Result<T>
100    where
101        F: FnOnce(AnyView, &mut Self::WindowContext<'_>) -> T;
102}
103
104pub trait VisualContext: Context {
105    type ViewContext<'a, V: 'static>;
106
107    fn build_view<V>(
108        &mut self,
109        build_view: impl FnOnce(&mut Self::ViewContext<'_, V>) -> V,
110    ) -> Self::Result<View<V>>
111    where
112        V: 'static + Send;
113
114    fn update_view<V: 'static, R>(
115        &mut self,
116        view: &View<V>,
117        update: impl FnOnce(&mut V, &mut Self::ViewContext<'_, V>) -> R,
118    ) -> Self::Result<R>;
119
120    fn replace_root_view<V>(
121        &mut self,
122        build_view: impl FnOnce(&mut Self::ViewContext<'_, V>) -> V,
123    ) -> Self::Result<View<V>>
124    where
125        V: 'static + Send + Render;
126}
127
128pub trait UpdateView {
129    type ViewContext<'a, V: 'static>;
130
131    fn update_view<V: 'static, R>(
132        &mut self,
133        view: &View<V>,
134        update: impl FnOnce(&mut V, &mut Self::ViewContext<'_, V>) -> R,
135    ) -> R;
136}
137
138pub trait Entity<T>: Sealed {
139    type Weak: 'static + Send;
140
141    fn entity_id(&self) -> EntityId;
142    fn downgrade(&self) -> Self::Weak;
143    fn upgrade_from(weak: &Self::Weak) -> Option<Self>
144    where
145        Self: Sized;
146}
147
148pub enum GlobalKey {
149    Numeric(usize),
150    View(EntityId),
151    Type(TypeId),
152}
153
154#[repr(transparent)]
155pub struct MainThread<T>(T);
156
157impl<T> Deref for MainThread<T> {
158    type Target = T;
159
160    fn deref(&self) -> &Self::Target {
161        &self.0
162    }
163}
164
165impl<T> DerefMut for MainThread<T> {
166    fn deref_mut(&mut self) -> &mut Self::Target {
167        &mut self.0
168    }
169}
170
171impl<C: Context> Context for MainThread<C> {
172    type WindowContext<'a> = MainThread<C::WindowContext<'a>>;
173    type ModelContext<'a, T> = MainThread<C::ModelContext<'a, T>>;
174    type Result<T> = C::Result<T>;
175
176    fn build_model<T>(
177        &mut self,
178        build_model: impl FnOnce(&mut Self::ModelContext<'_, T>) -> T,
179    ) -> Self::Result<Model<T>>
180    where
181        T: 'static + Send,
182    {
183        self.0.build_model(|cx| {
184            let cx = unsafe {
185                mem::transmute::<
186                    &mut C::ModelContext<'_, T>,
187                    &mut MainThread<C::ModelContext<'_, T>>,
188                >(cx)
189            };
190            build_model(cx)
191        })
192    }
193
194    fn update_model<T: 'static, R>(
195        &mut self,
196        handle: &Model<T>,
197        update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R,
198    ) -> Self::Result<R> {
199        self.0.update_model(handle, |entity, cx| {
200            let cx = unsafe {
201                mem::transmute::<
202                    &mut C::ModelContext<'_, T>,
203                    &mut MainThread<C::ModelContext<'_, T>>,
204                >(cx)
205            };
206            update(entity, cx)
207        })
208    }
209
210    fn update_window<T, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<T>
211    where
212        F: FnOnce(AnyView, &mut Self::WindowContext<'_>) -> T,
213    {
214        self.0.update_window(window, |root, cx| {
215            let cx = unsafe {
216                mem::transmute::<&mut C::WindowContext<'_>, &mut MainThread<C::WindowContext<'_>>>(
217                    cx,
218                )
219            };
220            update(root, cx)
221        })
222    }
223}
224
225impl<C: VisualContext> VisualContext for MainThread<C> {
226    type ViewContext<'a, V: 'static> = MainThread<C::ViewContext<'a, V>>;
227
228    fn build_view<V>(
229        &mut self,
230        build_view_state: impl FnOnce(&mut Self::ViewContext<'_, V>) -> V,
231    ) -> Self::Result<View<V>>
232    where
233        V: 'static + Send,
234    {
235        self.0.build_view(|cx| {
236            let cx = unsafe {
237                mem::transmute::<
238                    &mut C::ViewContext<'_, V>,
239                    &mut MainThread<C::ViewContext<'_, V>>,
240                >(cx)
241            };
242            build_view_state(cx)
243        })
244    }
245
246    fn update_view<V: 'static, R>(
247        &mut self,
248        view: &View<V>,
249        update: impl FnOnce(&mut V, &mut Self::ViewContext<'_, V>) -> R,
250    ) -> Self::Result<R> {
251        self.0.update_view(view, |view_state, cx| {
252            let cx = unsafe {
253                mem::transmute::<
254                    &mut C::ViewContext<'_, V>,
255                    &mut MainThread<C::ViewContext<'_, V>>,
256                >(cx)
257            };
258            update(view_state, cx)
259        })
260    }
261
262    fn replace_root_view<V>(
263        &mut self,
264        build_view: impl FnOnce(&mut Self::ViewContext<'_, V>) -> V,
265    ) -> Self::Result<View<V>>
266    where
267        V: 'static + Send + Render,
268    {
269        self.0.replace_root_view(|cx| {
270            let cx = unsafe {
271                mem::transmute::<
272                    &mut C::ViewContext<'_, V>,
273                    &mut MainThread<C::ViewContext<'_, V>>,
274                >(cx)
275            };
276            build_view(cx)
277        })
278    }
279}
280
281impl<C: UpdateView> UpdateView for MainThread<C> {
282    type ViewContext<'a, V: 'static> = MainThread<C::ViewContext<'a, V>>;
283
284    fn update_view<V: 'static, R>(
285        &mut self,
286        view: &View<V>,
287        update: impl FnOnce(&mut V, &mut Self::ViewContext<'_, V>) -> R,
288    ) -> R {
289        self.0.update_view(view, |view_state, cx| {
290            let cx = unsafe {
291                mem::transmute::<
292                    &mut C::ViewContext<'_, V>,
293                    &mut MainThread<C::ViewContext<'_, V>>,
294                >(cx)
295            };
296            update(view_state, cx)
297        })
298    }
299}
300
301pub trait BorrowAppContext {
302    fn with_text_style<F, R>(&mut self, style: TextStyleRefinement, f: F) -> R
303    where
304        F: FnOnce(&mut Self) -> R;
305
306    fn set_global<T: Send + 'static>(&mut self, global: T);
307}
308
309impl<C> BorrowAppContext for C
310where
311    C: BorrowMut<AppContext>,
312{
313    fn with_text_style<F, R>(&mut self, style: TextStyleRefinement, f: F) -> R
314    where
315        F: FnOnce(&mut Self) -> R,
316    {
317        self.borrow_mut().push_text_style(style);
318        let result = f(self);
319        self.borrow_mut().pop_text_style();
320        result
321    }
322
323    fn set_global<G: 'static + Send>(&mut self, global: G) {
324        self.borrow_mut().set_global(global)
325    }
326}
327
328pub trait EventEmitter: 'static {
329    type Event: Any;
330}
331
332pub trait Flatten<T> {
333    fn flatten(self) -> Result<T>;
334}
335
336impl<T> Flatten<T> for Result<Result<T>> {
337    fn flatten(self) -> Result<T> {
338        self?
339    }
340}
341
342impl<T> Flatten<T> for Result<T> {
343    fn flatten(self) -> Result<T> {
344        self
345    }
346}
347
348#[derive(Deref, DerefMut, Eq, PartialEq, Hash, Clone)]
349pub struct SharedString(ArcCow<'static, str>);
350
351impl Default for SharedString {
352    fn default() -> Self {
353        Self(ArcCow::Owned("".into()))
354    }
355}
356
357impl AsRef<str> for SharedString {
358    fn as_ref(&self) -> &str {
359        &self.0
360    }
361}
362
363impl Borrow<str> for SharedString {
364    fn borrow(&self) -> &str {
365        self.as_ref()
366    }
367}
368
369impl std::fmt::Debug for SharedString {
370    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
371        self.0.fmt(f)
372    }
373}
374
375impl std::fmt::Display for SharedString {
376    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
377        write!(f, "{}", self.0.as_ref())
378    }
379}
380
381impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
382    fn from(value: T) -> Self {
383        Self(value.into())
384    }
385}
386
387pub(crate) struct MainThreadOnly<T: ?Sized> {
388    executor: Executor,
389    value: Arc<T>,
390}
391
392impl<T: ?Sized> Clone for MainThreadOnly<T> {
393    fn clone(&self) -> Self {
394        Self {
395            executor: self.executor.clone(),
396            value: self.value.clone(),
397        }
398    }
399}
400
401/// Allows a value to be accessed only on the main thread, allowing a non-`Send` type
402/// to become `Send`.
403impl<T: 'static + ?Sized> MainThreadOnly<T> {
404    pub(crate) fn new(value: Arc<T>, executor: Executor) -> Self {
405        Self { executor, value }
406    }
407
408    pub(crate) fn borrow_on_main_thread(&self) -> &T {
409        assert!(self.executor.is_main_thread());
410        &self.value
411    }
412}
413
414unsafe impl<T: ?Sized> Send for MainThreadOnly<T> {}