Some initial testing on dynamic nodes and composition
* Test use of borrow stack
This commit is contained in:
parent
2ced9a57c4
commit
cef58b16c2
|
|
@ -340,6 +340,17 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "graph-craft"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"borrow_stack",
|
||||
"dyn-any",
|
||||
"graphene-core",
|
||||
"graphene-std",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "graph-proc-macros"
|
||||
version = "0.1.0"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ members = [
|
|||
"frontend/wasm",
|
||||
"node-graph/gcore",
|
||||
"node-graph/gstd",
|
||||
"node-graph/graph-craft",
|
||||
"node-graph/borrow_stack",
|
||||
"libraries/dyn-any",
|
||||
"libraries/bezier-rs",
|
||||
|
|
|
|||
|
|
@ -142,3 +142,9 @@ macro_rules! impl_tuple {
|
|||
impl_tuple! {
|
||||
A B C D E F G H I J K L
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple_downcast() {
|
||||
let x = Box::new(3_u32) as Box<dyn DynAny>;
|
||||
assert_eq!(*downcast::<u32>(x).unwrap(), 3_u32);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,52 @@ impl<'n, L: Add<R, Output = O> + 'n + Copy, R: Copy, O: 'n> Node<&'n (L, R)> for
|
|||
}
|
||||
}
|
||||
|
||||
// Unfortunatly we can't impl the AddNode as we get
|
||||
// `upstream crates may add a new impl of trait `core::ops::Add` for type `alloc::boxed::Box<(dyn dyn_any::DynAny<'_> + 'static)>` in future versions`
|
||||
pub struct DynamicAddNode;
|
||||
|
||||
// Alias for a dynamic type
|
||||
pub type Dynamic<'a> = alloc::boxed::Box<dyn dyn_any::DynAny<'a> + 'a>;
|
||||
|
||||
/// Resolves the dynamic types for a dynamic node.
|
||||
///
|
||||
/// Macro uses format `BaseNode => (arg1: u32) (arg1: i32)`
|
||||
macro_rules! resolve_dynamic_types {
|
||||
($node:ident => $(($($arg:ident : $t:ty),*))*) => {
|
||||
$(
|
||||
// Check for each possible set of arguments if their types match the arguments given
|
||||
if $(core::any::TypeId::of::<$t>() == $arg.type_id())&&* {
|
||||
// Cast the arguments and then call the inner node
|
||||
alloc::boxed::Box::new($node.eval(($(*dyn_any::downcast::<$t>($arg).unwrap()),*)) ) as Dynamic
|
||||
}
|
||||
)else*
|
||||
else{
|
||||
panic!("Unhandled type"); // TODO: Exit neatly (although this should probably not happen)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl<'n> Node<(Dynamic<'n>, Dynamic<'n>)> for DynamicAddNode {
|
||||
type Output = Dynamic<'n>;
|
||||
fn eval(self, (left, right): (Dynamic, Dynamic)) -> Self::Output {
|
||||
resolve_dynamic_types! { AddNode =>
|
||||
(left: usize, right: usize)
|
||||
(left: u8, right: u8)
|
||||
(left: u16, right: u16)
|
||||
(left: u32, right: u32)
|
||||
(left: u64, right: u64)
|
||||
(left: u128, right: u128)
|
||||
(left: isize, right: isize)
|
||||
(left: i8, right: i8)
|
||||
(left: i16, right: i16)
|
||||
(left: i32, right: i32)
|
||||
(left: i64, right: i64)
|
||||
(left: i128, right: i128)
|
||||
(left: f32, right: f32)
|
||||
(left: f64, right: f64) }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct CloneNode;
|
||||
impl<'n, O: Clone> Node<&'n O> for CloneNode {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
[package]
|
||||
name = "graph-craft"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
graphene-core = { path = "../gcore", features = ["async", "std"] }
|
||||
graphene-std = { path = "../gstd" }
|
||||
dyn-any = { path = "../../libraries/dyn-any" }
|
||||
num-traits = "0.2"
|
||||
borrow_stack = { path = "../borrow_stack" }
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use graphene_core::structural::*;
|
||||
use graphene_core::value::ValueNode;
|
||||
|
||||
use borrow_stack::BorrowStack;
|
||||
use graphene_std::any::{Any, DynAnyNode, DynAnyNodeTrait};
|
||||
use graphene_std::ops::AddNode;
|
||||
|
||||
#[test]
|
||||
fn borrow_stack() {
|
||||
let stack = borrow_stack::FixedSizeStack::new(256);
|
||||
unsafe {
|
||||
let dynanynode: DynAnyNode<'_, _, ()> = DynAnyNode::new(&ValueNode(2_u32));
|
||||
let refn = Box::new(dynanynode) as Box<dyn DynAnyNodeTrait>;
|
||||
stack.push(refn);
|
||||
}
|
||||
unsafe {
|
||||
let dynanynode: DynAnyNode<'_, _, &u32> = DynAnyNode::new(&ConsNode(ValueNode(2_u32)));
|
||||
let refn = Box::new(dynanynode) as Box<dyn DynAnyNodeTrait>;
|
||||
stack.push(refn);
|
||||
}
|
||||
unsafe {
|
||||
let dynanynode: DynAnyNode<'_, _, (&u32, u32)> = DynAnyNode::new(&AddNode);
|
||||
let refn = Box::new(dynanynode) as Box<dyn DynAnyNodeTrait>;
|
||||
stack.push(refn);
|
||||
}
|
||||
|
||||
let mut input = Box::new(()) as Any;
|
||||
for i in 0..3 {
|
||||
let value = unsafe { &stack.get()[i] };
|
||||
input = value.eval_ref_dispatch(input);
|
||||
}
|
||||
|
||||
assert_eq!(*dyn_any::downcast::<u32>(input).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]
|
||||
fn craft_from_flattened() {
|
||||
use graphene_std::document::*;
|
||||
// This is input and evaluated
|
||||
let construction_network = NodeNetwork {
|
||||
inputs: vec![10],
|
||||
output: 1,
|
||||
nodes: [
|
||||
(
|
||||
1,
|
||||
DocumentNode {
|
||||
name: "Inc".into(),
|
||||
inputs: vec![],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNode {
|
||||
name: "id".into(),
|
||||
input: ProtoNodeInput::Node(11),
|
||||
construction_args: ConstructionArgs::None,
|
||||
}),
|
||||
},
|
||||
),
|
||||
(
|
||||
10,
|
||||
DocumentNode {
|
||||
name: "cons".into(),
|
||||
inputs: vec![],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNode {
|
||||
name: "cons".into(),
|
||||
input: ProtoNodeInput::Network,
|
||||
construction_args: ConstructionArgs::Nodes(vec![14]),
|
||||
}),
|
||||
},
|
||||
),
|
||||
(
|
||||
11,
|
||||
DocumentNode {
|
||||
name: "add".into(),
|
||||
inputs: vec![],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNode {
|
||||
name: "add".into(),
|
||||
input: ProtoNodeInput::Node(10),
|
||||
construction_args: ConstructionArgs::None,
|
||||
}),
|
||||
},
|
||||
),
|
||||
(
|
||||
14,
|
||||
DocumentNode {
|
||||
name: "Value: 2".into(),
|
||||
inputs: vec![],
|
||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNode {
|
||||
name: "value".into(),
|
||||
input: ProtoNodeInput::None,
|
||||
construction_args: ConstructionArgs::Value(2_u32.into_any()),
|
||||
}),
|
||||
},
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -57,6 +57,33 @@ where
|
|||
self
|
||||
}
|
||||
}
|
||||
/// If we store a `Box<dyn RefNode>` in the stack then the origional DynAnyNode is dropped (because it is not stored by reference)
|
||||
/// This trait is implemented directly by `DynAnyNode` so this means the borrow stack will hold by value
|
||||
pub trait DynAnyNodeTrait<'n> {
|
||||
fn eval_ref_dispatch(&'n self, input: Any<'n>) -> Any<'n>;
|
||||
}
|
||||
impl<'n, I: StaticType, O: 'n + StaticType, Node: RefNode<I, Output = O> + Copy + 'n> DynAnyNodeTrait<'n> for DynAnyNode<'n, Node, I> {
|
||||
fn eval_ref_dispatch(&'n self, input: Any<'n>) -> Any<'n> {
|
||||
self.eval_ref(input)
|
||||
}
|
||||
}
|
||||
|
||||
use graphene_core::ops::Dynamic;
|
||||
pub struct BoxedComposition<'a, Second> {
|
||||
pub first: Box<dyn Node<(), Output = Dynamic<'a>>>,
|
||||
pub second: Second,
|
||||
}
|
||||
|
||||
// I can't see to get this to work
|
||||
// We can't use the existing thing in any as it breaks lifetimes
|
||||
// impl<'a, Second: Node<Dynamic<'a>>> Node<()> for BoxedComposition<'a, Second> {
|
||||
// type Output = <Second as Node<Dynamic<'a>>>::Output;
|
||||
// fn eval(self, input: ()) -> Self::Output {
|
||||
// let x = RefNode::eval_ref(self.first.as_ref(), input);
|
||||
// let arg: Dynamic<'a> = x.eval_ref(input);
|
||||
// (self.second).eval(arg)
|
||||
// }
|
||||
// }
|
||||
|
||||
/*impl<'n: 'static, I: StaticType, N, O: 'n + StaticType> DynAnyNode<'n, N, I>
|
||||
where
|
||||
|
|
@ -131,6 +158,9 @@ mod test {
|
|||
pub fn dyn_input_storage_composition() {
|
||||
let mut vec: Vec<&(dyn RefNode<Any, Output = Any>)> = vec![];
|
||||
//let id: DynAnyNode<_, u32> = DynAnyNode::new(IdNode);
|
||||
|
||||
// If we put this until the push in a new scope then it failes to compile due to lifetime errors which I'm struggling to fix.
|
||||
|
||||
let value: &DynAnyNode<&ValueNode<(u32, u32)>, ()> = &DynAnyNode(&ValueNode((3u32, 4u32)), PhantomData);
|
||||
let add: &DynAnyNode<&AddNode, &(u32, u32)> = &DynAnyNode(&AddNode, PhantomData);
|
||||
|
||||
|
|
@ -138,6 +168,7 @@ mod test {
|
|||
let add_ref = (&add).into_ref();
|
||||
vec.push(value_ref);
|
||||
vec.push(add_ref);
|
||||
|
||||
//vec.push(add.as_owned());
|
||||
//vec.push(id.as_owned());
|
||||
//let vec = vec.leak();
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@ fn merge_ids(a: u64, b: u64) -> u64 {
|
|||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct DocumentNode {
|
||||
name: String,
|
||||
inputs: Vec<NodeInput>,
|
||||
implementation: DocumentNodeImplementation,
|
||||
pub name: String,
|
||||
pub inputs: Vec<NodeInput>,
|
||||
pub implementation: DocumentNodeImplementation,
|
||||
}
|
||||
|
||||
impl DocumentNode {
|
||||
|
|
@ -114,9 +114,9 @@ pub enum DocumentNodeImplementation {
|
|||
|
||||
#[derive(Debug, Default, PartialEq)]
|
||||
pub struct NodeNetwork {
|
||||
inputs: Vec<NodeId>,
|
||||
output: NodeId,
|
||||
nodes: HashMap<NodeId, DocumentNode>,
|
||||
pub inputs: Vec<NodeId>,
|
||||
pub output: NodeId,
|
||||
pub nodes: HashMap<NodeId, DocumentNode>,
|
||||
}
|
||||
pub type Value = Box<dyn ValueTrait>;
|
||||
pub trait ValueTrait: DynAny<'static> + std::fmt::Debug {}
|
||||
|
|
@ -177,9 +177,9 @@ impl PartialEq for ConstructionArgs {
|
|||
|
||||
#[derive(Debug, Default, PartialEq)]
|
||||
pub struct ProtoNode {
|
||||
construction_args: ConstructionArgs,
|
||||
input: ProtoNodeInput,
|
||||
name: String,
|
||||
pub construction_args: ConstructionArgs,
|
||||
pub input: ProtoNodeInput,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Eq)]
|
||||
|
|
|
|||
Loading…
Reference in New Issue