gpui3.rs

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