From c7fef30cf1fdead32f042ce4683000380d1b1573 Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Thu, 30 Jul 2026 11:51:13 +0000 Subject: [PATCH] Delete the old erased node machinery --- node-graph/graph-craft/src/document/value.rs | 35 +-- .../src/dynamic_executor.rs | 2 +- .../libraries/core-types/src/registry.rs | 229 +----------------- node-graph/nodes/gstd/src/any.rs | 27 --- node-graph/nodes/gstd/src/lib.rs | 1 - 5 files changed, 4 insertions(+), 290 deletions(-) delete mode 100644 node-graph/nodes/gstd/src/any.rs diff --git a/node-graph/graph-craft/src/document/value.rs b/node-graph/graph-craft/src/document/value.rs index 35458cb5b0..42d1574e3b 100644 --- a/node-graph/graph-craft/src/document/value.rs +++ b/node-graph/graph-craft/src/document/value.rs @@ -1,7 +1,7 @@ use super::DocumentNode; use crate::application_io::PlatformEditorApi; use crate::application_io::resource::Resource; -use crate::proto::{Any as DAny, FutureAny}; +use crate::proto::Any as DAny; use brush_nodes::brush_stroke::BrushStroke; use core_types::color::SRGBA8; use core_types::list::List; @@ -767,39 +767,6 @@ impl Display for TaggedValue { } } -pub struct UpcastNode { - value: MemoHash, -} -impl<'input> Node<'input, DAny<'input>> for UpcastNode { - type Output = FutureAny<'input>; - - fn eval(&'input self, _: DAny<'input>) -> Self::Output { - let memo_clone = MemoHash::clone(&self.value); - Box::pin(async move { memo_clone.into_inner().as_ref().clone().to_dynany() }) - } -} -impl UpcastNode { - pub fn new(value: MemoHash) -> Self { - Self { value } - } -} -#[derive(Default, Debug, Clone, Copy)] -pub struct UpcastAsRefNode + Sync + Send, U: Sync + Send>(pub T, PhantomData); - -impl<'i, T: 'i + AsRef + Sync + Send, U: 'i + StaticType + Sync + Send> Node<'i, DAny<'i>> for UpcastAsRefNode { - type Output = FutureAny<'i>; - #[inline(always)] - fn eval(&'i self, _: DAny<'i>) -> Self::Output { - Box::pin(async move { Box::new(self.0.as_ref()) as DAny<'i> }) - } -} - -impl + Sync + Send, U: Sync + Send> UpcastAsRefNode { - pub const fn new(value: T) -> UpcastAsRefNode { - UpcastAsRefNode(value, PhantomData) - } -} - #[derive(Debug, Clone, PartialEq, dyn_any::DynAny, serde::Serialize, serde::Deserialize)] pub struct RenderOutput { pub data: RenderOutputType, diff --git a/node-graph/interpreted-executor/src/dynamic_executor.rs b/node-graph/interpreted-executor/src/dynamic_executor.rs index 5289fd90b2..4596c8af64 100644 --- a/node-graph/interpreted-executor/src/dynamic_executor.rs +++ b/node-graph/interpreted-executor/src/dynamic_executor.rs @@ -233,7 +233,7 @@ impl std::fmt::Display for IntrospectError { /// /// # Fields /// -/// * `nodes`: A [`HashMap`] of [`NodeId`]s to tuples of [`SharedNodeContainer`] and [`Path`]. +/// * `nodes`: A [`HashMap`] of [`NodeId`]s to tuples of [`EdgeHandle`] and [`Path`]. /// This stores the actual node instances and their associated paths. /// /// * `source_map`: A [`HashMap`] from [`Path`] to tuples of [`NodeId`] and [`NodeTypes`]. diff --git a/node-graph/libraries/core-types/src/registry.rs b/node-graph/libraries/core-types/src/registry.rs index 6034166b3a..02c9498346 100644 --- a/node-graph/libraries/core-types/src/registry.rs +++ b/node-graph/libraries/core-types/src/registry.rs @@ -1,14 +1,12 @@ use crate::concrete; use crate::context::{Context, ContextImpl}; use crate::gnode::GNode; -use crate::{ContextFeature, Node, NodeIO, ProtoNodeIdentifier, Type, WasmNotSend, WasmNotSync}; -use dyn_any::{DynAny, StaticType}; +use crate::{ContextFeature, ProtoNodeIdentifier, Type, WasmNotSend, WasmNotSync}; +use dyn_any::DynAny; use graphene_hash::CacheHash; pub use no_std_types::registry::types; use std::collections::HashMap; use std::hash::Hasher; -use std::marker::PhantomData; -use std::ops::Deref; use std::pin::Pin; use std::sync::{LazyLock, Mutex}; @@ -269,234 +267,11 @@ pub fn construct(entry: &RegistryEntry, inputs: Vec) -> Result = Pin + 'n + Send>>; -#[cfg(target_family = "wasm")] -pub type DynFuture<'n, T> = Pin + 'n>>; pub type LocalFuture<'n, T> = Pin + 'n>>; #[cfg(not(target_family = "wasm"))] pub type Any<'n> = Box + 'n + Send>; #[cfg(target_family = "wasm")] pub type Any<'n> = Box + 'n>; -pub type FutureAny<'n> = DynFuture<'n, Any<'n>>; -// TODO: is this safe? This is assumed to be send+sync. -#[cfg(not(target_family = "wasm"))] -pub type TypeErasedNode<'n> = dyn for<'i> NodeIO<'i, Any<'i>, Output = FutureAny<'i>> + 'n + Send + Sync; -#[cfg(target_family = "wasm")] -pub type TypeErasedNode<'n> = dyn for<'i> NodeIO<'i, Any<'i>, Output = FutureAny<'i>> + 'n; -pub type TypeErasedPinnedRef<'n> = Pin<&'n TypeErasedNode<'n>>; -pub type TypeErasedRef<'n> = &'n TypeErasedNode<'n>; -pub type TypeErasedBox<'n> = Box>; -pub type TypeErasedPinned<'n> = Pin>>; - -pub type SharedNodeContainer = std::sync::Arc; - -pub type DynNodeConstructor = fn(Vec) -> DynFuture<'static, TypeErasedBox<'static>>; - -#[derive(Clone)] -pub struct NodeContainer { - #[cfg(feature = "dealloc_nodes")] - pub node: *const TypeErasedNode<'static>, - #[cfg(not(feature = "dealloc_nodes"))] - pub node: TypeErasedRef<'static>, -} - -impl Deref for NodeContainer { - type Target = TypeErasedNode<'static>; - - #[cfg(feature = "dealloc_nodes")] - fn deref(&self) -> &Self::Target { - unsafe { &*(self.node) } - #[cfg(not(feature = "dealloc_nodes"))] - self.node - } - #[cfg(not(feature = "dealloc_nodes"))] - fn deref(&self) -> &Self::Target { - self.node - } -} - -/// # Safety -/// Marks NodeContainer as Sync. This dissallows the use of threadlocal storage for nodes as this would invalidate references to them. -// TODO: implement this on a higher level wrapper to avoid missuse -#[cfg(feature = "dealloc_nodes")] -unsafe impl Send for NodeContainer {} -#[cfg(feature = "dealloc_nodes")] -unsafe impl Sync for NodeContainer {} - -#[cfg(feature = "dealloc_nodes")] -impl Drop for NodeContainer { - fn drop(&mut self) { - unsafe { self.dealloc_unchecked() } - } -} - -impl std::fmt::Debug for NodeContainer { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("NodeContainer").finish() - } -} - -impl NodeContainer { - pub fn new(node: TypeErasedBox<'static>) -> SharedNodeContainer { - let node = Box::leak(node); - Self { node }.into() - } - - #[cfg(feature = "dealloc_nodes")] - unsafe fn dealloc_unchecked(&mut self) { - unsafe { - drop(Box::from_raw(self.node as *mut TypeErasedNode)); - } - } -} - -/// Boxes the input and downcasts the output. -/// Wraps around a node taking Box and returning Box -#[derive(Clone)] -pub struct DowncastBothNode { - node: SharedNodeContainer, - _i: PhantomData, - _o: PhantomData, -} -impl<'input, O, I> Node<'input, I> for DowncastBothNode -where - O: 'input + StaticType + WasmNotSend, - I: 'input + StaticType + WasmNotSend, -{ - type Output = DynFuture<'input, O>; - #[inline] - #[track_caller] - fn eval(&'input self, input: I) -> Self::Output { - { - let node_name = self.node.node_name(); - let input = Box::new(input); - let future = self.node.eval(input); - Box::pin(async move { - let out = dyn_any::downcast(future.await).unwrap_or_else(|e| panic!("DowncastBothNode wrong output type: {e} in: \n{node_name}")); - *out - }) - } - } - fn reset(&self) { - self.node.reset(); - } - - fn serialize(&self) -> Option> { - self.node.serialize() - } -} -impl DowncastBothNode { - pub const fn new(node: SharedNodeContainer) -> Self { - Self { - node, - _i: PhantomData, - _o: PhantomData, - } - } -} -pub struct FutureWrapperNode { - node: Node, -} - -impl<'i, T: 'i + WasmNotSend, N> Node<'i, T> for FutureWrapperNode -where - N: Node<'i, T, Output: WasmNotSend> + WasmNotSend, -{ - type Output = DynFuture<'i, N::Output>; - #[inline(always)] - fn eval(&'i self, input: T) -> Self::Output { - let result = self.node.eval(input); - Box::pin(async move { result }) - } - #[inline(always)] - fn reset(&self) { - self.node.reset(); - } - - #[inline(always)] - fn serialize(&self) -> Option> { - self.node.serialize() - } -} - -impl FutureWrapperNode { - pub const fn new(node: N) -> Self { - Self { node } - } -} - -pub struct DynAnyNode { - node: Node, - _i: PhantomData, - _o: PhantomData, -} - -impl<'input, I, O, N> Node<'input, Any<'input>> for DynAnyNode -where - I: 'input + StaticType + WasmNotSend, - O: 'input + StaticType + WasmNotSend, - N: 'input + Node<'input, I, Output = DynFuture<'input, O>>, -{ - type Output = FutureAny<'input>; - #[inline] - fn eval(&'input self, input: Any<'input>) -> Self::Output { - let node_name = std::any::type_name::(); - let output = |input| { - let result = self.node.eval(input); - async move { Box::new(result.await) as Any<'input> } - }; - match dyn_any::downcast(input) { - Ok(input) => Box::pin(output(*input)), - Err(e) => panic!("DynAnyNode Input, {e} in:\n{node_name}"), - } - } - - fn reset(&self) { - self.node.reset(); - } - - fn serialize(&self) -> Option> { - self.node.serialize() - } -} -impl<'input, I, O, N> DynAnyNode -where - I: 'input + StaticType, - O: 'input + StaticType, - N: 'input + Node<'input, I, Output = DynFuture<'input, O>>, -{ - pub const fn new(node: N) -> Self { - Self { - node, - _i: PhantomData, - _o: PhantomData, - } - } -} -pub struct PanicNode(PhantomData, PhantomData); - -impl<'i, I: 'i + WasmNotSend, O: 'i + WasmNotSend> Node<'i, I> for PanicNode { - type Output = O; - fn eval(&'i self, _: I) -> Self::Output { - unimplemented!("This node should never be evaluated") - } -} - -impl PanicNode { - pub const fn new() -> Self { - Self(PhantomData, PhantomData) - } -} - -impl Default for PanicNode { - fn default() -> Self { - Self::new() - } -} - -// TODO: Evaluate safety -unsafe impl Sync for PanicNode {} #[cfg(test)] mod tests { diff --git a/node-graph/nodes/gstd/src/any.rs b/node-graph/nodes/gstd/src/any.rs deleted file mode 100644 index c8959d23e2..0000000000 --- a/node-graph/nodes/gstd/src/any.rs +++ /dev/null @@ -1,27 +0,0 @@ -use core_types::NodeIO; -use core_types::WasmNotSend; -pub use core_types::registry::{DowncastBothNode, DynAnyNode, FutureWrapperNode, PanicNode}; -pub use core_types::{Node, generic, ops}; -use dyn_any::StaticType; -pub use graph_craft::proto::{Any, NodeContainer, TypeErasedBox, TypeErasedNode}; -use graph_craft::proto::{FutureAny, SharedNodeContainer}; - -pub trait IntoTypeErasedNode<'n> { - fn into_type_erased(self) -> TypeErasedBox<'n>; -} - -impl<'n, N: 'n> IntoTypeErasedNode<'n> for N -where - N: for<'i> NodeIO<'i, Any<'i>, Output = FutureAny<'i>> + Sync + WasmNotSend, -{ - fn into_type_erased(self) -> TypeErasedBox<'n> { - Box::new(self) - } -} - -pub fn input_node(n: SharedNodeContainer) -> DowncastBothNode<(), O> { - downcast_node(n) -} -pub fn downcast_node(n: SharedNodeContainer) -> DowncastBothNode { - DowncastBothNode::new(n) -} diff --git a/node-graph/nodes/gstd/src/lib.rs b/node-graph/nodes/gstd/src/lib.rs index 7236bb8c63..94719697a8 100644 --- a/node-graph/nodes/gstd/src/lib.rs +++ b/node-graph/nodes/gstd/src/lib.rs @@ -1,4 +1,3 @@ -pub mod any; pub mod platform_application_io; pub mod render_background; pub mod render_cache;