Bump dyn-any version + format code

This commit is contained in:
Dennis 2022-08-04 09:08:48 +02:00 committed by Keavon Chambers
parent c44e9d22e3
commit d09f023618
12 changed files with 464 additions and 513 deletions

View file

@ -1,79 +1,71 @@
use std::{
marker::PhantomData,
mem::MaybeUninit,
pin::Pin,
sync::atomic::{AtomicUsize, Ordering},
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];
type Item;
unsafe fn push(&'n self, value: Self::Item);
unsafe fn pop(&'n self);
unsafe fn get(&'n self) -> &'n [Self::Item];
}
#[derive(Debug)]
pub struct FixedSizeStack<'n, T> {
data: Pin<Box<[MaybeUninit<T>]>>,
capacity: usize,
len: AtomicUsize,
_phantom: PhantomData<&'n ()>,
data: Pin<Box<[MaybeUninit<T>]>>,
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::<MaybeUninit<T>>(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<T>, capacity)
as *mut [MaybeUninit<T>],
)
});
pub fn new(capacity: usize) -> Self {
let layout = std::alloc::Layout::array::<MaybeUninit<T>>(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<T>, capacity) as *mut [MaybeUninit<T>]) });
Self {
data: array,
capacity,
len: AtomicUsize::new(0),
_phantom: PhantomData,
}
}
Self {
data: array,
capacity,
len: AtomicUsize::new(0),
_phantom: PhantomData,
}
}
pub fn len(&self) -> usize {
self.len.load(Ordering::SeqCst)
}
pub fn len(&self) -> usize {
self.len.load(Ordering::SeqCst)
}
}
impl<'n, T> BorrowStack<'n> for FixedSizeStack<'n, T> {
type Item = 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 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 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),
)
}
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)]
mod tests {
#[test]
fn it_works() {
let result = 2 + 2;
assert_eq!(result, 4);
}
#[test]
fn it_works() {
let result = 2 + 2;
assert_eq!(result, 4);
}
}

View file

@ -1,46 +1,32 @@
use core::marker::PhantomData;
use crate::Node;
pub struct FnNode<'n, T: Fn(<N as Node<'n>>::Output) -> O, N: Node<'n>, O>(
T,
N,
PhantomData<&'n O>,
);
pub struct FnNode<'n, T: Fn(<N as Node<'n>>::Output) -> O, N: Node<'n>, O>(T, N, PhantomData<&'n O>);
impl<'n, T: Fn(<N as Node<'n>>::Output) -> O, N: Node<'n>, O> Node<'n> for FnNode<'n, T, N, O> {
type Output = O;
type Output = O;
fn eval(&'n self) -> Self::Output {
self.0(self.1.eval())
}
fn eval(&'n self) -> Self::Output {
self.0(self.1.eval())
}
}
impl<'n, T: Fn(<N as Node<'n>>::Output) -> O, N: Node<'n>, O> FnNode<'n, T, N, O> {
pub fn new(f: T, input: N) -> Self {
FnNode(f, input, PhantomData)
}
pub fn new(f: T, input: N) -> Self {
FnNode(f, input, PhantomData)
}
}
pub struct FnNodeWithState<
'n,
T: Fn(<N as Node<'n>>::Output, &'n State) -> O,
N: Node<'n>,
O,
State: 'n,
>(T, N, State, PhantomData<&'n O>);
impl<'n, T: Fn(<N as Node<'n>>::Output, &'n State) -> O, N: Node<'n>, O: 'n, State: 'n> Node<'n>
for FnNodeWithState<'n, T, N, O, State>
{
type Output = O;
pub struct FnNodeWithState<'n, T: Fn(<N as Node<'n>>::Output, &'n State) -> O, N: Node<'n>, O, State: 'n>(T, N, State, PhantomData<&'n O>);
impl<'n, T: Fn(<N as Node<'n>>::Output, &'n State) -> O, N: Node<'n>, O: 'n, State: 'n> Node<'n> for FnNodeWithState<'n, T, N, O, State> {
type Output = O;
fn eval(&'n self) -> Self::Output {
self.0(self.1.eval(), &self.2)
}
fn eval(&'n self) -> Self::Output {
self.0(self.1.eval(), &self.2)
}
}
impl<'n, T: Fn(<N as Node<'n>>::Output, &'n State) -> O, N: Node<'n>, O: 'n, State: 'n>
FnNodeWithState<'n, T, N, O, State>
{
pub fn new(f: T, input: N, state: State) -> Self {
FnNodeWithState(f, input, state, PhantomData)
}
impl<'n, T: Fn(<N as Node<'n>>::Output, &'n State) -> O, N: Node<'n>, O: 'n, State: 'n> FnNodeWithState<'n, T, N, O, State> {
pub fn new(f: T, input: N, state: State) -> Self {
FnNodeWithState(f, input, state, PhantomData)
}
}

View file

@ -14,62 +14,62 @@ pub mod ops;
pub mod value;
pub trait Node<'n> {
type Output; // TODO: replace with generic associated type
type Output; // TODO: replace with generic associated type
fn eval(&'n self) -> Self::Output;
fn eval(&'n self) -> Self::Output;
}
impl<'n, N: Node<'n>> Node<'n> for &'n N {
type Output = N::Output;
type Output = N::Output;
fn eval(&'n self) -> Self::Output {
Node::eval(*self)
}
fn eval(&'n self) -> Self::Output {
Node::eval(*self)
}
}
pub trait NodeInput {
type Nodes;
type Nodes;
fn new(input: Self::Nodes) -> Self;
fn new(input: Self::Nodes) -> Self;
}
trait FQN {
fn fqn(&self) -> &'static str;
fn fqn(&self) -> &'static str;
}
trait Input<I> {
unsafe fn input(&self, input: I);
unsafe fn input(&self, input: I);
}
#[cfg(feature = "async")]
#[async_trait]
pub trait AsyncNode<'n> {
type Output; // TODO: replace with generic associated type
type Output; // TODO: replace with generic associated type
async fn eval_async(&'n self) -> Self::Output;
async fn eval_async(&'n self) -> Self::Output;
}
#[cfg(feature = "async")]
#[async_trait]
impl<'n, N: Node<'n> + Sync> AsyncNode<'n> for N {
type Output = N::Output;
type Output = N::Output;
async fn eval_async(&'n self) -> Self::Output {
Node::eval(self)
}
async fn eval_async(&'n self) -> Self::Output {
Node::eval(self)
}
}
pub trait Cache {
fn clear(&mut self);
fn clear(&mut self);
}
#[cfg(not(feature = "gpu"))]
extern crate alloc;
#[cfg(not(feature = "gpu"))]
impl<'n, I, O: 'n> Node<'n, I> for alloc::boxed::Box<dyn Node<'n, I, Output = O>> {
type Output = O;
type Output = O;
fn eval(&'n self, input: &'n I) -> Self::Output {
self.as_ref().eval(input)
}
fn eval(&'n self, input: &'n I) -> Self::Output {
self.as_ref().eval(input)
}
}

View file

@ -3,165 +3,156 @@ use core::{marker::PhantomData, ops::Add};
use crate::{Node, NodeInput};
#[repr(C)]
pub struct AddNode<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>>(
pub I1,
pub I2,
PhantomData<&'n (L, R)>,
);
impl<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>> Node<'n>
for AddNode<'n, L, R, I1, I2>
{
type Output = <L as Add<R>>::Output;
fn eval(&'n self) -> Self::Output {
self.0.eval() + self.1.eval()
}
pub struct AddNode<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>>(pub I1, pub I2, PhantomData<&'n (L, R)>);
impl<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>> Node<'n> for AddNode<'n, L, R, I1, I2> {
type Output = <L as Add<R>>::Output;
fn eval(&'n self) -> Self::Output {
self.0.eval() + self.1.eval()
}
}
impl<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>>
AddNode<'n, L, R, I1, I2>
{
pub fn new(input: (I1, I2)) -> AddNode<'n, L, R, I1, I2> {
AddNode(input.0, input.1, PhantomData)
}
impl<'n, L: Add<R>, R, I1: Node<'n, Output = L>, I2: Node<'n, Output = R>> AddNode<'n, L, R, I1, I2> {
pub fn new(input: (I1, I2)) -> AddNode<'n, L, R, I1, I2> {
AddNode(input.0, input.1, PhantomData)
}
}
#[repr(C)]
pub struct CloneNode<'n, N: Node<'n, Output = &'n O>, O: Clone + 'n>(pub N, PhantomData<&'n ()>);
impl<'n, N: Node<'n, Output = &'n O>, O: Clone> Node<'n> for CloneNode<'n, N, O> {
type Output = O;
fn eval(&'n self) -> Self::Output {
self.0.eval().clone()
}
type Output = O;
fn eval(&'n self) -> Self::Output {
self.0.eval().clone()
}
}
impl<'n, N: Node<'n, Output = &'n O>, O: Clone> CloneNode<'n, N, O> {
pub const fn new(node: N) -> CloneNode<'n, N, O> {
CloneNode(node, PhantomData)
}
pub const fn new(node: N) -> CloneNode<'n, N, O> {
CloneNode(node, PhantomData)
}
}
#[repr(C)]
pub struct FstNode<'n, N: Node<'n>>(pub N, PhantomData<&'n ()>);
impl<'n, T: 'n, U, N: Node<'n, Output = (T, U)>> Node<'n> for FstNode<'n, N> {
type Output = T;
fn eval(&'n self) -> Self::Output {
let (a, _) = self.0.eval();
a
}
type Output = T;
fn eval(&'n self) -> Self::Output {
let (a, _) = self.0.eval();
a
}
}
#[repr(C)]
/// Destructures a Tuple of two values and returns the first one
pub struct SndNode<'n, N: Node<'n>>(pub N, PhantomData<&'n ()>);
impl<'n, T, U: 'n, N: Node<'n, Output = (T, U)>> Node<'n> for SndNode<'n, N> {
type Output = U;
fn eval(&'n self) -> Self::Output {
let (_, b) = self.0.eval();
b
}
type Output = U;
fn eval(&'n self) -> Self::Output {
let (_, b) = self.0.eval();
b
}
}
#[repr(C)]
/// Return a tuple with two instances of the input argument
pub struct DupNode<'n, N: Node<'n>>(N, PhantomData<&'n ()>);
impl<'n, N: Node<'n>> Node<'n> for DupNode<'n, N> {
type Output = (N::Output, N::Output);
fn eval(&'n self) -> Self::Output {
(self.0.eval(), self.0.eval()) //TODO: use Copy/Clone implementation
}
type Output = (N::Output, N::Output);
fn eval(&'n self) -> Self::Output {
(self.0.eval(), self.0.eval()) //TODO: use Copy/Clone implementation
}
}
impl<'n, N: Node<'n>> NodeInput for DupNode<'n, N> {
type Nodes = N;
type Nodes = N;
fn new(input: Self::Nodes) -> Self {
Self(input, PhantomData)
}
fn new(input: Self::Nodes) -> Self {
Self(input, PhantomData)
}
}
#[repr(C)]
/// Return the Input Argument
pub struct IdNode<'n, N: Node<'n>>(N, PhantomData<&'n ()>);
impl<'n, N: Node<'n>> Node<'n> for IdNode<'n, N> {
type Output = N::Output;
fn eval(&'n self) -> Self::Output {
self.0.eval()
}
type Output = N::Output;
fn eval(&'n self) -> Self::Output {
self.0.eval()
}
}
impl<'n, N: Node<'n>> NodeInput for IdNode<'n, N> {
type Nodes = N;
type Nodes = N;
fn new(input: Self::Nodes) -> Self {
Self(input, PhantomData)
}
fn new(input: Self::Nodes) -> Self {
Self(input, PhantomData)
}
}
pub fn foo() {
let unit = crate::value::UnitNode;
let value = IdNode(crate::value::ValueNode(2u32), PhantomData);
let value2 = crate::value::ValueNode(4u32);
let dup = DupNode(&value, PhantomData);
fn int(_: (), state: &u32) -> &u32 {
state
}
fn swap<'n>(input: (&'n u32, &'n u32)) -> (&'n u32, &'n u32) {
(input.1, input.0)
}
let fnn = crate::generic::FnNode::new(swap, &dup);
let fns = crate::generic::FnNodeWithState::new(int, &unit, 42u32);
let _ = fnn.eval();
let _ = fns.eval();
let snd = SndNode(&fnn, PhantomData);
let _ = snd.eval();
let add = AddNode(&snd, value2, PhantomData);
let _ = add.eval();
let unit = crate::value::UnitNode;
let value = IdNode(crate::value::ValueNode(2u32), PhantomData);
let value2 = crate::value::ValueNode(4u32);
let dup = DupNode(&value, PhantomData);
fn int(_: (), state: &u32) -> &u32 {
state
}
fn swap<'n>(input: (&'n u32, &'n u32)) -> (&'n u32, &'n u32) {
(input.1, input.0)
}
let fnn = crate::generic::FnNode::new(swap, &dup);
let fns = crate::generic::FnNodeWithState::new(int, &unit, 42u32);
let _ = fnn.eval();
let _ = fns.eval();
let snd = SndNode(&fnn, PhantomData);
let _ = snd.eval();
let add = AddNode(&snd, value2, PhantomData);
let _ = add.eval();
}
#[cfg(target_arch = "spirv")]
pub mod gpu {
//#![deny(warnings)]
#[repr(C)]
pub struct PushConsts {
n: u32,
node: u32,
}
use super::*;
use crate::{structural::ComposeNodeOwned, Node};
//use crate::Node;
use spirv_std::glam::UVec3;
const ADD: AddNode<u32> = AddNode(PhantomData);
const OPERATION: ComposeNodeOwned<'_, (u32, u32), u32, FstNode<u32, u32>, DupNode<u32>> =
ComposeNodeOwned::new(FstNode(PhantomData, PhantomData), DupNode(PhantomData));
//#![deny(warnings)]
#[repr(C)]
pub struct PushConsts {
n: u32,
node: u32,
}
use super::*;
use crate::{structural::ComposeNodeOwned, Node};
//use crate::Node;
use spirv_std::glam::UVec3;
const ADD: AddNode<u32> = AddNode(PhantomData);
const OPERATION: ComposeNodeOwned<'_, (u32, u32), u32, FstNode<u32, u32>, DupNode<u32>> = ComposeNodeOwned::new(FstNode(PhantomData, PhantomData), DupNode(PhantomData));
#[allow(unused)]
#[spirv(compute(threads(64)))]
pub fn spread(
#[spirv(global_invocation_id)] global_id: UVec3,
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] a: &[(u32, u32)],
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] y: &mut [(u32, u32)],
#[spirv(push_constant)] push_consts: &PushConsts,
) {
fn node_graph(input: Input) -> Output {
let n0 = ValueNode::new(input);
let n1 = IdNode::new(n0);
let n2 = IdNode::new(n1);
return n2.eval();
}
let gid = global_id.x as usize;
// Only process up to n, which is the length of the buffers.
if global_id.x < push_consts.n {
y[gid] = node_graph(a[gid]);
}
}
#[allow(unused)]
#[spirv(compute(threads(64)))]
pub fn add(
#[spirv(global_invocation_id)] global_id: UVec3,
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] a: &[(u32, u32)],
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] y: &mut [u32],
#[spirv(push_constant)] push_consts: &PushConsts,
) {
let gid = global_id.x as usize;
// Only process up to n, which is the length of the buffers.
if global_id.x < push_consts.n {
y[gid] = ADD.eval(a[gid]);
}
}
#[allow(unused)]
#[spirv(compute(threads(64)))]
pub fn spread(
#[spirv(global_invocation_id)] global_id: UVec3,
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] a: &[(u32, u32)],
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] y: &mut [(u32, u32)],
#[spirv(push_constant)] push_consts: &PushConsts,
) {
fn node_graph(input: Input) -> Output {
let n0 = ValueNode::new(input);
let n1 = IdNode::new(n0);
let n2 = IdNode::new(n1);
return n2.eval();
}
let gid = global_id.x as usize;
// Only process up to n, which is the length of the buffers.
if global_id.x < push_consts.n {
y[gid] = node_graph(a[gid]);
}
}
#[allow(unused)]
#[spirv(compute(threads(64)))]
pub fn add(
#[spirv(global_invocation_id)] global_id: UVec3,
#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] a: &[(u32, u32)],
#[spirv(storage_buffer, descriptor_set = 0, binding = 1)] y: &mut [u32],
#[spirv(push_constant)] push_consts: &PushConsts,
) {
let gid = global_id.x as usize;
// Only process up to n, which is the length of the buffers.
if global_id.x < push_consts.n {
y[gid] = ADD.eval(a[gid]);
}
}
}

View file

@ -6,57 +6,57 @@ use crate::Node;
pub struct IntNode<const N: u32>;
impl<'n, const N: u32> Node<'n> for IntNode<N> {
type Output = u32;
fn eval(&self) -> u32 {
N
}
type Output = u32;
fn eval(&self) -> u32 {
N
}
}
#[derive(Default)]
pub struct ValueNode<T>(pub T);
impl<'n, T: 'n> Node<'n> for ValueNode<T> {
type Output = &'n T;
fn eval(&'n self) -> Self::Output {
&self.0
}
type Output = &'n T;
fn eval(&'n self) -> Self::Output {
&self.0
}
}
impl<T> ValueNode<T> {
pub const fn new(value: T) -> ValueNode<T> {
ValueNode(value)
}
pub const fn new(value: T) -> ValueNode<T> {
ValueNode(value)
}
}
#[derive(Default)]
pub struct DefaultNode<T>(PhantomData<T>);
impl<'n, T: Default + 'n> Node<'n> for DefaultNode<T> {
type Output = T;
fn eval(&self) -> T {
T::default()
}
type Output = T;
fn eval(&self) -> T {
T::default()
}
}
#[repr(C)]
/// Return the unit value
pub struct UnitNode;
impl<'n> Node<'n> for UnitNode {
type Output = ();
fn eval(&'n self) -> Self::Output {}
type Output = ();
fn eval(&'n self) -> Self::Output {}
}
pub struct InputNode<T>(MaybeUninit<T>, AtomicBool);
impl<'n, T: 'n> Node<'n> for InputNode<T> {
type Output = &'n T;
fn eval(&'n self) -> Self::Output {
if self.1.load(core::sync::atomic::Ordering::SeqCst) {
unsafe { self.0.assume_init_ref() }
} else {
panic!("tried to access an input before setting it")
}
}
type Output = &'n T;
fn eval(&'n self) -> Self::Output {
if self.1.load(core::sync::atomic::Ordering::SeqCst) {
unsafe { self.0.assume_init_ref() }
} else {
panic!("tried to access an input before setting it")
}
}
}
impl<T> InputNode<T> {
pub const fn new() -> InputNode<T> {
InputNode(MaybeUninit::uninit(), AtomicBool::new(false))
}
pub const fn new() -> InputNode<T> {
InputNode(MaybeUninit::uninit(), AtomicBool::new(false))
}
}

View file

@ -2,7 +2,7 @@ pub mod value;
pub use graphene_core::{generic, ops /*, structural*/};
#[cfg(feature = "caching")]
pub mod caching;
pub mod cache;
#[cfg(feature = "memoization")]
pub mod memo;

View file

@ -5,147 +5,144 @@ use graphene_std::value::{AnyRefNode, AnyValueNode, StorageNode, ValueNode};
use graphene_std::*;
/*fn mul(#[dyn_any(default)] a: f32, b: f32) -> f32 {
a * b
a * b
}*/
mod mul {
use dyn_any::{downcast_ref, DynAny, StaticType};
use graphene_std::{DynAnyNode, DynNode, DynamicInput, Node};
pub struct MulNodeInput<'n> {
pub a: &'n f32,
pub b: &'n f32,
}
#[derive(Copy, Clone)]
pub struct MulNodeAnyProxy<'n> {
pub a: Option<DynAnyNode<'n>>,
pub b: Option<DynAnyNode<'n>>,
}
#[derive(Copy, Clone)]
pub struct MulNodeTypedProxy<'n> {
pub a: Option<DynNode<'n, &'n f32>>,
pub b: Option<DynNode<'n, &'n f32>>,
}
impl<'n> Node<'n> for MulNodeAnyProxy<'n> {
type Output = MulNodeInput<'n>;
fn eval(&'n self) -> <Self as graphene_std::Node<'n>>::Output {
let a = self.a.unwrap().eval();
let a: &f32 = self
.a
.map(|v| downcast_ref(v.eval()).unwrap())
.unwrap_or(&1.);
/*let b: &f32 = self
.b
.map(|v| v.eval(&()).downcast_ref::<&'n f32, &'n f32>().unwrap())
.unwrap_or(&&2.);
a * b*/
MulNodeInput { a, b: a }
}
}
impl<'n> Node<'n> for MulNodeTypedProxy<'n> {
type Output = MulNodeInput<'n>;
fn eval(&'n self) -> <Self as graphene_std::Node<'n>>::Output {
let a = self.a.unwrap().eval();
let b = self.b.unwrap().eval();
MulNodeInput { a, b }
}
}
use dyn_any::{downcast_ref, DynAny, StaticType};
use graphene_std::{DynAnyNode, DynNode, DynamicInput, Node};
pub struct MulNodeInput<'n> {
pub a: &'n f32,
pub b: &'n f32,
}
#[derive(Copy, Clone)]
pub struct MulNodeAnyProxy<'n> {
pub a: Option<DynAnyNode<'n>>,
pub b: Option<DynAnyNode<'n>>,
}
#[derive(Copy, Clone)]
pub struct MulNodeTypedProxy<'n> {
pub a: Option<DynNode<'n, &'n f32>>,
pub b: Option<DynNode<'n, &'n f32>>,
}
impl<'n> Node<'n> for MulNodeAnyProxy<'n> {
type Output = MulNodeInput<'n>;
fn eval(&'n self) -> <Self as graphene_std::Node<'n>>::Output {
let a = self.a.unwrap().eval();
let a: &f32 = self.a.map(|v| downcast_ref(v.eval()).unwrap()).unwrap_or(&1.);
/*let b: &f32 = self
.b
.map(|v| v.eval(&()).downcast_ref::<&'n f32, &'n f32>().unwrap())
.unwrap_or(&&2.);
a * b*/
MulNodeInput { a, b: a }
}
}
impl<'n> Node<'n> for MulNodeTypedProxy<'n> {
type Output = MulNodeInput<'n>;
fn eval(&'n self) -> <Self as graphene_std::Node<'n>>::Output {
let a = self.a.unwrap().eval();
let b = self.b.unwrap().eval();
MulNodeInput { a, b }
}
}
/*macro_rules! new {
() => {
mul::MulNode { a: None, b: None }
};
}*/
//pub(crate) use new;
/*macro_rules! new {
() => {
mul::MulNode { a: None, b: None }
};
}*/
//pub(crate) use new;
impl<'n> DynamicInput<'n> for MulNodeAnyProxy<'n> {
fn set_kwarg_by_name(&mut self, name: &str, value: DynAnyNode<'n>) {
todo!()
}
fn set_arg_by_index(&mut self, index: usize, value: DynAnyNode<'n>) {
match index {
0 => {
self.a = Some(value);
}
_ => todo!(),
}
}
}
impl<'n> DynamicInput<'n> for MulNodeAnyProxy<'n> {
fn set_kwarg_by_name(&mut self, name: &str, value: DynAnyNode<'n>) {
todo!()
}
fn set_arg_by_index(&mut self, index: usize, value: DynAnyNode<'n>) {
match index {
0 => {
self.a = Some(value);
}
_ => todo!(),
}
}
}
}
type SNode<'n> = dyn Node<'n, Output = &'n dyn DynAny<'n>>;
struct NodeStore<'n>(borrow_stack::FixedSizeStack<'n, Box<SNode<'n>>>);
impl<'n> NodeStore<'n> {
fn len(&self) -> usize {
self.0.len()
}
fn len(&self) -> usize {
self.0.len()
}
fn push(&'n mut self, f: fn(&'n [Box<SNode>]) -> Box<SNode<'n>>) {
unsafe { self.0.push(f(self.0.get())) };
}
fn push(&'n mut self, f: fn(&'n [Box<SNode>]) -> Box<SNode<'n>>) {
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 get_index(&'n self, index: usize) -> &'n SNode<'n> {
assert!(index < self.0.len());
&unsafe { self.0.get()[index] }
}*/
}
fn main() {
use graphene_std::*;
use quote::quote;
use syn::parse::Parse;
let nodes = vec![
NodeKind::Input,
NodeKind::Value(syn::parse_quote!(1u32)),
NodeKind::Node(syn::parse_quote!(graphene_core::ops::AddNode), vec![0, 0]),
];
use graphene_std::*;
use quote::quote;
use syn::parse::Parse;
let nodes = vec![
NodeKind::Input,
NodeKind::Value(syn::parse_quote!(1u32)),
NodeKind::Node(syn::parse_quote!(graphene_core::ops::AddNode), vec![0, 0]),
];
//println!("{}", node_graph(1));
//println!("{}", node_graph(1));
let nodegraph = NodeGraph {
nodes,
input: syn::Type::Verbatim(quote! {u32}),
output: syn::Type::Verbatim(quote! {u32}),
};
let nodegraph = NodeGraph {
nodes,
input: syn::Type::Verbatim(quote! {u32}),
output: syn::Type::Verbatim(quote! {u32}),
};
//let pretty = pretty_token_stream::Pretty::new(nodegraph.serialize_gpu("add"));
//pretty.print();
/*
use dyn_any::{downcast_ref, DynAny, StaticType};
//let mut mul = mul::MulNode::new();
let mut stack: borrow_stack::FixedSizeStack<Box<dyn Node<'_, Output = &dyn DynAny>>> =
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();
dbg!(downcast_ref::<f32>(result));
/*unsafe {
stack
.push(Box::new(AnyRefNode::new(stack.get(0).as_ref()))
as Box<dyn Node<(), Output = &dyn DynAny>>)
};*/
let f = (3.2f32, 3.1f32);
let a = ValueNode::new(1.);
let id = std::any::TypeId::of::<&f32>();
let any_a = AnyRefNode::new(&a);
/*let _mul2 = mul::MulNodeInput {
a: None,
b: Some(&any_a),
};
let mut mul2 = mul::new!();
//let cached = memo::CacheNode::new(&mul1);
//let foo = value::AnyRefNode::new(&cached);
mul2.set_arg_by_index(0, &any_a);*/
let int = value::IntNode::<32>;
Node::eval(&int);
println!("{}", Node::eval(&int));
//let _add: u32 = ops::AddNode::<u32>::default().eval((int.exec(), int.exec()));
//let fnode = generic::FnNode::new(|(a, b): &(i32, i32)| a - b);
//let sub = fnode.any(&("a", 2));
//let cache = memo::CacheNode::new(&fnode);
//let cached_result = cache.eval(&(2, 3));
*/
//println!("{}", cached_result)
//let pretty = pretty_token_stream::Pretty::new(nodegraph.serialize_gpu("add"));
//pretty.print();
/*
use dyn_any::{downcast_ref, DynAny, StaticType};
//let mut mul = mul::MulNode::new();
let mut stack: borrow_stack::FixedSizeStack<Box<dyn Node<'_, Output = &dyn DynAny>>> =
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();
dbg!(downcast_ref::<f32>(result));
/*unsafe {
stack
.push(Box::new(AnyRefNode::new(stack.get(0).as_ref()))
as Box<dyn Node<(), Output = &dyn DynAny>>)
};*/
let f = (3.2f32, 3.1f32);
let a = ValueNode::new(1.);
let id = std::any::TypeId::of::<&f32>();
let any_a = AnyRefNode::new(&a);
/*let _mul2 = mul::MulNodeInput {
a: None,
b: Some(&any_a),
};
let mut mul2 = mul::new!();
//let cached = memo::CacheNode::new(&mul1);
//let foo = value::AnyRefNode::new(&cached);
mul2.set_arg_by_index(0, &any_a);*/
let int = value::IntNode::<32>;
Node::eval(&int);
println!("{}", Node::eval(&int));
//let _add: u32 = ops::AddNode::<u32>::default().eval((int.exec(), int.exec()));
//let fnode = generic::FnNode::new(|(a, b): &(i32, i32)| a - b);
//let sub = fnode.any(&("a", 2));
//let cache = memo::CacheNode::new(&fnode);
//let cached_result = cache.eval(&(2, 3));
*/
//println!("{}", cached_result)
}

View file

@ -5,106 +5,93 @@ use syn::punctuated::Punctuated;
use syn::{parse_macro_input, FnArg, ItemFn, Pat, Type};
fn extract_type(a: FnArg) -> Type {
match a {
FnArg::Typed(p) => *p.ty, // notice `ty` instead of `pat`
_ => panic!("Not supported on types with `self`!"),
}
match a {
FnArg::Typed(p) => *p.ty, // notice `ty` instead of `pat`
_ => panic!("Not supported on types with `self`!"),
}
}
fn extract_arg_types(fn_args: Punctuated<FnArg, syn::token::Comma>) -> Vec<Type> {
fn_args.into_iter().map(extract_type).collect::<Vec<_>>()
fn_args.into_iter().map(extract_type).collect::<Vec<_>>()
}
fn extract_arg_idents(fn_args: Punctuated<FnArg, syn::token::Comma>) -> Vec<Pat> {
fn_args.into_iter().map(extract_arg_pat).collect::<Vec<_>>()
fn_args.into_iter().map(extract_arg_pat).collect::<Vec<_>>()
}
fn extract_arg_pat(a: FnArg) -> Pat {
match a {
FnArg::Typed(p) => *p.pat,
_ => panic!("Not supported on types with `self`!"),
}
match a {
FnArg::Typed(p) => *p.pat,
_ => panic!("Not supported on types with `self`!"),
}
}
#[proc_macro_attribute] // 2
pub fn to_node(_attr: TokenStream, item: TokenStream) -> TokenStream {
let string = item.to_string();
let item2 = item;
let parsed = parse_macro_input!(item2 as ItemFn); // 3
//item.extend(generate_to_string(parsed, string)); // 4
//item
generate_to_string(parsed, string)
let string = item.to_string();
let item2 = item;
let parsed = parse_macro_input!(item2 as ItemFn); // 3
//item.extend(generate_to_string(parsed, string)); // 4
//item
generate_to_string(parsed, string)
}
fn generate_to_string(parsed: ItemFn, string: String) -> TokenStream {
let whole_function = parsed.clone();
//let fn_body = parsed.block; // function body
let sig = parsed.sig; // function signature
//let vis = parsed.vis; // visibility, pub or not
let generics = sig.generics;
let fn_args = sig.inputs; // comma separated args
let fn_return_type = sig.output; // return type
let fn_name = sig.ident; // function name/identifier
let idents = extract_arg_idents(fn_args.clone());
let types = extract_arg_types(fn_args);
let types = types
.iter()
.map(|t| t.to_token_stream())
.collect::<Vec<_>>();
let idents = idents
.iter()
.map(|t| t.to_token_stream())
.collect::<Vec<_>>();
let const_idents = idents
.iter()
.map(|t| {
let name = t.to_string().to_uppercase();
quote! {#name}
})
.collect::<Vec<_>>();
let whole_function = parsed.clone();
//let fn_body = parsed.block; // function body
let sig = parsed.sig; // function signature
//let vis = parsed.vis; // visibility, pub or not
let generics = sig.generics;
let fn_args = sig.inputs; // comma separated args
let fn_return_type = sig.output; // return type
let fn_name = sig.ident; // function name/identifier
let idents = extract_arg_idents(fn_args.clone());
let types = extract_arg_types(fn_args);
let types = types.iter().map(|t| t.to_token_stream()).collect::<Vec<_>>();
let idents = idents.iter().map(|t| t.to_token_stream()).collect::<Vec<_>>();
let const_idents = idents
.iter()
.map(|t| {
let name = t.to_string().to_uppercase();
quote! {#name}
})
.collect::<Vec<_>>();
let node_fn_name = fn_name.append("_node");
let struct_name = fn_name.append("_input");
let return_type_string = fn_return_type
.to_token_stream()
.to_string()
.replace("->", "");
let arg_type_string = types
.iter()
.map(|t| t.to_string())
.collect::<Vec<_>>()
.join(", ");
let error = format!("called {} with the wrong type", fn_name);
let node_fn_name = fn_name.append("_node");
let struct_name = fn_name.append("_input");
let return_type_string = fn_return_type.to_token_stream().to_string().replace("->", "");
let arg_type_string = types.iter().map(|t| t.to_string()).collect::<Vec<_>>().join(", ");
let error = format!("called {} with the wrong type", fn_name);
let x = quote! {
//#whole_function
mod #fn_name {
#[derive(Copy, Clone)]
type F32Node<'n> = &'n (dyn Node<'n, (), Output = &'n (dyn Any + 'static)> + 'n);
struct #struct_name {
#(#idents: #types,)*
}
impl Node for #struct_name {
let x = quote! {
//#whole_function
mod #fn_name {
#[derive(Copy, Clone)]
type F32Node<'n> = &'n (dyn Node<'n, (), Output = &'n (dyn Any + 'static)> + 'n);
struct #struct_name {
#(#idents: #types,)*
}
impl Node for #struct_name {
}
}
}
fn #node_fn_name #generics() -> Node<'static> {
Node { func: Box::new(move |x| {
let args = x.downcast::<(#(#types,)*)>().expect(#error);
let (#(#idents,)*) = *args;
#whole_function
}
fn #node_fn_name #generics() -> Node<'static> {
Node { func: Box::new(move |x| {
let args = x.downcast::<(#(#types,)*)>().expect(#error);
let (#(#idents,)*) = *args;
#whole_function
Box::new(#fn_name(#(#idents,)*))
}),
code: #string.to_string(),
return_type: #return_type_string.trim().to_string(),
args: format!("({})",#arg_type_string.trim()),
position: (0., 0.),
}
}
Box::new(#fn_name(#(#idents,)*))
}),
code: #string.to_string(),
return_type: #return_type_string.trim().to_string(),
args: format!("({})",#arg_type_string.trim()),
position: (0., 0.),
}
}
};
//panic!("{}\n{:?}", x.to_string(), x);
x.into()
};
//panic!("{}\n{:?}", x.to_string(), x);
x.into()
}