gpui3.rs

  1mod app;
  2mod assets;
  3mod color;
  4mod element;
  5mod elements;
  6mod events;
  7mod executor;
  8mod geometry;
  9mod image_cache;
 10mod interactive;
 11mod platform;
 12mod scene;
 13mod style;
 14mod style_helpers;
 15mod styled;
 16mod svg_renderer;
 17mod taffy;
 18mod text_system;
 19mod util;
 20mod view;
 21mod window;
 22
 23pub use anyhow::Result;
 24pub use app::*;
 25pub use assets::*;
 26pub use color::*;
 27pub use element::*;
 28pub use elements::*;
 29pub use events::*;
 30pub use executor::*;
 31pub use geometry::*;
 32pub use gpui3_macros::*;
 33pub use image_cache::*;
 34pub use interactive::*;
 35pub use platform::*;
 36pub use refineable::*;
 37pub use scene::*;
 38pub use serde;
 39pub use serde_json;
 40pub use smallvec;
 41pub use smol::Timer;
 42pub use style::*;
 43pub use style_helpers::*;
 44pub use styled::*;
 45pub use svg_renderer::*;
 46pub use taffy::{AvailableSpace, LayoutId};
 47pub use text_system::*;
 48pub use util::arc_cow::ArcCow;
 49pub use view::*;
 50pub use window::*;
 51
 52use std::{
 53    any::Any,
 54    mem,
 55    ops::{Deref, DerefMut},
 56    sync::Arc,
 57};
 58use taffy::TaffyLayoutEngine;
 59
 60type AnyBox = Box<dyn Any + Send + Sync + 'static>;
 61
 62pub trait Context {
 63    type EntityContext<'a, 'w, T: 'static + Send + Sync>;
 64    type Result<T>;
 65
 66    fn entity<T: Send + Sync + 'static>(
 67        &mut self,
 68        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
 69    ) -> Self::Result<Handle<T>>;
 70
 71    fn update_entity<T: Send + Sync + 'static, R>(
 72        &mut self,
 73        handle: &Handle<T>,
 74        update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
 75    ) -> Self::Result<R>;
 76}
 77
 78#[repr(transparent)]
 79pub struct MainThread<T>(T);
 80
 81impl<T> Deref for MainThread<T> {
 82    type Target = T;
 83
 84    fn deref(&self) -> &Self::Target {
 85        &self.0
 86    }
 87}
 88
 89impl<T> DerefMut for MainThread<T> {
 90    fn deref_mut(&mut self) -> &mut Self::Target {
 91        &mut self.0
 92    }
 93}
 94
 95impl<C: Context> Context for MainThread<C> {
 96    type EntityContext<'a, 'w, T: 'static + Send + Sync> = MainThread<C::EntityContext<'a, 'w, T>>;
 97    type Result<T> = C::Result<T>;
 98
 99    fn entity<T: Send + Sync + 'static>(
100        &mut self,
101        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
102    ) -> Self::Result<Handle<T>> {
103        self.0.entity(|cx| {
104            let cx = unsafe {
105                mem::transmute::<
106                    &mut C::EntityContext<'_, '_, T>,
107                    &mut MainThread<C::EntityContext<'_, '_, T>>,
108                >(cx)
109            };
110            build_entity(cx)
111        })
112    }
113
114    fn update_entity<T: Send + Sync + 'static, R>(
115        &mut self,
116        handle: &Handle<T>,
117        update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
118    ) -> Self::Result<R> {
119        self.0.update_entity(handle, |entity, cx| {
120            let cx = unsafe {
121                mem::transmute::<
122                    &mut C::EntityContext<'_, '_, T>,
123                    &mut MainThread<C::EntityContext<'_, '_, T>>,
124                >(cx)
125            };
126            update(entity, cx)
127        })
128    }
129}
130
131pub trait BorrowAppContext {
132    fn app_mut(&mut self) -> &mut AppContext;
133
134    fn with_text_style<F, R>(&mut self, style: TextStyleRefinement, f: F) -> R
135    where
136        F: FnOnce(&mut Self) -> R,
137    {
138        self.app_mut().push_text_style(style);
139        let result = f(self);
140        self.app_mut().pop_text_style();
141        result
142    }
143
144    fn with_state<T: Send + Sync + 'static, F, R>(&mut self, state: T, f: F) -> R
145    where
146        F: FnOnce(&mut Self) -> R,
147    {
148        self.app_mut().push_state(state);
149        let result = f(self);
150        self.app_mut().pop_state::<T>();
151        result
152    }
153}
154
155pub trait Flatten<T> {
156    fn flatten(self) -> Result<T>;
157}
158
159impl<T> Flatten<T> for Result<Result<T>> {
160    fn flatten(self) -> Result<T> {
161        self?
162    }
163}
164
165impl<T> Flatten<T> for Result<T> {
166    fn flatten(self) -> Result<T> {
167        self
168    }
169}
170
171#[derive(Clone, Eq, PartialEq, Hash)]
172pub struct SharedString(ArcCow<'static, str>);
173
174impl Default for SharedString {
175    fn default() -> Self {
176        Self(ArcCow::Owned("".into()))
177    }
178}
179
180impl AsRef<str> for SharedString {
181    fn as_ref(&self) -> &str {
182        &self.0
183    }
184}
185
186impl std::fmt::Debug for SharedString {
187    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
188        self.0.fmt(f)
189    }
190}
191
192impl std::fmt::Display for SharedString {
193    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
194        write!(f, "{}", self.0.as_ref())
195    }
196}
197
198impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
199    fn from(value: T) -> Self {
200        Self(value.into())
201    }
202}
203
204pub enum Reference<'a, T> {
205    Immutable(&'a T),
206    Mutable(&'a mut T),
207}
208
209impl<'a, T> Deref for Reference<'a, T> {
210    type Target = T;
211
212    fn deref(&self) -> &Self::Target {
213        match self {
214            Reference::Immutable(target) => target,
215            Reference::Mutable(target) => target,
216        }
217    }
218}
219
220impl<'a, T> DerefMut for Reference<'a, T> {
221    fn deref_mut(&mut self) -> &mut Self::Target {
222        match self {
223            Reference::Immutable(_) => {
224                panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
225            }
226            Reference::Mutable(target) => target,
227        }
228    }
229}
230
231pub(crate) struct MainThreadOnly<T: ?Sized> {
232    executor: Executor,
233    value: Arc<T>,
234}
235
236impl<T: ?Sized> Clone for MainThreadOnly<T> {
237    fn clone(&self) -> Self {
238        Self {
239            executor: self.executor.clone(),
240            value: self.value.clone(),
241        }
242    }
243}
244
245/// Allows a value to be accessed only on the main thread, allowing a non-`Send` type
246/// to become `Send`.
247impl<T: 'static + ?Sized> MainThreadOnly<T> {
248    pub(crate) fn new(value: Arc<T>, executor: Executor) -> Self {
249        Self { executor, value }
250    }
251
252    pub(crate) fn borrow_on_main_thread(&self) -> &T {
253        assert!(self.executor.is_main_thread());
254        &self.value
255    }
256}
257
258unsafe impl<T: ?Sized> Send for MainThreadOnly<T> {}