Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
DocumentNode {
inputs: vec![NodeInput::import(concrete!(Table<Raster<CPU>>), 0), NodeInput::node(NodeId(0), 0)],
call_argument: generic!(T),
implementation: DocumentNodeImplementation::ProtoNode(wgpu_executor::texture_upload::upload_texture::IDENTIFIER),
implementation: DocumentNodeImplementation::ProtoNode(wgpu_executor::texture_conversion::upload_texture::IDENTIFIER),
..Default::default()
},
DocumentNode {
Expand Down
19 changes: 10 additions & 9 deletions node-graph/gcore/src/ops.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::Node;
use graphene_core_shaders::Ctx;

use crate::{ExtractFootprint, Node, transform::Footprint};
use std::marker::PhantomData;

// TODO: Rename to "Passthrough"
Expand Down Expand Up @@ -49,25 +50,25 @@ fn into<'i, T: 'i + Send + Into<O>, O: 'i + Send>(_: impl Ctx, value: T, _out_ty

/// The [`Convert`] trait allows for conversion between Rust primitive numeric types.
/// Because number casting is lossy, we cannot use the normal [`Into`] trait like we do for other types.
pub trait Convert<T>: Sized {
pub trait Convert<T, C>: Sized {
/// Converts this type into the (usually inferred) output type.
#[must_use]
fn convert(self) -> T;
fn convert(self, footprint: Footprint, converter: C) -> impl Future<Output = T> + Send;
}

impl<T: ToString> Convert<String> for T {
impl<T: ToString + Send> Convert<String, ()> for T {
/// Converts this type into a `String` using its `ToString` implementation.
#[inline]
fn convert(self) -> String {
async fn convert(self, _: Footprint, _converter: ()) -> String {
self.to_string()
}
}

/// Implements the [`Convert`] trait for conversion between the cartesian product of Rust's primitive numeric types.
macro_rules! impl_convert {
($from:ty, $to:ty) => {
impl Convert<$to> for $from {
fn convert(self) -> $to {
impl Convert<$to, ()> for $from {
async fn convert(self, _: Footprint, _: ()) -> $to {
self as $to
}
}
Expand Down Expand Up @@ -105,8 +106,8 @@ impl_convert!(isize);
impl_convert!(usize);

#[node_macro::node(skip_impl)]
fn convert<'i, T: 'i + Send + Convert<O>, O: 'i + Send>(_: impl Ctx, value: T, _out_ty: PhantomData<O>) -> O {
value.convert()
async fn convert<'i, T: 'i + Send + Convert<O, C>, O: 'i + Send, C: 'i + Send>(ctx: impl Ctx + ExtractFootprint, value: T, converter: C, _out_ty: PhantomData<O>) -> O {
value.convert(*ctx.try_footprint().unwrap_or(&Footprint::DEFAULT), converter).await
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion node-graph/gcore/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::sync::{LazyLock, Mutex};
pub use graphene_core_shaders::registry::types;

// Translation struct between macro and definition
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct NodeMetadata {
pub display_name: &'static str,
pub category: Option<&'static str>,
Expand Down
25 changes: 19 additions & 6 deletions node-graph/interpreted-executor/src/node_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
convert_node!(from: DVec2, to: String),
convert_node!(from: IVec2, to: String),
convert_node!(from: DAffine2, to: String),
convert_node!(from: Table<Raster<CPU>>, to: Table<Raster<CPU>>, converter: &WgpuExecutor),
convert_node!(from: Table<Raster<CPU>>, to: Table<Raster<GPU>>, converter: &WgpuExecutor),
convert_node!(from: Table<Raster<GPU>>, to: Table<Raster<GPU>>, converter: &WgpuExecutor),
convert_node!(from: Table<Raster<GPU>>, to: Table<Raster<CPU>>, converter: &WgpuExecutor),
// =============
// MONITOR NODES
// =============
Expand Down Expand Up @@ -394,21 +398,30 @@ mod node_registry_macros {
x
}};
(from: $from:ty, to: $to:ty) => {
convert_node!(from: $from, to: $to, converter: ())
};
(from: $from:ty, to: $to:ty, converter: $convert:ty) => {
(
ProtoNodeIdentifier::new(concat!["graphene_core::ops::ConvertNode<", stringify!($to), ">"]),
|mut args| {
Box::pin(async move {
let node = graphene_core::ops::ConvertNode::new(graphene_std::any::downcast_node::<Context, $from>(args.pop().unwrap()),
graphene_std::any::FutureWrapperNode::new(graphene_std::value::ClonedNode::new(std::marker::PhantomData::<$to>)) );
let mut args = args.drain(..);
let node = graphene_core::ops::ConvertNode::new(
graphene_std::any::downcast_node::<Context, $from>(args.next().expect("Convert node did not get first argument")),
graphene_std::any::downcast_node::<Context, $convert>(args.next().expect("Convert node did not get converter argument")),
graphene_std::any::FutureWrapperNode::new(graphene_std::value::ClonedNode::new(std::marker::PhantomData::<$to>))
);
let any: DynAnyNode<Context, $to, _> = graphene_std::any::DynAnyNode::new(node);
Box::new(any) as TypeErasedBox
})
},
{
let node = graphene_core::ops::ConvertNode::new(graphene_std::any::PanicNode::<Context, core::pin::Pin<Box<dyn core::future::Future<Output = $from> + Send>>>::new(),

graphene_std::any::FutureWrapperNode::new(graphene_std::value::ClonedNode::new(std::marker::PhantomData::<$to>)) );
let params = vec![fn_type_fut!(Context, $from)];
let node = graphene_core::ops::ConvertNode::new(
graphene_std::any::PanicNode::<Context, core::pin::Pin<Box<dyn core::future::Future<Output = $from> + Send>>>::new(),
graphene_std::any::PanicNode::<Context, core::pin::Pin<Box<dyn core::future::Future<Output = $convert> + Send>>>::new(),
graphene_std::any::FutureWrapperNode::new(graphene_std::value::ClonedNode::new(std::marker::PhantomData::<$to>))
);
let params = vec![fn_type_fut!(Context, $from), fn_type_fut!(Context, $convert)];
let node_io = NodeIO::<'_, Context>::to_async_node_io(&node, params);
node_io
},
Expand Down
2 changes: 1 addition & 1 deletion node-graph/node-macro/src/shader_nodes/per_pixel_adjust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl PerPixelAdjustCodegen<'_> {
#(pub #uniform_members),*
}
};
let uniform_struct_shader_struct_derive = crate::buffer_struct::derive_buffer_struct_struct(&self.crate_ident, &uniform_struct)?;
let uniform_struct_shader_struct_derive = crate::buffer_struct::derive_buffer_struct_struct(self.crate_ident, &uniform_struct)?;

let image_params = self
.params
Expand Down
4 changes: 3 additions & 1 deletion node-graph/preprocessor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ pub fn generate_node_substitutions() -> HashMap<ProtoNodeIdentifier, DocumentNod
1 => {
let input = inputs.iter().next().unwrap();
let input_ty = input.nested_type();
let mut inputs = vec![NodeInput::import(input.clone(), i)];

let into_node_identifier = ProtoNodeIdentifier {
name: format!("graphene_core::ops::IntoNode<{}>", input_ty.clone()).into(),
Expand All @@ -80,13 +81,14 @@ pub fn generate_node_substitutions() -> HashMap<ProtoNodeIdentifier, DocumentNod
into_node_identifier
} else if into_node_registry.keys().any(|ident| ident.name.as_ref() == convert_node_identifier.name.as_ref()) {
generated_nodes += 1;
inputs.push(NodeInput::value(TaggedValue::None, false));
convert_node_identifier
} else {
identity_node.clone()
};

DocumentNode {
inputs: vec![NodeInput::import(input.clone(), i)],
inputs,
implementation: DocumentNodeImplementation::ProtoNode(proto_node),
visible: true,
..Default::default()
Expand Down
2 changes: 1 addition & 1 deletion node-graph/wgpu-executor/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod context;
pub mod shader_runtime;
pub mod texture_upload;
pub mod texture_conversion;

use crate::shader_runtime::ShaderRuntime;
use anyhow::Result;
Expand Down
Loading
Loading