gpui3.rs

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