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