mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Restructure node crates (#3384)
* Restructure node-graph folder * Fix wasm compilation * Move node definitions out of *-types crates * Cleanup * Fix warnings * Fix warnings * Start adding migrations * Add migrations and move memo nodes to gcore * Move nodes/gsvg-render -> rendering * Replace some hard coded identifiers and fix automatic conversion * Fix Vec2Value node migration * Fix formatting * Add more migrations * Cleanup features * Fix core_types::raster import * Update demo artwork (to make profile ci work) * Move *-types to node-graph/libraries folder * Add missing node migrations * Migrate more nodes * Remove impure memo node * More fixes and remove warning * Migrate context and add a few missing migrations --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
@@ -26,5 +26,5 @@ proc-macro-crate = "3.1.0"
|
||||
proc-macro-error2 = "2"
|
||||
|
||||
[dev-dependencies]
|
||||
graphene-core = { workspace = true }
|
||||
graphene-core-shaders = { workspace = true }
|
||||
core-types = { workspace = true }
|
||||
no-std-types = { workspace = true }
|
||||
|
||||
@@ -62,7 +62,7 @@ pub fn derive_buffer_struct_enum(crate_ident: &CrateIdent, item: &ItemEnum) -> R
|
||||
///
|
||||
/// This is also largely copied from my (@firestar99) project and adjusted
|
||||
///
|
||||
/// [`BufferStruct`]: `graphene_core_shaders::shaders::buffer_struct::BufferStruct`
|
||||
/// [`BufferStruct`]: `no_std_types::shaders::buffer_struct::BufferStruct`
|
||||
pub fn derive_buffer_struct_struct(crate_ident: &CrateIdent, item: &ItemStruct) -> Result<TokenStream> {
|
||||
let gcore_shaders = crate_ident.gcore_shaders()?;
|
||||
let mod_buffer_struct = quote!(#gcore_shaders::shaders::buffer_struct);
|
||||
|
||||
@@ -26,7 +26,7 @@ pub(crate) fn generate_node_code(crate_ident: &CrateIdent, parsed: &ParsedNodeFn
|
||||
description,
|
||||
..
|
||||
} = parsed;
|
||||
let graphene_core = crate_ident.gcore()?;
|
||||
let core_types = crate_ident.gcore()?;
|
||||
|
||||
let category = &attributes.category.as_ref().map(|value| quote!(Some(#value))).unwrap_or(quote!(None));
|
||||
let mod_name = format_ident!("_{}_mod", mod_name);
|
||||
@@ -68,8 +68,8 @@ pub(crate) fn generate_node_code(crate_ident: &CrateIdent, parsed: &ParsedNodeFn
|
||||
.map(|field| match &field.ty {
|
||||
ParsedFieldType::Regular(RegularParsedField { ty, .. }) => ty.clone(),
|
||||
ParsedFieldType::Node(NodeParsedField { output_type, input_type, .. }) => match parsed.is_async {
|
||||
true => parse_quote!(&'n impl #graphene_core::Node<'n, #input_type, Output = impl core::future::Future<Output=#output_type>>),
|
||||
false => parse_quote!(&'n impl #graphene_core::Node<'n, #input_type, Output = #output_type>),
|
||||
true => parse_quote!(&'n impl #core_types::Node<'n, #input_type, Output = impl core::future::Future<Output=#output_type>>),
|
||||
false => parse_quote!(&'n impl #core_types::Node<'n, #input_type, Output = #output_type>),
|
||||
},
|
||||
})
|
||||
.collect();
|
||||
@@ -181,13 +181,13 @@ pub(crate) fn generate_node_code(crate_ident: &CrateIdent, parsed: &ParsedNodeFn
|
||||
let mut tokens = quote!();
|
||||
if let Some(min) = number_hard_min {
|
||||
tokens.extend(quote_spanned! {min.span()=>
|
||||
let #name = #graphene_core::misc::Clampable::clamp_hard_min(#name, #min);
|
||||
let #name = #core_types::misc::Clampable::clamp_hard_min(#name, #min);
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(max) = number_hard_max {
|
||||
tokens.extend(quote_spanned! {max.span()=>
|
||||
let #name = #graphene_core::misc::Clampable::clamp_hard_max(#name, #max);
|
||||
let #name = #core_types::misc::Clampable::clamp_hard_max(#name, #max);
|
||||
});
|
||||
}
|
||||
tokens
|
||||
@@ -224,13 +224,13 @@ pub(crate) fn generate_node_code(crate_ident: &CrateIdent, parsed: &ParsedNodeFn
|
||||
// Add Clampable bound if this field uses hard_min or hard_max
|
||||
if number_hard_min.is_some() || number_hard_max.is_some() {
|
||||
// The bound applies to the Output type of the future, which is #ty
|
||||
clampable_clauses.push(quote!(#ty: #graphene_core::misc::Clampable));
|
||||
clampable_clauses.push(quote!(#ty: #core_types::misc::Clampable));
|
||||
}
|
||||
|
||||
quote!(
|
||||
#fut_ident: core::future::Future<Output = #ty> + #graphene_core::WasmNotSend + 'n,
|
||||
for<'all> #all_lifetime_ty: #graphene_core::WasmNotSend,
|
||||
#name: #graphene_core::Node<'n, #input_type, Output = #fut_ident> + #graphene_core::WasmNotSync
|
||||
#fut_ident: core::future::Future<Output = #ty> + #core_types::WasmNotSend + 'n,
|
||||
for<'all> #all_lifetime_ty: #core_types::WasmNotSend,
|
||||
#name: #core_types::Node<'n, #input_type, Output = #fut_ident> + #core_types::WasmNotSync
|
||||
)
|
||||
}
|
||||
(ParsedFieldType::Node(NodeParsedField { input_type, output_type, .. }), true) => {
|
||||
@@ -239,8 +239,8 @@ pub(crate) fn generate_node_code(crate_ident: &CrateIdent, parsed: &ParsedNodeFn
|
||||
future_idents.push(fut_ident.clone());
|
||||
|
||||
quote!(
|
||||
#fut_ident: core::future::Future<Output = #output_type> + #graphene_core::WasmNotSend + 'n,
|
||||
#name: #graphene_core::Node<'n, #input_type, Output = #fut_ident > + #graphene_core::WasmNotSync
|
||||
#fut_ident: core::future::Future<Output = #output_type> + #core_types::WasmNotSend + 'n,
|
||||
#name: #core_types::Node<'n, #input_type, Output = #fut_ident > + #core_types::WasmNotSync
|
||||
)
|
||||
}
|
||||
(ParsedFieldType::Node { .. }, false) => unreachable!("Found node which takes an impl Node<> input but is not async"),
|
||||
@@ -267,11 +267,11 @@ pub(crate) fn generate_node_code(crate_ident: &CrateIdent, parsed: &ParsedNodeFn
|
||||
let await_keyword = is_async.then(|| quote!(.await));
|
||||
|
||||
let eval_impl = quote! {
|
||||
type Output = #graphene_core::registry::DynFuture<'n, #output_type>;
|
||||
type Output = #core_types::registry::DynFuture<'n, #output_type>;
|
||||
#[inline]
|
||||
fn eval(&'n self, __input: #input_type) -> Self::Output {
|
||||
Box::pin(async move {
|
||||
use #graphene_core::misc::Clampable;
|
||||
use #core_types::misc::Clampable;
|
||||
|
||||
#(#eval_args)*
|
||||
#(#min_max_args)*
|
||||
@@ -295,7 +295,7 @@ pub(crate) fn generate_node_code(crate_ident: &CrateIdent, parsed: &ParsedNodeFn
|
||||
let properties = &attributes.properties_string.as_ref().map(|value| quote!(Some(#value))).unwrap_or(quote!(None));
|
||||
|
||||
let cfg = crate::shader_nodes::modify_cfg(attributes);
|
||||
let node_input_accessor = generate_node_input_references(parsed, fn_generics, &field_idents, graphene_core, &identifier, &cfg);
|
||||
let node_input_accessor = generate_node_input_references(parsed, fn_generics, &field_idents, core_types, &identifier, &cfg);
|
||||
let ShaderTokens { shader_entry_point, gpu_node } = attributes.shader_node.as_ref().map(|n| n.codegen(crate_ident, parsed)).unwrap_or(Ok(ShaderTokens::default()))?;
|
||||
|
||||
Ok(quote! {
|
||||
@@ -306,15 +306,15 @@ pub(crate) fn generate_node_code(crate_ident: &CrateIdent, parsed: &ParsedNodeFn
|
||||
|
||||
#cfg
|
||||
#[automatically_derived]
|
||||
impl<'n, #(#fn_generics,)* #(#struct_generics,)* #(#future_idents,)*> #graphene_core::Node<'n, #input_type> for #mod_name::#struct_name<#(#struct_generics,)*>
|
||||
impl<'n, #(#fn_generics,)* #(#struct_generics,)* #(#future_idents,)*> #core_types::Node<'n, #input_type> for #mod_name::#struct_name<#(#struct_generics,)*>
|
||||
#struct_where_clause
|
||||
{
|
||||
#eval_impl
|
||||
}
|
||||
|
||||
#cfg
|
||||
const fn #identifier() -> #graphene_core::ProtoNodeIdentifier {
|
||||
#graphene_core::ProtoNodeIdentifier::new(std::concat!(#identifier_path, "::", std::stringify!(#struct_name)))
|
||||
const fn #identifier() -> #core_types::ProtoNodeIdentifier {
|
||||
#core_types::ProtoNodeIdentifier::new(std::concat!(#identifier_path, "::", std::stringify!(#struct_name)))
|
||||
}
|
||||
|
||||
#cfg
|
||||
@@ -329,7 +329,7 @@ pub(crate) fn generate_node_code(crate_ident: &CrateIdent, parsed: &ParsedNodeFn
|
||||
#[allow(clippy::module_inception)]
|
||||
mod #mod_name {
|
||||
use super::*;
|
||||
use #graphene_core as gcore;
|
||||
use #core_types as gcore;
|
||||
use gcore::{Node, NodeIOTypes, concrete, fn_type, fn_type_fut, future, ProtoNodeIdentifier, WasmNotSync, NodeIO, ContextFeature};
|
||||
use gcore::value::ClonedNode;
|
||||
use gcore::ops::TypeNode;
|
||||
@@ -400,7 +400,7 @@ fn generate_node_input_references(
|
||||
parsed: &ParsedNodeFn,
|
||||
fn_generics: &[crate::GenericParam],
|
||||
field_idents: &[&PatIdent],
|
||||
graphene_core: &TokenStream2,
|
||||
core_types: &TokenStream2,
|
||||
identifier: &Ident,
|
||||
cfg: &TokenStream2,
|
||||
) -> TokenStream2 {
|
||||
@@ -436,9 +436,9 @@ fn generate_node_input_references(
|
||||
}
|
||||
});
|
||||
generated_input_accessor.push(quote! {
|
||||
impl <#(#used),*> #graphene_core::NodeInputDecleration for #struct_name <#(#fn_generic_params),*> {
|
||||
impl <#(#used),*> #core_types::NodeInputDecleration for #struct_name <#(#fn_generic_params),*> {
|
||||
const INDEX: usize = #input_index;
|
||||
fn identifier() -> #graphene_core::ProtoNodeIdentifier {
|
||||
fn identifier() -> #core_types::ProtoNodeIdentifier {
|
||||
#inputs_module_name::IDENTIFIER.clone()
|
||||
}
|
||||
type Result = #ty;
|
||||
@@ -453,7 +453,7 @@ fn generate_node_input_references(
|
||||
use super::*;
|
||||
|
||||
/// The `ProtoNodeIdentifier` of this node without any generics attached to it
|
||||
pub const IDENTIFIER: #graphene_core::ProtoNodeIdentifier = #identifier();
|
||||
pub const IDENTIFIER: #core_types::ProtoNodeIdentifier = #identifier();
|
||||
#(#generated_input_accessor)*
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ use quote::{format_ident, quote};
|
||||
pub struct CrateIdent {
|
||||
gcore: syn::Result<TokenStream>,
|
||||
gcore_shaders: syn::Result<TokenStream>,
|
||||
raster_types: syn::Result<TokenStream>,
|
||||
wgpu_executor: syn::Result<TokenStream>,
|
||||
}
|
||||
|
||||
@@ -17,6 +18,10 @@ impl CrateIdent {
|
||||
self.gcore_shaders.as_ref().map_err(Clone::clone)
|
||||
}
|
||||
|
||||
pub fn raster_types(&self) -> syn::Result<&TokenStream> {
|
||||
self.raster_types.as_ref().map_err(Clone::clone)
|
||||
}
|
||||
|
||||
pub fn wgpu_executor(&self) -> syn::Result<&TokenStream> {
|
||||
self.wgpu_executor.as_ref().map_err(Clone::clone)
|
||||
}
|
||||
@@ -33,9 +38,15 @@ impl Default for CrateIdent {
|
||||
Err(e) => Err(syn::Error::new(Span::call_site(), format!("Could not find dependency on `{orig_name}`:\n{e}"))),
|
||||
};
|
||||
|
||||
let gcore = find_crate("graphene-core");
|
||||
let gcore_shaders = find_crate("graphene-core-shaders").or_else(|eshaders| gcore.clone().map_err(|ecore| syn::Error::new(Span::call_site(), format!("{ecore}\n\nFallback: {eshaders}"))));
|
||||
let gcore = find_crate("core-types");
|
||||
let gcore_shaders = find_crate("no-std-types").or_else(|eshaders| gcore.clone().map_err(|ecore| syn::Error::new(Span::call_site(), format!("{ecore}\n\nFallback: {eshaders}"))));
|
||||
let raster_types = find_crate("raster-types");
|
||||
let wgpu_executor = find_crate("wgpu-executor");
|
||||
Self { gcore, gcore_shaders, wgpu_executor }
|
||||
Self {
|
||||
gcore,
|
||||
gcore_shaders,
|
||||
raster_types,
|
||||
wgpu_executor,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,14 +110,12 @@ fn derive_enum(enum_attributes: &[Attribute], name: Ident, input: syn::DataEnum)
|
||||
.collect();
|
||||
|
||||
let crate_name = {
|
||||
let crate_name = proc_macro_crate::crate_name("graphene-core-shaders")
|
||||
.or_else(|_e| proc_macro_crate::crate_name("graphene-core"))
|
||||
.map_err(|e| {
|
||||
syn::Error::new(
|
||||
Span::call_site(),
|
||||
format!("Failed to find location of 'graphene_core' or 'graphene-core-shaders'. Make sure it is imported as a dependency: {e}"),
|
||||
)
|
||||
})?;
|
||||
let crate_name = proc_macro_crate::crate_name("no-std-types").or_else(|_e| proc_macro_crate::crate_name("core-types")).map_err(|e| {
|
||||
syn::Error::new(
|
||||
Span::call_site(),
|
||||
format!("Failed to find location of 'no-std-types' or 'core-types'. Make sure it is imported as a dependency: {e}"),
|
||||
)
|
||||
})?;
|
||||
match crate_name {
|
||||
proc_macro_crate::FoundCrate::Itself => quote!(crate),
|
||||
proc_macro_crate::FoundCrate::Name(name) => {
|
||||
|
||||
@@ -804,7 +804,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_basic_node() {
|
||||
let attr = quote!(category("Math: Arithmetic"), path(graphene_core::TestNode), skip_impl);
|
||||
let attr = quote!(category("Math: Arithmetic"), path(core_types::TestNode), skip_impl);
|
||||
let input = quote!(
|
||||
/// Multi
|
||||
/// Line
|
||||
@@ -819,7 +819,7 @@ mod tests {
|
||||
attributes: NodeFnAttributes {
|
||||
category: Some(parse_quote!("Math: Arithmetic")),
|
||||
display_name: None,
|
||||
path: Some(parse_quote!(graphene_core::TestNode)),
|
||||
path: Some(parse_quote!(core_types::TestNode)),
|
||||
skip_impl: true,
|
||||
properties_string: None,
|
||||
cfg: None,
|
||||
@@ -1080,7 +1080,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_number_min_max_range_mode() {
|
||||
let attr = quote!(category("Math: Arithmetic"), path(graphene_core::TestNode));
|
||||
let attr = quote!(category("Math: Arithmetic"), path(core_types::TestNode));
|
||||
let input = quote!(
|
||||
fn add(
|
||||
a: f64,
|
||||
@@ -1100,7 +1100,7 @@ mod tests {
|
||||
attributes: NodeFnAttributes {
|
||||
category: Some(parse_quote!("Math: Arithmetic")),
|
||||
display_name: None,
|
||||
path: Some(parse_quote!(graphene_core::TestNode)),
|
||||
path: Some(parse_quote!(core_types::TestNode)),
|
||||
skip_impl: false,
|
||||
properties_string: None,
|
||||
cfg: None,
|
||||
|
||||
@@ -182,10 +182,11 @@ impl PerPixelAdjustCodegen<'_> {
|
||||
|
||||
fn codegen_gpu_node(&self) -> syn::Result<TokenStream> {
|
||||
let gcore = self.crate_ident.gcore()?;
|
||||
let raster_types = self.crate_ident.raster_types()?;
|
||||
let wgpu_executor = self.crate_ident.wgpu_executor()?;
|
||||
|
||||
// adapt fields for gpu node
|
||||
let raster_gpu: Type = parse_quote!(#gcore::table::Table<#gcore::raster_types::Raster<#gcore::raster_types::GPU>>);
|
||||
let raster_gpu: Type = parse_quote!(#gcore::table::Table<#raster_types::Raster<#raster_types::GPU>>);
|
||||
let mut fields = self
|
||||
.parsed
|
||||
.fields
|
||||
|
||||
Reference in New Issue
Block a user