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