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