Implement node registry (#822)
This commit is contained in:
parent
c3fbc4eac9
commit
11c6413251
|
|
@ -100,6 +100,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "borrow_stack"
|
name = "borrow_stack"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"dyn-any",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,4 @@ license = "MIT OR Apache-2.0"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
dyn-any = {path = "../../libraries/dyn-any"}
|
||||||
|
|
|
||||||
|
|
@ -5,25 +5,24 @@ use std::{
|
||||||
sync::atomic::{AtomicUsize, Ordering},
|
sync::atomic::{AtomicUsize, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait BorrowStack<'n> {
|
pub trait BorrowStack {
|
||||||
type Item;
|
type Item;
|
||||||
/// # Safety
|
/// # Safety
|
||||||
unsafe fn push(&self, value: Self::Item);
|
unsafe fn push(&self, value: Self::Item);
|
||||||
/// # Safety
|
/// # Safety
|
||||||
unsafe fn pop(&self);
|
unsafe fn pop(&self);
|
||||||
/// # Safety
|
/// # Safety
|
||||||
unsafe fn get(&self) -> &'n [Self::Item];
|
unsafe fn get(&self) -> &'static [Self::Item];
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FixedSizeStack<'n, T> {
|
pub struct FixedSizeStack<T: dyn_any::StaticTypeSized> {
|
||||||
data: Pin<Box<[MaybeUninit<T>]>>,
|
data: Pin<Box<[MaybeUninit<T>]>>,
|
||||||
capacity: usize,
|
capacity: usize,
|
||||||
len: AtomicUsize,
|
len: AtomicUsize,
|
||||||
_phantom: PhantomData<&'n ()>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'n, T: Unpin + 'n> FixedSizeStack<'n, T> {
|
impl<'n, T: Unpin + 'n + dyn_any::StaticTypeSized> FixedSizeStack<T> {
|
||||||
pub fn new(capacity: usize) -> Self {
|
pub fn new(capacity: usize) -> Self {
|
||||||
let layout = std::alloc::Layout::array::<MaybeUninit<T>>(capacity).unwrap();
|
let layout = std::alloc::Layout::array::<MaybeUninit<T>>(capacity).unwrap();
|
||||||
let array = unsafe { std::alloc::alloc(layout) };
|
let array = unsafe { std::alloc::alloc(layout) };
|
||||||
|
|
@ -33,7 +32,6 @@ impl<'n, T: Unpin + 'n> FixedSizeStack<'n, T> {
|
||||||
data: array,
|
data: array,
|
||||||
capacity,
|
capacity,
|
||||||
len: AtomicUsize::new(0),
|
len: AtomicUsize::new(0),
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,19 +42,19 @@ impl<'n, T: Unpin + 'n> FixedSizeStack<'n, T> {
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.len.load(Ordering::SeqCst) == 0
|
self.len.load(Ordering::SeqCst) == 0
|
||||||
}
|
}
|
||||||
pub fn push_fn(&self, f: impl FnOnce(&'n [T]) -> T) {
|
pub fn push_fn(&self, f: impl FnOnce(&'static [T::Static]) -> T) {
|
||||||
unsafe { self.push(f(self.get())) }
|
unsafe { self.push(std::mem::transmute_copy(&f(self.get()))) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'n, T> BorrowStack<'n> for FixedSizeStack<'n, T> {
|
impl<'n, T: 'n + dyn_any::StaticTypeSized> BorrowStack for FixedSizeStack<T> {
|
||||||
type Item = T;
|
type Item = T::Static;
|
||||||
|
|
||||||
unsafe fn push(&self, value: Self::Item) {
|
unsafe fn push(&self, value: Self::Item) {
|
||||||
let len = self.len.load(Ordering::SeqCst);
|
let len = self.len.load(Ordering::SeqCst);
|
||||||
assert!(len < self.capacity);
|
assert!(len < self.capacity);
|
||||||
let ptr = self.data[len].as_ptr();
|
let ptr = self.data[len].as_ptr();
|
||||||
(ptr as *mut T).write(value);
|
(ptr as *mut T::Static).write(value);
|
||||||
self.len.fetch_add(1, Ordering::SeqCst);
|
self.len.fetch_add(1, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,8 +64,8 @@ impl<'n, T> BorrowStack<'n> for FixedSizeStack<'n, T> {
|
||||||
self.len.fetch_sub(1, Ordering::SeqCst);
|
self.len.fetch_sub(1, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn get(&self) -> &'n [Self::Item] {
|
unsafe fn get(&self) -> &'static [Self::Item] {
|
||||||
std::slice::from_raw_parts(self.data.as_ptr() as *const T, self.len.load(Ordering::SeqCst))
|
std::slice::from_raw_parts(self.data.as_ptr() as *const T::Static, self.len.load(Ordering::SeqCst))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AsBoxNode<'n, T>
|
pub trait AsRefNode<'n, T>
|
||||||
where
|
where
|
||||||
&'n Self: Node<T>,
|
&'n Self: Node<T>,
|
||||||
Self: 'n,
|
Self: 'n,
|
||||||
|
|
@ -57,7 +57,7 @@ where
|
||||||
fn eval_box(&'n self, input: T) -> <Self>::Output;
|
fn eval_box(&'n self, input: T) -> <Self>::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'n, N: 'n, I> AsBoxNode<'n, I> for N
|
impl<'n, N: 'n, I> AsRefNode<'n, I> for N
|
||||||
where
|
where
|
||||||
&'n N: Node<I, Output = N::Output>,
|
&'n N: Node<I, Output = N::Output>,
|
||||||
N: Node<I>,
|
N: Node<I>,
|
||||||
|
|
@ -69,7 +69,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'n, T> Node<T> for &'n (dyn AsBoxNode<'n, T, Output = T> + 'n) {
|
impl<'n, T> Node<T> for &'n (dyn AsRefNode<'n, T, Output = T> + 'n) {
|
||||||
type Output = T;
|
type Output = T;
|
||||||
fn eval(self, input: T) -> Self::Output {
|
fn eval(self, input: T) -> Self::Output {
|
||||||
self.eval_box(input)
|
self.eval_box(input)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::ops::Add;
|
use core::ops::Add;
|
||||||
|
|
||||||
use crate::Node;
|
use crate::{Node, RefNode};
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct AddNode;
|
pub struct AddNode;
|
||||||
|
|
@ -153,18 +153,24 @@ impl<'n, T: Clone + 'n> Node<T> for DupNode {
|
||||||
/// Return the Input Argument
|
/// Return the Input Argument
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct IdNode;
|
pub struct IdNode;
|
||||||
impl<'n, T: 'n> Node<T> for IdNode {
|
impl<T> Node<T> for IdNode {
|
||||||
type Output = T;
|
type Output = T;
|
||||||
fn eval(self, input: T) -> Self::Output {
|
fn eval(self, input: T) -> Self::Output {
|
||||||
input
|
input
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'n, T: 'n> Node<T> for &'n IdNode {
|
impl<'n, T> Node<T> for &'n IdNode {
|
||||||
type Output = T;
|
type Output = T;
|
||||||
fn eval(self, input: T) -> Self::Output {
|
fn eval(self, input: T) -> Self::Output {
|
||||||
input
|
input
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<T> RefNode<T> for IdNode {
|
||||||
|
type Output = T;
|
||||||
|
fn eval_ref(&self, input: T) -> Self::Output {
|
||||||
|
input
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct MapResultNode<MN, I, E>(pub MN, pub PhantomData<(I, E)>);
|
pub struct MapResultNode<MN, I, E>(pub MN, pub PhantomData<(I, E)>);
|
||||||
|
|
||||||
|
|
@ -177,7 +183,7 @@ impl<MN: Node<I>, I, E> Node<Result<I, E>> for MapResultNode<MN, I, E> {
|
||||||
impl<'n, MN: Node<I> + Copy, I, E> Node<Result<I, E>> for &'n MapResultNode<MN, I, E> {
|
impl<'n, MN: Node<I> + Copy, I, E> Node<Result<I, E>> for &'n MapResultNode<MN, I, E> {
|
||||||
type Output = Result<MN::Output, E>;
|
type Output = Result<MN::Output, E>;
|
||||||
fn eval(self, input: Result<I, E>) -> Self::Output {
|
fn eval(self, input: Result<I, E>) -> Self::Output {
|
||||||
input.map(|x| (&self.0).eval(x))
|
input.map(|x| self.0.eval(x))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use crate::{Node, RefNode};
|
use crate::{AsRefNode, Node, RefNode};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ComposeNode<First, Second, Input> {
|
pub struct ComposeNode<First, Second, Input> {
|
||||||
|
|
@ -26,17 +26,19 @@ where
|
||||||
}
|
}
|
||||||
impl<'n, Input, Inter, First, Second> Node<Input> for &'n ComposeNode<First, Second, Input>
|
impl<'n, Input, Inter, First, Second> Node<Input> for &'n ComposeNode<First, Second, Input>
|
||||||
where
|
where
|
||||||
First: RefNode<Input, Output = Inter> + Copy,
|
First: AsRefNode<'n, Input, Output = Inter>,
|
||||||
Second: RefNode<Inter> + Copy,
|
Second: AsRefNode<'n, Inter>,
|
||||||
|
&'n First: Node<Input, Output = Inter>,
|
||||||
|
&'n Second: Node<Inter>,
|
||||||
{
|
{
|
||||||
type Output = <Second as RefNode<Inter>>::Output;
|
type Output = <Second as AsRefNode<'n, Inter>>::Output;
|
||||||
|
|
||||||
fn eval(self, input: Input) -> Self::Output {
|
fn eval(self, input: Input) -> Self::Output {
|
||||||
// evaluate the first node with the given input
|
// evaluate the first node with the given input
|
||||||
// and then pipe the result from the first computation
|
// and then pipe the result from the first computation
|
||||||
// into the second node
|
// into the second node
|
||||||
let arg: Inter = (self.first).eval_ref(input);
|
let arg: Inter = (self.first).eval_box(input);
|
||||||
(self.second).eval_ref(arg)
|
(self.second).eval_box(arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<Input, Inter, First, Second> RefNode<Input> for ComposeNode<First, Second, Input>
|
impl<Input, Inter, First, Second> RefNode<Input> for ComposeNode<First, Second, Input>
|
||||||
|
|
@ -136,3 +138,8 @@ impl<'n, Root: Node<T> + Copy, T: From<()>, Input> Node<Input> for &'n ConsNode<
|
||||||
(input, arg)
|
(input, arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<Root, T: From<()>> ConsNode<Root, T> {
|
||||||
|
pub fn new(root: Root) -> Self {
|
||||||
|
ConsNode(root, PhantomData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
pub mod node_registry;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
|
|
@ -7,7 +9,7 @@ mod tests {
|
||||||
use graphene_core::{structural::*, RefNode};
|
use graphene_core::{structural::*, RefNode};
|
||||||
|
|
||||||
use borrow_stack::BorrowStack;
|
use borrow_stack::BorrowStack;
|
||||||
use dyn_any::{downcast, DynAny, IntoDynAny};
|
use dyn_any::{downcast, IntoDynAny};
|
||||||
use graphene_std::any::{Any, DowncastNode, DynAnyNode, TypeErasedNode};
|
use graphene_std::any::{Any, DowncastNode, DynAnyNode, TypeErasedNode};
|
||||||
use graphene_std::ops::AddNode;
|
use graphene_std::ops::AddNode;
|
||||||
|
|
||||||
|
|
@ -19,7 +21,8 @@ mod tests {
|
||||||
stack.push(dynanynode.into_box());
|
stack.push(dynanynode.into_box());
|
||||||
}
|
}
|
||||||
stack.push_fn(|nodes| {
|
stack.push_fn(|nodes| {
|
||||||
let downcast: DowncastNode<_, &u32> = DowncastNode::new(&nodes[0]);
|
let pre_node = nodes.get(0).unwrap();
|
||||||
|
let downcast: DowncastNode<&TypeErasedNode, &u32> = DowncastNode::new(pre_node);
|
||||||
let dynanynode: DynAnyNode<ConsNode<_, Any<'_>>, u32, _, _> = DynAnyNode::new(ConsNode(downcast, PhantomData));
|
let dynanynode: DynAnyNode<ConsNode<_, Any<'_>>, u32, _, _> = DynAnyNode::new(ConsNode(downcast, PhantomData));
|
||||||
dynanynode.into_box()
|
dynanynode.into_box()
|
||||||
});
|
});
|
||||||
|
|
@ -39,17 +42,6 @@ mod tests {
|
||||||
assert_eq!(*downcast::<u32>(add).unwrap(), 6_u32);
|
assert_eq!(*downcast::<u32>(add).unwrap(), 6_u32);
|
||||||
let add = unsafe { &stack.get()[3] }.eval_ref(4_u32.into_dyn());
|
let add = unsafe { &stack.get()[3] }.eval_ref(4_u32.into_dyn());
|
||||||
assert_eq!(*downcast::<u32>(add).unwrap(), 6_u32);
|
assert_eq!(*downcast::<u32>(add).unwrap(), 6_u32);
|
||||||
|
|
||||||
/*
|
|
||||||
for i in 0..3 {
|
|
||||||
println!("node_id: {}", i);
|
|
||||||
let value = unsafe { &stack.get()[i] };
|
|
||||||
input = value.eval_ref(input);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//assert_eq!(*dyn_any::downcast::<u32>(result).unwrap(), 4)
|
|
||||||
|
|
||||||
//assert_eq!(4, *dyn_any::downcast::<u32>(DynamicAddNode.eval((Box::new(2_u32) as Dynamic, Box::new(2_u32) as Dynamic))).unwrap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use borrow_stack::FixedSizeStack;
|
||||||
|
use graphene_core::ops::{AddNode, IdNode};
|
||||||
|
use graphene_core::structural::{ConsNode, Then};
|
||||||
|
use graphene_core::{AsRefNode, Node};
|
||||||
|
use graphene_std::{
|
||||||
|
any::{Any, DowncastNode, DynAnyNode, IntoTypeErasedNode, TypeErasedNode},
|
||||||
|
document::{ConstructionArgs, ProtoNode, ProtoNodeInput},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NodeIdentifier {
|
||||||
|
name: &'static str,
|
||||||
|
types: &'static [&'static str],
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn annotate<'n, 's: 'n, F>(f: F) -> F
|
||||||
|
where
|
||||||
|
F: Fn(ProtoNode, FixedSizeStack<TypeErasedNode<'n>>),
|
||||||
|
{
|
||||||
|
f
|
||||||
|
}
|
||||||
|
|
||||||
|
use borrow_stack::BorrowStack;
|
||||||
|
unsafe fn foo<'n>(proto_node: ProtoNode, stack: &'n FixedSizeStack<TypeErasedNode<'n>>) {
|
||||||
|
let node_id = proto_node.input.unwrap_node() as usize;
|
||||||
|
let nodes = stack.get();
|
||||||
|
let pre_node = nodes.get(node_id).unwrap();
|
||||||
|
let downcast: DowncastNode<_, &u32> = DowncastNode::new(pre_node);
|
||||||
|
let dynanynode: DynAnyNode<ConsNode<_, Any<'_>>, u32, _, _> = DynAnyNode::new(ConsNode(downcast, PhantomData));
|
||||||
|
stack.push(dynanynode.into_box());
|
||||||
|
}
|
||||||
|
fn borrow_stack() {
|
||||||
|
let stack = borrow_stack::FixedSizeStack::new(256);
|
||||||
|
unsafe {
|
||||||
|
{
|
||||||
|
let proto_node = ProtoNode::id();
|
||||||
|
foo(proto_node, &stack);
|
||||||
|
let proto_node = ProtoNode::id();
|
||||||
|
let stack = &stack;
|
||||||
|
let node_id = proto_node.input.unwrap_node() as usize;
|
||||||
|
let nodes = stack.get();
|
||||||
|
let pre_node = nodes.get(node_id).unwrap();
|
||||||
|
let downcast: DowncastNode<&TypeErasedNode, &u32> = DowncastNode::new(pre_node);
|
||||||
|
let dynanynode: DynAnyNode<ConsNode<_, Any<'_>>, u32, _, _> = DynAnyNode::new(ConsNode(downcast, PhantomData));
|
||||||
|
stack.push(dynanynode.into_box());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static NODE_REGISTRY: &[(NodeIdentifier, fn(ProtoNode, &FixedSizeStack<TypeErasedNode<'static>>))] = &[
|
||||||
|
(
|
||||||
|
NodeIdentifier {
|
||||||
|
name: "graphene_core::ops::IdNode",
|
||||||
|
types: &["Any<'n>"],
|
||||||
|
},
|
||||||
|
|proto_node, stack| {
|
||||||
|
stack.push_fn(|nodes| {
|
||||||
|
let pre_node = nodes.get(proto_node.input.unwrap_node() as usize).unwrap();
|
||||||
|
let node = pre_node.then(graphene_core::ops::IdNode);
|
||||||
|
node.into_type_erased()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
NodeIdentifier {
|
||||||
|
name: "graphene_core::ops::AddNode",
|
||||||
|
types: &["u32", "u32"],
|
||||||
|
},
|
||||||
|
|proto_node, stack| {
|
||||||
|
stack.push_fn(|nodes| {
|
||||||
|
let pre_node = nodes.get(proto_node.input.unwrap_node() as usize).unwrap();
|
||||||
|
let node: DynAnyNode<AddNode, (u32, u32), _, _> = DynAnyNode::new(graphene_core::ops::AddNode);
|
||||||
|
let node = (pre_node).then(node);
|
||||||
|
|
||||||
|
node.into_type_erased()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
),
|
||||||
|
/*(
|
||||||
|
NodeIdentifier {
|
||||||
|
name: "graphene_core::structural::ConsNode",
|
||||||
|
types: &["&TypeErasedNode", "&u32", "u32"],
|
||||||
|
},
|
||||||
|
|proto_node, stack| {
|
||||||
|
let node_id = proto_node.input.unwrap_node() as usize;
|
||||||
|
stack.push_fn(move |nodes| {
|
||||||
|
let pre_node = nodes.get(node_id).unwrap();
|
||||||
|
let downcast: DowncastNode<_, &u32> = DowncastNode::new(pre_node);
|
||||||
|
let dynanynode: DynAnyNode<ConsNode<_, Any<'_>>, u32, _, _> = DynAnyNode::new(ConsNode(downcast, PhantomData));
|
||||||
|
dynanynode.into_box()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
),*/
|
||||||
|
(
|
||||||
|
NodeIdentifier {
|
||||||
|
name: "graphene_core::any::DowncastNode",
|
||||||
|
types: &["&TypeErasedNode", "&u32"],
|
||||||
|
},
|
||||||
|
|proto_node, stack| {
|
||||||
|
stack.push_fn(|nodes| {
|
||||||
|
let pre_node = nodes.get(proto_node.input.unwrap_node() as usize).unwrap();
|
||||||
|
let node = pre_node.then(graphene_core::ops::IdNode);
|
||||||
|
node.into_type_erased()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
/*#[test]
|
||||||
|
fn test() {
|
||||||
|
let nodes = [TypeErasedNode(Box::new(42u32))];
|
||||||
|
let node = NODE_REGISTRY[0].1(node, &nodes);
|
||||||
|
assert_eq!(node.eval(()), 42);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use dyn_any::{DynAny, StaticType};
|
use dyn_any::{DynAny, StaticType, StaticTypeSized};
|
||||||
pub use graphene_core::{generic, ops /*, structural*/, Node, RefNode};
|
pub use graphene_core::{generic, ops /*, structural*/, Node, RefNode};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
|
@ -6,7 +6,7 @@ fn fmt_error<I>() -> String {
|
||||||
format!("DynAnyNode: input is not of correct type, expected {}", std::any::type_name::<I>())
|
format!("DynAnyNode: input is not of correct type, expected {}", std::any::type_name::<I>())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DynAnyNode<N, I: StaticType, O: StaticType, ORef: StaticType>(pub N, PhantomData<(I, O, ORef)>);
|
pub struct DynAnyNode<N, I: StaticType, O: StaticType, ORef: StaticType>(pub N, pub PhantomData<(I, O, ORef)>);
|
||||||
/*impl<'n, I: StaticType, N: RefNode<'n, &'n I, Output = O> + 'n, O: 'n + StaticType> Node<&'n dyn DynAny<'n>> for DynAnyNode<'n, N, I> {
|
/*impl<'n, I: StaticType, N: RefNode<'n, &'n I, Output = O> + 'n, O: 'n + StaticType> Node<&'n dyn DynAny<'n>> for DynAnyNode<'n, N, I> {
|
||||||
type Output = Box<dyn dyn_any::DynAny<'n> + 'n>;
|
type Output = Box<dyn dyn_any::DynAny<'n> + 'n>;
|
||||||
fn eval(self, input: &'n dyn DynAny<'n>) -> Self::Output {
|
fn eval(self, input: &'n dyn DynAny<'n>) -> Self::Output {
|
||||||
|
|
@ -49,13 +49,37 @@ where
|
||||||
Box::new((&self.0).eval_ref(*input))
|
Box::new((&self.0).eval_ref(*input))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub struct TypeErasedNode<'n>(pub Box<dyn AsBoxNode<'n, Any<'n>, Output = Any<'n>>>);
|
pub struct TypeErasedNode<'n>(pub Box<dyn AsRefNode<'n, Any<'n>, Output = Any<'n>> + 'n>);
|
||||||
impl<'n> Node<Any<'n>> for &'n TypeErasedNode<'n> {
|
impl<'n> Node<Any<'n>> for &'n TypeErasedNode<'n> {
|
||||||
type Output = Any<'n>;
|
type Output = Any<'n>;
|
||||||
fn eval(self, input: Any<'n>) -> Self::Output {
|
fn eval(self, input: Any<'n>) -> Self::Output {
|
||||||
self.0.eval_box(input)
|
self.0.eval_box(input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'n> Node<Any<'n>> for &'n &'n TypeErasedNode<'n> {
|
||||||
|
type Output = Any<'n>;
|
||||||
|
fn eval(self, input: Any<'n>) -> Self::Output {
|
||||||
|
self.0.eval_box(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait IntoTypeErasedNode<'n> {
|
||||||
|
fn into_type_erased(self) -> TypeErasedNode<'n>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n> StaticTypeSized for TypeErasedNode<'n> {
|
||||||
|
type Static = TypeErasedNode<'static>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n, N: 'n> IntoTypeErasedNode<'n> for N
|
||||||
|
where
|
||||||
|
N: AsRefNode<'n, Any<'n>, Output = Any<'n>>,
|
||||||
|
&'n N: Node<Any<'n>, Output = Any<'n>>,
|
||||||
|
{
|
||||||
|
fn into_type_erased(self) -> TypeErasedNode<'n> {
|
||||||
|
TypeErasedNode(Box::new(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'n, I: StaticType + 'n, N: 'n, O: 'n + StaticType, ORef: 'n + StaticType> DynAnyNode<N, I, O, ORef>
|
impl<'n, I: StaticType + 'n, N: 'n, O: 'n + StaticType, ORef: 'n + StaticType> DynAnyNode<N, I, O, ORef>
|
||||||
where
|
where
|
||||||
|
|
@ -81,11 +105,19 @@ where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
N: Node<I, Output = O>,
|
N: Node<I, Output = O>,
|
||||||
{
|
{
|
||||||
TypeErasedNode(Box::new(self))
|
self.into_type_erased()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'n, I: StaticType + 'n, N: 'n, O: 'n + StaticType, ORef: 'n + StaticType> DynAnyNode<&'n N, I, O, ORef>
|
||||||
|
where
|
||||||
|
N: Node<I, Output = ORef>,
|
||||||
|
{
|
||||||
|
pub fn new_from_ref(n: &'n N) -> Self {
|
||||||
|
DynAnyNode(n, PhantomData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DowncastNode<N, I: StaticType>(pub N, PhantomData<I>);
|
pub struct DowncastNode<N, I: StaticType>(pub N, pub PhantomData<I>);
|
||||||
impl<N: Copy + Clone, I: StaticType> Clone for DowncastNode<N, I> {
|
impl<N: Copy + Clone, I: StaticType> Clone for DowncastNode<N, I> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self(self.0, self.1)
|
Self(self.0, self.1)
|
||||||
|
|
@ -127,7 +159,7 @@ where
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
use graphene_core::{ops::Dynamic, AsBoxNode};
|
use graphene_core::{ops::Dynamic, AsRefNode};
|
||||||
pub struct BoxedComposition<'a, Second> {
|
pub struct BoxedComposition<'a, Second> {
|
||||||
pub first: Box<dyn Node<(), Output = Dynamic<'a>>>,
|
pub first: Box<dyn Node<(), Output = Dynamic<'a>>>,
|
||||||
pub second: Second,
|
pub second: Second,
|
||||||
|
|
|
||||||
|
|
@ -198,6 +198,15 @@ impl NodeInput {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ProtoNodeInput {
|
||||||
|
pub fn unwrap_node(self) -> NodeId {
|
||||||
|
match self {
|
||||||
|
ProtoNodeInput::Node(id) => id,
|
||||||
|
_ => panic!("tried to unwrap id from non node input"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ProtoNode {
|
impl ProtoNode {
|
||||||
pub fn id() -> Self {
|
pub fn id() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue