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