
This PR adds a component level state API to GPUI, as well as a few utilities for simplified interactions with entities Release Notes: - N/A
112 lines
3.6 KiB
Rust
112 lines
3.6 KiB
Rust
use proc_macro::TokenStream;
|
|
use quote::quote;
|
|
use syn::{DeriveInput, parse_macro_input};
|
|
|
|
use crate::get_simple_attribute_field;
|
|
|
|
pub fn derive_app_context(input: TokenStream) -> TokenStream {
|
|
let ast = parse_macro_input!(input as DeriveInput);
|
|
|
|
let Some(app_variable) = get_simple_attribute_field(&ast, "app") else {
|
|
return quote! {
|
|
compile_error!("Derive must have an #[app] attribute to detect the &mut App field");
|
|
}
|
|
.into();
|
|
};
|
|
|
|
let type_name = &ast.ident;
|
|
let (impl_generics, type_generics, where_clause) = ast.generics.split_for_impl();
|
|
|
|
let r#gen = quote! {
|
|
impl #impl_generics gpui::AppContext for #type_name #type_generics
|
|
#where_clause
|
|
{
|
|
type Result<T> = T;
|
|
|
|
fn new<T: 'static>(
|
|
&mut self,
|
|
build_entity: impl FnOnce(&mut gpui::Context<'_, T>) -> T,
|
|
) -> Self::Result<gpui::Entity<T>> {
|
|
self.#app_variable.new(build_entity)
|
|
}
|
|
|
|
fn reserve_entity<T: 'static>(&mut self) -> Self::Result<gpui::Reservation<T>> {
|
|
self.#app_variable.reserve_entity()
|
|
}
|
|
|
|
fn insert_entity<T: 'static>(
|
|
&mut self,
|
|
reservation: gpui::Reservation<T>,
|
|
build_entity: impl FnOnce(&mut gpui::Context<'_, T>) -> T,
|
|
) -> Self::Result<gpui::Entity<T>> {
|
|
self.#app_variable.insert_entity(reservation, build_entity)
|
|
}
|
|
|
|
fn update_entity<T, R>(
|
|
&mut self,
|
|
handle: &gpui::Entity<T>,
|
|
update: impl FnOnce(&mut T, &mut gpui::Context<'_, T>) -> R,
|
|
) -> Self::Result<R>
|
|
where
|
|
T: 'static,
|
|
{
|
|
self.#app_variable.update_entity(handle, update)
|
|
}
|
|
|
|
fn as_mut<'y, 'z, T>(
|
|
&'y mut self,
|
|
handle: &'z gpui::Entity<T>,
|
|
) -> Self::Result<gpui::GpuiBorrow<'y, T>>
|
|
where
|
|
T: 'static,
|
|
{
|
|
self.#app_variable.as_mut(handle)
|
|
}
|
|
|
|
fn read_entity<T, R>(
|
|
&self,
|
|
handle: &gpui::Entity<T>,
|
|
read: impl FnOnce(&T, &gpui::App) -> R,
|
|
) -> Self::Result<R>
|
|
where
|
|
T: 'static,
|
|
{
|
|
self.#app_variable.read_entity(handle, read)
|
|
}
|
|
|
|
fn update_window<T, F>(&mut self, window: gpui::AnyWindowHandle, f: F) -> gpui::Result<T>
|
|
where
|
|
F: FnOnce(gpui::AnyView, &mut gpui::Window, &mut gpui::App) -> T,
|
|
{
|
|
self.#app_variable.update_window(window, f)
|
|
}
|
|
|
|
fn read_window<T, R>(
|
|
&self,
|
|
window: &gpui::WindowHandle<T>,
|
|
read: impl FnOnce(gpui::Entity<T>, &gpui::App) -> R,
|
|
) -> gpui::Result<R>
|
|
where
|
|
T: 'static,
|
|
{
|
|
self.#app_variable.read_window(window, read)
|
|
}
|
|
|
|
fn background_spawn<R>(&self, future: impl std::future::Future<Output = R> + Send + 'static) -> gpui::Task<R>
|
|
where
|
|
R: Send + 'static,
|
|
{
|
|
self.#app_variable.background_spawn(future)
|
|
}
|
|
|
|
fn read_global<G, R>(&self, callback: impl FnOnce(&G, &gpui::App) -> R) -> Self::Result<R>
|
|
where
|
|
G: gpui::Global,
|
|
{
|
|
self.#app_variable.read_global(callback)
|
|
}
|
|
}
|
|
};
|
|
|
|
r#gen.into()
|
|
}
|