Skip to content

Commit 27aa8a4

Browse files
committed
Implement Convert trait / node for places we can't use Into
1 parent de38de1 commit 27aa8a4

File tree

3 files changed

+127
-11
lines changed

3 files changed

+127
-11
lines changed

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
@@ -608,6 +608,68 @@ where
608608
Box::pin(async move { input.into() })
609609
}
610610
}
611+
pub trait Convert<T>: Sized {
612+
/// Converts this type into the (usually inferred) input type.
613+
#[must_use]
614+
fn convert(self) -> T;
615+
}
616+
617+
macro_rules! impl_convert {
618+
($from:ty,$to:ty) => {
619+
impl Convert<$to> for $from {
620+
fn convert(self) -> $to {
621+
self as $to
622+
}
623+
}
624+
};
625+
($to:ty) => {
626+
impl_convert!(i8, $to);
627+
impl_convert!(u8, $to);
628+
impl_convert!(u16, $to);
629+
impl_convert!(i16, $to);
630+
impl_convert!(i32, $to);
631+
impl_convert!(u32, $to);
632+
impl_convert!(i64, $to);
633+
impl_convert!(u64, $to);
634+
impl_convert!(f32, $to);
635+
impl_convert!(f64, $to);
636+
};
637+
}
638+
impl_convert!(i8);
639+
impl_convert!(u8);
640+
impl_convert!(u16);
641+
impl_convert!(i16);
642+
impl_convert!(i32);
643+
impl_convert!(u32);
644+
impl_convert!(i64);
645+
impl_convert!(u64);
646+
impl_convert!(f32);
647+
impl_convert!(f64);
648+
649+
// Convert
650+
pub struct ConvertNode<O>(PhantomData<O>);
651+
impl<_O> ConvertNode<_O> {
652+
#[cfg(feature = "alloc")]
653+
pub const fn new() -> Self {
654+
Self(core::marker::PhantomData)
655+
}
656+
}
657+
impl<_O> Default for ConvertNode<_O> {
658+
fn default() -> Self {
659+
Self::new()
660+
}
661+
}
662+
impl<'input, I: 'input, _O: 'input> Node<'input, I> for ConvertNode<_O>
663+
where
664+
I: Convert<_O> + Sync + Send,
665+
{
666+
type Output = ::dyn_any::DynFuture<'input, _O>;
667+
668+
#[inline]
669+
fn eval(&'input self, input: I) -> Self::Output {
670+
Box::pin(async move { input.convert() })
671+
}
672+
}
611673

612674
#[cfg(test)]
613675
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,7 +15,7 @@ use graphene_std::GraphicElement;
1515
use graphene_std::any::{ComposeTypeErased, DowncastBothNode, DynAnyNode, IntoTypeErasedNode};
1616
use graphene_std::application_io::{ImageTexture, TextureFrameTable};
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;
@@ -25,10 +25,7 @@ use wgpu_executor::{WgpuExecutor, WgpuSurface, WindowHandle};
2525

2626
// TODO: turn into hashmap
2727
fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeConstructor>> {
28-
let node_types: Vec<(ProtoNodeIdentifier, NodeConstructor, NodeIOTypes)> = vec![
29-
into_node!(from: f64, to: f64),
30-
into_node!(from: u32, to: f64),
31-
into_node!(from: u8, to: u32),
28+
let mut node_types: Vec<(ProtoNodeIdentifier, NodeConstructor, NodeIOTypes)> = vec![
3229
into_node!(from: VectorDataTable, to: VectorDataTable),
3330
into_node!(from: VectorDataTable, to: GraphicElement),
3431
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)