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 ModelContext<'a, T>;
 81    type Result<T>;
 82
 83    fn build_model<T>(
 84        &mut self,
 85        build_model: impl FnOnce(&mut Self::ModelContext<'_, T>) -> T,
 86    ) -> Self::Result<Model<T>>
 87    where
 88        T: 'static + Send;
 89
 90    fn update_model<T: 'static, R>(
 91        &mut self,
 92        handle: &Model<T>,
 93        update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R,
 94    ) -> Self::Result<R>;
 95}
 96
 97pub trait VisualContext: Context {
 98    type ViewContext<'a, 'w, V>;
 99
100    fn build_view<V>(
101        &mut self,
102        build_view_state: impl FnOnce(&mut Self::ViewContext<'_, '_, V>) -> V,
103    ) -> Self::Result<View<V>>
104    where
105        V: 'static + Send;
106
107    fn update_view<V: 'static, R>(
108        &mut self,
109        view: &View<V>,
110        update: impl FnOnce(&mut V, &mut Self::ViewContext<'_, '_, V>) -> R,
111    ) -> Self::Result<R>;
112}
113
114pub trait Entity<T>: Sealed {
115    type Weak: 'static + Send;
116
117    fn entity_id(&self) -> EntityId;
118    fn downgrade(&self) -> Self::Weak;
119    fn upgrade_from(weak: &Self::Weak) -> Option<Self>
120    where
121        Self: Sized;
122}
123
124pub enum GlobalKey {
125    Numeric(usize),
126    View(EntityId),
127    Type(TypeId),
128}
129
130#[repr(transparent)]
131pub struct MainThread<T>(T);
132
133impl<T> Deref for MainThread<T> {
134    type Target = T;
135
136    fn deref(&self) -> &Self::Target {
137        &self.0
138    }
139}
140
141impl<T> DerefMut for MainThread<T> {
142    fn deref_mut(&mut self) -> &mut Self::Target {
143        &mut self.0
144    }
145}
146
147impl<C: Context> Context for MainThread<C> {
148    type ModelContext<'a, T> = MainThread<C::ModelContext<'a, T>>;
149    type Result<T> = C::Result<T>;
150
151    fn build_model<T>(
152        &mut self,
153        build_model: impl FnOnce(&mut Self::ModelContext<'_, T>) -> T,
154    ) -> Self::Result<Model<T>>
155    where
156        T: 'static + Send,
157    {
158        self.0.build_model(|cx| {
159            let cx = unsafe {
160                mem::transmute::<
161                    &mut C::ModelContext<'_, T>,
162                    &mut MainThread<C::ModelContext<'_, T>>,
163                >(cx)
164            };
165            build_model(cx)
166        })
167    }
168
169    fn update_model<T: 'static, R>(
170        &mut self,
171        handle: &Model<T>,
172        update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R,
173    ) -> Self::Result<R> {
174        self.0.update_model(handle, |entity, cx| {
175            let cx = unsafe {
176                mem::transmute::<
177                    &mut C::ModelContext<'_, T>,
178                    &mut MainThread<C::ModelContext<'_, T>>,
179                >(cx)
180            };
181            update(entity, cx)
182        })
183    }
184}
185
186impl<C: VisualContext> VisualContext for MainThread<C> {
187    type ViewContext<'a, 'w, V> = MainThread<C::ViewContext<'a, 'w, V>>;
188
189    fn build_view<V>(
190        &mut self,
191        build_view_state: impl FnOnce(&mut Self::ViewContext<'_, '_, V>) -> V,
192    ) -> Self::Result<View<V>>
193    where
194        V: 'static + Send,
195    {
196        self.0.build_view(|cx| {
197            let cx = unsafe {
198                mem::transmute::<
199                    &mut C::ViewContext<'_, '_, V>,
200                    &mut MainThread<C::ViewContext<'_, '_, V>>,
201                >(cx)
202            };
203            build_view_state(cx)
204        })
205    }
206
207    fn update_view<V: 'static, R>(
208        &mut self,
209        view: &View<V>,
210        update: impl FnOnce(&mut V, &mut Self::ViewContext<'_, '_, V>) -> R,
211    ) -> Self::Result<R> {
212        self.0.update_view(view, |view_state, cx| {
213            let cx = unsafe {
214                mem::transmute::<
215                    &mut C::ViewContext<'_, '_, V>,
216                    &mut MainThread<C::ViewContext<'_, '_, V>>,
217                >(cx)
218            };
219            update(view_state, cx)
220        })
221    }
222}
223
224pub trait BorrowAppContext {
225    fn with_text_style<F, R>(&mut self, style: TextStyleRefinement, f: F) -> R
226    where
227        F: FnOnce(&mut Self) -> R;
228
229    fn set_global<T: Send + 'static>(&mut self, global: T);
230}
231
232impl<C> BorrowAppContext for C
233where
234    C: BorrowMut<AppContext>,
235{
236    fn with_text_style<F, R>(&mut self, style: TextStyleRefinement, f: F) -> R
237    where
238        F: FnOnce(&mut Self) -> R,
239    {
240        self.borrow_mut().push_text_style(style);
241        let result = f(self);
242        self.borrow_mut().pop_text_style();
243        result
244    }
245
246    fn set_global<G: 'static + Send>(&mut self, global: G) {
247        self.borrow_mut().set_global(global)
248    }
249}
250
251pub trait EventEmitter: 'static {
252    type Event: Any;
253}
254
255pub trait Flatten<T> {
256    fn flatten(self) -> Result<T>;
257}
258
259impl<T> Flatten<T> for Result<Result<T>> {
260    fn flatten(self) -> Result<T> {
261        self?
262    }
263}
264
265impl<T> Flatten<T> for Result<T> {
266    fn flatten(self) -> Result<T> {
267        self
268    }
269}
270
271#[derive(Deref, DerefMut, Eq, PartialEq, Hash, Clone)]
272pub struct SharedString(ArcCow<'static, str>);
273
274impl Default for SharedString {
275    fn default() -> Self {
276        Self(ArcCow::Owned("".into()))
277    }
278}
279
280impl AsRef<str> for SharedString {
281    fn as_ref(&self) -> &str {
282        &self.0
283    }
284}
285
286impl Borrow<str> for SharedString {
287    fn borrow(&self) -> &str {
288        self.as_ref()
289    }
290}
291
292impl std::fmt::Debug for SharedString {
293    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
294        self.0.fmt(f)
295    }
296}
297
298impl std::fmt::Display for SharedString {
299    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
300        write!(f, "{}", self.0.as_ref())
301    }
302}
303
304impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
305    fn from(value: T) -> Self {
306        Self(value.into())
307    }
308}
309
310pub enum Reference<'a, T> {
311    Immutable(&'a T),
312    Mutable(&'a mut T),
313}
314
315impl<'a, T> Deref for Reference<'a, T> {
316    type Target = T;
317
318    fn deref(&self) -> &Self::Target {
319        match self {
320            Reference::Immutable(target) => target,
321            Reference::Mutable(target) => target,
322        }
323    }
324}
325
326impl<'a, T> DerefMut for Reference<'a, T> {
327    fn deref_mut(&mut self) -> &mut Self::Target {
328        match self {
329            Reference::Immutable(_) => {
330                panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
331            }
332            Reference::Mutable(target) => target,
333        }
334    }
335}
336
337pub(crate) struct MainThreadOnly<T: ?Sized> {
338    executor: Executor,
339    value: Arc<T>,
340}
341
342impl<T: ?Sized> Clone for MainThreadOnly<T> {
343    fn clone(&self) -> Self {
344        Self {
345            executor: self.executor.clone(),
346            value: self.value.clone(),
347        }
348    }
349}
350
351/// Allows a value to be accessed only on the main thread, allowing a non-`Send` type
352/// to become `Send`.
353impl<T: 'static + ?Sized> MainThreadOnly<T> {
354    pub(crate) fn new(value: Arc<T>, executor: Executor) -> Self {
355        Self { executor, value }
356    }
357
358    pub(crate) fn borrow_on_main_thread(&self) -> &T {
359        assert!(self.executor.is_main_thread());
360        &self.value
361    }
362}
363
364unsafe impl<T: ?Sized> Send for MainThreadOnly<T> {}