Skip to content

Commit a7699c7

Browse files
committed
Implement Convert trait / node for places we can't use Into
1 parent 34bc28a commit a7699c7

3 files changed

Lines changed: 127 additions & 11 deletions

File tree

editor/src/messages/portfolio/document/node_graph/document_node_definitions/document_node_derive.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,19 @@ pub(super) fn post_process_nodes(mut custom: Vec<DocumentNodeDefinition>) -> Vec
101101
let into_node_identifier = ProtoNodeIdentifier {
102102
name: format!("graphene_core::ops::IntoNode<{}>", input_ty.clone()).into(),
103103
};
104+
let convert_node_identifier = ProtoNodeIdentifier {
105+
name: format!("graphene_core::ops::ConvertNode<{}>", input_ty.clone()).into(),
106+
};
104107
let proto_node = if into_node_registry.iter().any(|(ident, _)| {
105108
let ident = ident.name.as_ref();
106-
// log::debug!("checking: {} against {}", ident, into_node_identifier.name.as_ref());
107109
ident == into_node_identifier.name.as_ref()
108110
}) {
109-
// log::debug!("placing {}", into_node_identifier.name.as_ref());
110111
into_node_identifier
112+
} else if into_node_registry.iter().any(|(ident, _)| {
113+
let ident = ident.name.as_ref();
114+
ident == convert_node_identifier.name.as_ref()
115+
}) {
116+
convert_node_identifier
111117
} else {
112118
identity_node.clone()
113119
};
@@ -122,7 +128,7 @@ pub(super) fn post_process_nodes(mut custom: Vec<DocumentNodeDefinition>) -> Vec
122128
_ => DocumentNode {
123129
inputs: vec![NodeInput::network(generic!(X), i)],
124130
implementation: DocumentNodeImplementation::ProtoNode(identity_node.clone()),
125-
visible: true,
131+
visible: false,
126132
..Default::default()
127133
},
128134
},

node-graph/gcore/src/ops.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,68 @@ where
570570
Box::pin(async move { input.into() })
571571
}
572572
}
573+
pub trait Convert<T>: Sized {
574+
/// Converts this type into the (usually inferred) input type.
575+
#[must_use]
576+
fn convert(self) -> T;
577+
}
578+
579+
macro_rules! impl_convert {
580+
($from:ty,$to:ty) => {
581+
impl Convert<$to> for $from {
582+
fn convert(self) -> $to {
583+
self as $to
584+
}
585+
}
586+
};
587+
($to:ty) => {
588+
impl_convert!(i8, $to);
589+
impl_convert!(u8, $to);
590+
impl_convert!(u16, $to);
591+
impl_convert!(i16, $to);
592+
impl_convert!(i32, $to);
593+
impl_convert!(u32, $to);
594+
impl_convert!(i64, $to);
595+
impl_convert!(u64, $to);
596+
impl_convert!(f32, $to);
597+
impl_convert!(f64, $to);
598+
};
599+
}
600+
impl_convert!(i8);
601+
impl_convert!(u8);
602+
impl_convert!(u16);
603+
impl_convert!(i16);
604+
impl_convert!(i32);
605+
impl_convert!(u32);
606+
impl_convert!(i64);
607+
impl_convert!(u64);
608+
impl_convert!(f32);
609+
impl_convert!(f64);
610+
611+
// Convert
612+
pub struct ConvertNode<O>(PhantomData<O>);
613+
impl<_O> ConvertNode<_O> {
614+
#[cfg(feature = "alloc")]
615+
pub const fn new() -> Self {
616+
Self(core::marker::PhantomData)
617+
}
618+
}
619+
impl<_O> Default for ConvertNode<_O> {
620+
fn default() -> Self {
621+
Self::new()
622+
}
623+
}
624+
impl<'input, I: 'input, _O: 'input> Node<'input, I> for ConvertNode<_O>
625+
where
626+
I: Convert<_O> + Sync + Send,
627+
{
628+
type Output = ::dyn_any::DynFuture<'input, _O>;
629+
630+
#[inline]
631+
fn eval(&'input self, input: I) -> Self::Output {
632+
Box::pin(async move { input.convert() })
633+
}
634+
}
573635

574636
#[cfg(test)]
575637
mod test {

node-graph/interpreted-executor/src/node_registry.rs

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,15 @@ use graphene_std::GraphicElement;
1515
use graphene_std::any::{ComposeTypeErased, DowncastBothNode, DynAnyNode, IntoTypeErasedNode};
1616
use graphene_std::application_io::{ImageTexture, SurfaceFrame};
1717
use graphene_std::wasm_application_io::*;
18-
use node_registry_macros::{async_node, into_node};
18+
use node_registry_macros::{async_node, convert_node, into_node};
1919
use once_cell::sync::Lazy;
2020
use std::collections::HashMap;
2121
use std::sync::Arc;
2222
use wgpu_executor::{WgpuExecutor, WgpuSurface, WindowHandle};
2323

2424
// TODO: turn into hashmap
2525
fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeConstructor>> {
26-
let node_types: Vec<(ProtoNodeIdentifier, NodeConstructor, NodeIOTypes)> = vec![
27-
into_node!(from: f64, to: f64),
28-
into_node!(from: u32, to: f64),
29-
into_node!(from: u8, to: u32),
26+
let mut node_types: Vec<(ProtoNodeIdentifier, NodeConstructor, NodeIOTypes)> = vec![
3027
into_node!(from: VectorDataTable, to: VectorDataTable),
3128
into_node!(from: VectorDataTable, to: GraphicElement),
3229
into_node!(from: VectorDataTable, to: GraphicGroupTable),
@@ -137,6 +134,22 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
137134
},
138135
),
139136
];
137+
node_types.extend(
138+
[
139+
convert_node!(from: i8, to: numbers),
140+
convert_node!(from: u8, to: numbers),
141+
convert_node!(from: u16, to: numbers),
142+
convert_node!(from: i16, to: numbers),
143+
convert_node!(from: i32, to: numbers),
144+
convert_node!(from: u32, to: numbers),
145+
convert_node!(from: i64, to: numbers),
146+
convert_node!(from: u64, to: numbers),
147+
convert_node!(from: f32, to: numbers),
148+
convert_node!(from: f64, to: numbers),
149+
]
150+
.into_iter()
151+
.flatten(),
152+
);
140153

141154
let mut map: HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeConstructor>> = HashMap::new();
142155

@@ -152,7 +165,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
152165
// This might be caused by the stringify! macro
153166
let mut new_name = id.name.replace('\n', " ");
154167
// Remove struct generics for all nodes except for the IntoNode
155-
if !new_name.contains("IntoNode") {
168+
if !(new_name.contains("IntoNode") || new_name.contains("ConvertNode")) {
156169
if let Some((path, _generics)) = new_name.split_once("<") {
157170
new_name = path.to_string();
158171
}
@@ -203,9 +216,8 @@ mod node_registry_macros {
203216
(from: $from:ty, to: $to:ty) => {
204217
(
205218
ProtoNodeIdentifier::new(concat!["graphene_core::ops::IntoNode<", stringify!($to), ">"]),
206-
|mut args| {
219+
|_| {
207220
Box::pin(async move {
208-
args.reverse();
209221
let node = graphene_core::ops::IntoNode::<$to>::new();
210222
let any: DynAnyNode<$from, _, _> = graphene_std::any::DynAnyNode::new(node);
211223
Box::new(any) as TypeErasedBox
@@ -220,7 +232,43 @@ mod node_registry_macros {
220232
)
221233
};
222234
}
235+
macro_rules! convert_node {
236+
(from: $from:ty, to: numbers) => {{
237+
let x: Vec<(ProtoNodeIdentifier, NodeConstructor, NodeIOTypes)> = vec![
238+
convert_node!(from: $from, to: i8),
239+
convert_node!(from: $from, to: u8),
240+
convert_node!(from: $from, to: u16),
241+
convert_node!(from: $from, to: i16),
242+
convert_node!(from: $from, to: i32),
243+
convert_node!(from: $from, to: u32),
244+
convert_node!(from: $from, to: i64),
245+
convert_node!(from: $from, to: u64),
246+
convert_node!(from: $from, to: f32),
247+
convert_node!(from: $from, to: f64),
248+
];
249+
x
250+
}};
251+
(from: $from:ty, to: $to:ty) => {
252+
(
253+
ProtoNodeIdentifier::new(concat!["graphene_core::ops::ConvertNode<", stringify!($to), ">"]),
254+
|_| {
255+
Box::pin(async move {
256+
let node = graphene_core::ops::ConvertNode::<$to>::new();
257+
let any: DynAnyNode<$from, _, _> = graphene_std::any::DynAnyNode::new(node);
258+
Box::new(any) as TypeErasedBox
259+
})
260+
},
261+
{
262+
let node = graphene_core::ops::ConvertNode::<$to>::new();
263+
let mut node_io = NodeIO::<'_, $from>::to_async_node_io(&node, vec![]);
264+
node_io.call_argument = future!(<$from as StaticType>::Static);
265+
node_io
266+
},
267+
)
268+
};
269+
}
223270

224271
pub(crate) use async_node;
272+
pub(crate) use convert_node;
225273
pub(crate) use into_node;
226274
}

0 commit comments

Comments
 (0)