diff --git a/node-graph/Cargo.lock b/node-graph/Cargo.lock index 25d2d7ef..b9886480 100644 --- a/node-graph/Cargo.lock +++ b/node-graph/Cargo.lock @@ -257,11 +257,15 @@ dependencies = [ [[package]] name = "graphene-core" version = "0.1.0" +dependencies = [ + "dyn-any", +] [[package]] name = "graphene-std" version = "0.1.0" dependencies = [ + "borrow_stack", "dyn-any", "graph-proc-macros", "graphene-core", diff --git a/node-graph/borrow_stack/src/lib.rs b/node-graph/borrow_stack/src/lib.rs index 20be5a9b..8be41d6d 100644 --- a/node-graph/borrow_stack/src/lib.rs +++ b/node-graph/borrow_stack/src/lib.rs @@ -1,13 +1,72 @@ -trait BorrowStack { - type Item; - unsafe fn push(&mut self, T) -> &Item; - unsafe fn pop(&mut self) -> T; - unsafe fn get(&self) -> &T; +use std::{ + marker::PhantomData, + mem::MaybeUninit, + pin::Pin, + sync::atomic::{AtomicUsize, Ordering}, +}; +pub trait BorrowStack<'n> { + type Item; + unsafe fn push(&'n self, value: Self::Item); + unsafe fn pop(&'n self); + unsafe fn get(&'n self) -> &'n [Self::Item]; } -struct BorrowStack { - data: S, +#[derive(Debug)] +pub struct FixedSizeStack<'n, T> { + data: Pin]>>, + capacity: usize, + len: AtomicUsize, + _phantom: PhantomData<&'n ()>, +} + +impl<'n, T: Unpin> FixedSizeStack<'n, T> { + pub fn new(capacity: usize) -> Self { + let layout = std::alloc::Layout::array::>(capacity).unwrap(); + let array = unsafe { std::alloc::alloc(layout) }; + let array = Pin::new(unsafe { + Box::from_raw( + std::slice::from_raw_parts_mut(array as *mut MaybeUninit, capacity) + as *mut [MaybeUninit], + ) + }); + + Self { + data: array, + capacity, + len: AtomicUsize::new(0), + _phantom: PhantomData, + } + } + + pub fn len(&self) -> usize { + self.len.load(Ordering::SeqCst) + } +} + +impl<'n, T> BorrowStack<'n> for FixedSizeStack<'n, T> { + type Item = T; + + unsafe fn push(&'n self, value: Self::Item) { + let len = self.len.load(Ordering::SeqCst); + assert!(len < self.capacity); + let ptr = self.data[len].as_ptr(); + (ptr as *mut T).write(value); + self.len.fetch_add(1, Ordering::SeqCst); + } + + unsafe fn pop(&'n self) { + let ptr = self.data[self.len.load(Ordering::SeqCst)].as_ptr(); + Box::from_raw(ptr as *mut T); + self.len.fetch_sub(1, Ordering::SeqCst); + } + + unsafe fn get(&'n self) -> &'n [Self::Item] { + std::slice::from_raw_parts( + self.data.as_ptr() as *const T, + self.len.load(Ordering::SeqCst), + ) + } } #[cfg(test)] diff --git a/node-graph/gcore/Cargo.toml b/node-graph/gcore/Cargo.toml index f7eb0ebf..b88d474a 100644 --- a/node-graph/gcore/Cargo.toml +++ b/node-graph/gcore/Cargo.toml @@ -12,4 +12,4 @@ authors = ["Dennis Kobert "] #default = ["std"] [dependencies] -#dyn-any = {path = "../dyn-any", features = ["derive"], optional = true} +dyn-any = {path = "../dyn-any", features = ["derive"]} diff --git a/node-graph/gcore/src/lib.rs b/node-graph/gcore/src/lib.rs index 3b9d6a3c..74ec48ff 100644 --- a/node-graph/gcore/src/lib.rs +++ b/node-graph/gcore/src/lib.rs @@ -22,3 +22,12 @@ impl<'n, T: Node<'n, ()>> Exec<'n> for T {} pub trait Cache { fn clear(&mut self); } + +extern crate alloc; +impl<'n, I, O: 'n> Node<'n, I> for alloc::boxed::Box> { + type Output = O; + + fn eval(&'n self, input: &'n I) -> Self::Output { + self.as_ref().eval(input) + } +} diff --git a/node-graph/gcore/src/value.rs b/node-graph/gcore/src/value.rs index 4d711201..696291df 100644 --- a/node-graph/gcore/src/value.rs +++ b/node-graph/gcore/src/value.rs @@ -10,6 +10,7 @@ impl<'n, const N: u32> Node<'n, ()> for IntNode { } } +use dyn_any::{DynAny, StaticType, StaticTypeSized}; #[derive(Default)] pub struct ValueNode<'n, T>(T, PhantomData<&'n ()>); impl<'n, T: 'n> Node<'n, ()> for ValueNode<'n, T> { @@ -18,6 +19,11 @@ impl<'n, T: 'n> Node<'n, ()> for ValueNode<'n, T> { &self.0 } } + +impl<'n, T: StaticTypeSized> StaticType for ValueNode<'n, T> { + type Static = ValueNode<'static, ::Static>; +} + impl<'n, T> ValueNode<'n, T> { pub const fn new(value: T) -> ValueNode<'n, T> { ValueNode(value, PhantomData) diff --git a/node-graph/gstd/Cargo.toml b/node-graph/gstd/Cargo.toml index 22e5608a..5069da7d 100644 --- a/node-graph/gstd/Cargo.toml +++ b/node-graph/gstd/Cargo.toml @@ -17,6 +17,7 @@ default = ["derive", "memoization"] [dependencies] graphene-core = {path = "../gcore"} +borrow_stack = {path = "../borrow_stack"} dyn-any = {path = "../dyn-any", features = ["derive"]} graph-proc-macros = {path = "../proc-macro", optional = true} once_cell = {version= "1.10", optional = true} diff --git a/node-graph/gstd/src/lib.rs b/node-graph/gstd/src/lib.rs index 067ff34d..f436c9fb 100644 --- a/node-graph/gstd/src/lib.rs +++ b/node-graph/gstd/src/lib.rs @@ -9,7 +9,6 @@ pub mod memo; pub use graphene_core::*; use dyn_any::{downcast_ref, DynAny, StaticType}; -use std::any::Any; pub type DynNode<'n, T> = &'n (dyn Node<'n, (), Output = T> + 'n); pub type DynAnyNode<'n> = &'n (dyn Node<'n, (), Output = &'n dyn DynAny<'n>> + 'n); @@ -18,11 +17,11 @@ pub trait DynamicInput<'n> { fn set_arg_by_index(&mut self, index: usize, value: DynAnyNode<'n>); } -pub trait AnyRef<'n, I: StaticType<'n>>: Node<'n, I> { +pub trait AnyRef<'n, I: StaticType>: Node<'n, I> { fn any(&'n self, input: &'n dyn DynAny<'n>) -> Self::Output; } -impl<'n, T: Node<'n, I>, I: StaticType<'n>> AnyRef<'n, I> for T { +impl<'n, T: Node<'n, I>, I: StaticType + 'n> AnyRef<'n, I> for T { fn any(&'n self, input: &'n dyn DynAny<'n>) -> Self::Output { self.eval(downcast_ref::(input).unwrap_or_else(|| { panic!( diff --git a/node-graph/gstd/src/main.rs b/node-graph/gstd/src/main.rs index 3955ebbf..b5e9a6b3 100644 --- a/node-graph/gstd/src/main.rs +++ b/node-graph/gstd/src/main.rs @@ -1,6 +1,7 @@ +use borrow_stack::BorrowStack; //#![feature(generic_associated_types)] -use dyn_any::StaticType; -use graphene_std::value::{AnyRefNode, ValueNode}; +use dyn_any::{DynAny, StaticType}; +use graphene_std::value::{AnyRefNode, AnyValueNode, StorageNode, ValueNode}; use graphene_std::*; /*fn mul(#[dyn_any(default)] a: f32, b: f32) -> f32 { @@ -70,9 +71,39 @@ mod mul { } } } +type SNode<'n> = dyn Node<'n, (), Output = &'n dyn DynAny<'n>>; + +struct NodeStore<'n>(borrow_stack::FixedSizeStack<'n, Box>>); + +impl<'n> NodeStore<'n> { + fn len(&self) -> usize { + self.0.len() + } + + fn push(&'n mut self, f: fn(&'n [Box]) -> Box>) { + unsafe { self.0.push(f(self.0.get())) }; + } + + /*fn get_index(&'n self, index: usize) -> &'n SNode<'n> { + assert!(index < self.0.len()); + &unsafe { self.0.get()[index] } + }*/ +} fn main() { //let mut mul = mul::MulNode::new(); + let mut stack: borrow_stack::FixedSizeStack>> = + borrow_stack::FixedSizeStack::new(42); + unsafe { stack.push(Box::new(AnyValueNode::new(1f32))) }; + //let node = unsafe { stack.get(0) }; + //let boxed = Box::new(StorageNode::new(node)); + //unsafe { stack.push(boxed) }; + let result = unsafe { &stack.get()[0] }.eval(&()); + /*unsafe { + stack + .push(Box::new(AnyRefNode::new(stack.get(0).as_ref())) + as Box>) + };*/ let f = (3.2f32, 3.1f32); let a = ValueNode::new(1.); let id = std::any::TypeId::of::<&f32>(); diff --git a/node-graph/gstd/src/memo.rs b/node-graph/gstd/src/memo.rs index 110c2775..b5e382fd 100644 --- a/node-graph/gstd/src/memo.rs +++ b/node-graph/gstd/src/memo.rs @@ -30,6 +30,7 @@ impl<'n, CachedNode: Node<'n, Input>, Input> Cache for CacheNode<'n, CachedNode, } } -use dyn_any::{DynAny, StaticType}; +/*use dyn_any::{DynAny, StaticType}; #[derive(DynAny)] struct Boo<'a>(&'a u8); +*/ diff --git a/node-graph/gstd/src/value.rs b/node-graph/gstd/src/value.rs index f76364d0..8ba1d446 100644 --- a/node-graph/gstd/src/value.rs +++ b/node-graph/gstd/src/value.rs @@ -2,21 +2,55 @@ use core::marker::PhantomData; pub use graphene_core::value::*; use graphene_core::Node; -use dyn_any::{DynAny, StaticType}; -pub struct AnyRefNode<'n, N: Node<'n, I, Output = &'n O>, I, O>( +use dyn_any::{DynAny, StaticType, StaticTypeSized}; + +pub struct AnyRefNode<'n, N: Node<'n, I, Output = O>, I, O>( &'n N, PhantomData<&'n I>, PhantomData<&'n O>, ); -impl<'n, N: Node<'n, I, Output = &'n O>, I, O: DynAny<'n>> Node<'n, I> for AnyRefNode<'n, N, I, O> { + +impl<'n, N: Node<'n, I, Output = &'n O>, I, O: DynAny<'n>> Node<'n, I> + for AnyRefNode<'n, N, I, &'n O> +{ type Output = &'n (dyn DynAny<'n>); fn eval(&'n self, input: &'n I) -> Self::Output { let value: &O = self.0.eval(input); value } } -impl<'n, N: Node<'n, I, Output = &'n O>, I, O: 'static> AnyRefNode<'n, N, I, O> { - pub fn new(n: &'n N) -> AnyRefNode<'n, N, I, O> { +impl<'n, N: Node<'n, I, Output = &'n O>, I, O: 'n + ?Sized> AnyRefNode<'n, N, I, &'n O> { + pub fn new(n: &'n N) -> AnyRefNode<'n, N, I, &'n O> { AnyRefNode(n, PhantomData, PhantomData) } } + +pub struct StorageNode<'n>(&'n dyn Node<'n, (), Output = &'n dyn DynAny<'n>>); + +impl<'n> Node<'n, ()> for StorageNode<'n> { + type Output = &'n (dyn DynAny<'n>); + fn eval(&'n self, input: &'n ()) -> Self::Output { + let value = self.0.eval(input); + value + } +} +impl<'n> StorageNode<'n> { + pub fn new>>(n: &'n N) -> StorageNode<'n> { + StorageNode(n) + } +} + +#[derive(Default)] +pub struct AnyValueNode<'n, T>(T, PhantomData<&'n ()>); +impl<'n, T: 'n + DynAny<'n>> Node<'n, ()> for AnyValueNode<'n, T> { + type Output = &'n dyn DynAny<'n>; + fn eval(&'n self, _input: &()) -> &'n dyn DynAny<'n> { + &self.0 + } +} + +impl<'n, T> AnyValueNode<'n, T> { + pub const fn new(value: T) -> AnyValueNode<'n, T> { + AnyValueNode(value, PhantomData) + } +}