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