1mod app;
2mod color;
3mod element;
4mod elements;
5mod executor;
6mod geometry;
7mod platform;
8mod renderer;
9mod scene;
10mod style;
11mod style_helpers;
12mod styled;
13mod taffy;
14mod text_system;
15mod util;
16mod view;
17mod window;
18
19pub use anyhow::Result;
20pub use app::*;
21pub use color::*;
22pub use element::*;
23pub use elements::*;
24pub use executor::*;
25use futures::channel::oneshot;
26pub use geometry::*;
27pub use gpui3_macros::*;
28pub use platform::*;
29pub use refineable::*;
30pub use scene::*;
31pub use serde;
32pub use serde_json;
33pub use smallvec;
34pub use smol::Timer;
35use std::{
36 future::Future,
37 ops::{Deref, DerefMut},
38 sync::Arc,
39};
40pub use style::*;
41pub use style_helpers::*;
42pub use styled::*;
43use taffy::TaffyLayoutEngine;
44pub use taffy::{AvailableSpace, LayoutId};
45pub use text_system::*;
46pub use util::arc_cow::ArcCow;
47pub use view::*;
48pub use window::*;
49
50pub trait Context {
51 type EntityContext<'a, 'w, T: Send + 'static>;
52
53 fn entity<T: 'static + Send>(
54 &mut self,
55 build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
56 ) -> Handle<T>;
57
58 fn update_entity<T: 'static + Send, R>(
59 &mut self,
60 handle: &Handle<T>,
61 update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
62 ) -> R;
63}
64
65#[derive(Clone, Eq, PartialEq)]
66pub struct SharedString(ArcCow<'static, str>);
67
68impl Default for SharedString {
69 fn default() -> Self {
70 Self(ArcCow::Owned("".into()))
71 }
72}
73
74impl AsRef<str> for SharedString {
75 fn as_ref(&self) -> &str {
76 &self.0
77 }
78}
79
80impl std::fmt::Debug for SharedString {
81 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82 self.0.fmt(f)
83 }
84}
85
86impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
87 fn from(value: T) -> Self {
88 Self(value.into())
89 }
90}
91
92pub enum Reference<'a, T> {
93 Immutable(&'a T),
94 Mutable(&'a mut T),
95}
96
97impl<'a, T> Deref for Reference<'a, T> {
98 type Target = T;
99
100 fn deref(&self) -> &Self::Target {
101 match self {
102 Reference::Immutable(target) => target,
103 Reference::Mutable(target) => target,
104 }
105 }
106}
107
108impl<'a, T> DerefMut for Reference<'a, T> {
109 fn deref_mut(&mut self) -> &mut Self::Target {
110 match self {
111 Reference::Immutable(_) => {
112 panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
113 }
114 Reference::Mutable(target) => target,
115 }
116 }
117}
118
119pub(crate) struct MainThreadOnly<T: ?Sized> {
120 dispatcher: Arc<dyn PlatformDispatcher>,
121 value: Arc<T>,
122}
123
124impl<T: ?Sized> Clone for MainThreadOnly<T> {
125 fn clone(&self) -> Self {
126 Self {
127 dispatcher: self.dispatcher.clone(),
128 value: self.value.clone(),
129 }
130 }
131}
132
133/// Allows a value to be accessed only on the main thread, allowing a non-`Send` type
134/// to become `Send`.
135impl<T: 'static + ?Sized> MainThreadOnly<T> {
136 pub(crate) fn new(value: Arc<T>, dispatcher: Arc<dyn PlatformDispatcher>) -> Self {
137 Self { dispatcher, value }
138 }
139
140 pub(crate) fn borrow_on_main_thread(&self) -> &T {
141 assert!(self.dispatcher.is_main_thread());
142 &self.value
143 }
144
145 pub(crate) fn read<R>(
146 &self,
147 f: impl FnOnce(&T) -> R + Send + 'static,
148 ) -> impl Future<Output = R>
149 where
150 R: Send + 'static,
151 {
152 let (tx, rx) = oneshot::channel();
153 if self.dispatcher.is_main_thread() {
154 let _ = tx.send(f(&self.value));
155 } else {
156 let this = self.clone();
157 let _ = crate::spawn_on_main(self.dispatcher.clone(), async move {
158 // Required so we move `this` instead of this.value. Only `this` is `Send`.
159 let this = this;
160 let _ = tx.send(f(&this.value));
161 });
162 }
163
164 async move { rx.await.unwrap() }
165 }
166}
167
168unsafe impl<T: ?Sized> Send for MainThreadOnly<T> {}