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