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