mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-07-16 12:15:00 +00:00
Impl DynNode
This commit is contained in:
parent
f73836b838
commit
71f12db1e6
16 changed files with 433 additions and 84 deletions
40
Cargo.lock
generated
40
Cargo.lock
generated
|
@ -234,9 +234,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
|
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_logger"
|
name = "env_logger"
|
||||||
|
@ -253,16 +253,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "exr"
|
name = "exr"
|
||||||
version = "1.4.2"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "14cc0e06fb5f67e5d6beadf3a382fec9baca1aa751c6d5368fdeee7e5932c215"
|
checksum = "78c26a90d9dd411a3d119d6f55752fb4c134ca243250c32fb9cab7b2561638d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"deflate",
|
|
||||||
"flume",
|
"flume",
|
||||||
"half",
|
"half",
|
||||||
"inflate",
|
|
||||||
"lebe",
|
"lebe",
|
||||||
|
"miniz_oxide",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"threadpool",
|
"threadpool",
|
||||||
]
|
]
|
||||||
|
@ -298,15 +297,15 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.21"
|
version = "0.3.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
|
checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.21"
|
version = "0.3.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868"
|
checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
|
@ -479,15 +478,6 @@ dependencies = [
|
||||||
"tiff",
|
"tiff",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "inflate"
|
|
||||||
version = "0.4.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
|
|
||||||
dependencies = [
|
|
||||||
"adler32",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -529,9 +519,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lebe"
|
name = "lebe"
|
||||||
version = "0.5.1"
|
version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7efd1d698db0759e6ef11a7cd44407407399a910c774dd804c64c032da7826ff"
|
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
|
@ -646,18 +636,18 @@ checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.0.11"
|
version = "1.0.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78203e83c48cffbe01e4a2d35d566ca4de445d79a85372fc64e378bfc812a260"
|
checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pin-project-internal",
|
"pin-project-internal",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-internal"
|
name = "pin-project-internal"
|
||||||
version = "1.0.11"
|
version = "1.0.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74"
|
checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
@ -25,6 +25,15 @@ pub fn downcast_ref<'a, V: StaticType>(i: &'a dyn DynAny<'a>) -> Option<&'a V> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn downcast<'a, V: StaticType>(i: Box<dyn DynAny<'a> + 'a>) -> Option<Box<V>> {
|
||||||
|
if i.type_id() == std::any::TypeId::of::<<V as StaticType>::Static>() {
|
||||||
|
// SAFETY: caller guarantees that T is the correct type
|
||||||
|
let ptr = Box::into_raw(i) as *mut dyn DynAny<'a> as *mut V;
|
||||||
|
Some(unsafe { Box::from_raw(ptr) })
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait StaticType {
|
pub trait StaticType {
|
||||||
type Static: 'static + ?Sized;
|
type Static: 'static + ?Sized;
|
||||||
|
@ -39,8 +48,11 @@ pub trait StaticTypeSized {
|
||||||
std::any::TypeId::of::<Self::Static>()
|
std::any::TypeId::of::<Self::Static>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a, T: StaticTypeSized> StaticType for T {
|
impl<T: StaticType + Sized> StaticTypeSized for T
|
||||||
type Static = <T as StaticTypeSized>::Static;
|
where
|
||||||
|
T::Static: Sized,
|
||||||
|
{
|
||||||
|
type Static = <T as StaticType>::Static;
|
||||||
}
|
}
|
||||||
pub trait StaticTypeClone {
|
pub trait StaticTypeClone {
|
||||||
type Static: 'static + Clone;
|
type Static: 'static + Clone;
|
||||||
|
@ -48,41 +60,44 @@ pub trait StaticTypeClone {
|
||||||
std::any::TypeId::of::<Self::Static>()
|
std::any::TypeId::of::<Self::Static>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a, T: StaticTypeClone> StaticTypeSized for T {
|
impl<T: StaticType + Clone> StaticTypeClone for T
|
||||||
type Static = <T as StaticTypeClone>::Static;
|
where
|
||||||
|
T::Static: Clone,
|
||||||
|
{
|
||||||
|
type Static = <T as StaticType>::Static;
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_type {
|
macro_rules! impl_type {
|
||||||
($($id:ident$(<$($(($l:lifetime, $s:lifetime)),*|)?$($T:ident),*>)?),*) => {
|
($($id:ident$(<$($(($l:lifetime, $s:lifetime)),*|)?$($T:ident),*>)?),*) => {
|
||||||
$(
|
$(
|
||||||
impl<'a, $($($T: 'a + $crate::StaticTypeSized + Sized,)*)?> $crate::StaticTypeSized for $id $(<$($($l,)*)?$($T, )*>)?{
|
impl< $($($T: $crate::StaticTypeSized ,)*)?> $crate::StaticType for $id $(<$($($l,)*)?$($T, )*>)?{
|
||||||
type Static = $id$(<$($($s,)*)?$(<$T as $crate::StaticTypeSized>::Static,)*>)?;
|
type Static = $id$(<$($($s,)*)?$(<$T as $crate::StaticTypeSized>::Static,)*>)?;
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
impl<'a, T: Clone + StaticTypeClone> StaticTypeClone for std::borrow::Cow<'a, T> {
|
impl<'a, T: StaticTypeClone + Clone> StaticType for std::borrow::Cow<'a, T> {
|
||||||
type Static = std::borrow::Cow<'static, <T as StaticTypeSized>::Static>;
|
type Static = std::borrow::Cow<'static, T::Static>;
|
||||||
}
|
}
|
||||||
impl<'a, T: StaticTypeSized> StaticTypeSized for *const [T] {
|
impl<T: StaticTypeSized> StaticType for *const [T] {
|
||||||
type Static = *const [<T as StaticTypeSized>::Static];
|
type Static = *const [<T as StaticTypeSized>::Static];
|
||||||
}
|
}
|
||||||
impl<'a, T: StaticTypeSized> StaticTypeSized for *mut [T] {
|
impl<T: StaticTypeSized> StaticType for *mut [T] {
|
||||||
type Static = *mut [<T as StaticTypeSized>::Static];
|
type Static = *mut [<T as StaticTypeSized>::Static];
|
||||||
}
|
}
|
||||||
impl<'a, T: StaticTypeSized> StaticTypeSized for &'a [T] {
|
impl<'a, T: StaticTypeSized> StaticType for &'a [T] {
|
||||||
type Static = &'static [<T as StaticTypeSized>::Static];
|
type Static = &'static [<T as StaticTypeSized>::Static];
|
||||||
}
|
}
|
||||||
impl<'a> StaticTypeSized for &'a str {
|
impl<'a> StaticType for &'a str {
|
||||||
type Static = &'static str;
|
type Static = &'static str;
|
||||||
}
|
}
|
||||||
impl<'a> StaticTypeSized for () {
|
impl StaticType for () {
|
||||||
type Static = ();
|
type Static = ();
|
||||||
}
|
}
|
||||||
impl<'a, T: 'a + StaticTypeClone> StaticTypeClone for &'a T {
|
impl<'a, T: 'a + StaticType> StaticType for &'a T {
|
||||||
type Static = &'static <T as StaticTypeClone>::Static;
|
type Static = &'static <T as StaticType>::Static;
|
||||||
}
|
}
|
||||||
impl<'a, T: StaticTypeSized, const N: usize> StaticTypeSized for [T; N] {
|
impl<T: StaticTypeSized, const N: usize> StaticType for [T; N] {
|
||||||
type Static = [<T as StaticTypeSized>::Static; N];
|
type Static = [<T as StaticTypeSized>::Static; N];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +117,7 @@ use std::{
|
||||||
|
|
||||||
impl_type!(Option<T>,Result<T, E>,Cell<T>,UnsafeCell<T>,RefCell<T>,MaybeUninit<T>,
|
impl_type!(Option<T>,Result<T, E>,Cell<T>,UnsafeCell<T>,RefCell<T>,MaybeUninit<T>,
|
||||||
Vec<T>, String, BTreeMap<K,V>,BTreeSet<V>, LinkedList<T>, VecDeque<T>,
|
Vec<T>, String, BTreeMap<K,V>,BTreeSet<V>, LinkedList<T>, VecDeque<T>,
|
||||||
BinaryHeap<T>, ManuallyDrop<T>, PhantomData<T>, PhantomPinned,Empty<T>,
|
BinaryHeap<T>, Box<T>, ManuallyDrop<T>, PhantomData<T>, PhantomPinned,Empty<T>,
|
||||||
Wrapping<T>, Duration, Once, Mutex<T>, RwLock<T>, bool, f32, f64, char,
|
Wrapping<T>, Duration, Once, Mutex<T>, RwLock<T>, bool, f32, f64, char,
|
||||||
u8, AtomicU8, u16,AtomicU16, u32,AtomicU32, u64,AtomicU64, usize,AtomicUsize,
|
u8, AtomicU8, u16,AtomicU16, u32,AtomicU32, u64,AtomicU64, usize,AtomicUsize,
|
||||||
i8,AtomicI8, i16,AtomicI16, i32,AtomicI32, i64,AtomicI64, isize,AtomicIsize,
|
i8,AtomicI8, i16,AtomicI16, i32,AtomicI32, i64,AtomicI64, isize,AtomicIsize,
|
||||||
|
@ -115,7 +130,7 @@ macro_rules! impl_tuple {
|
||||||
impl_tuple! { @rec $($t)* }
|
impl_tuple! { @rec $($t)* }
|
||||||
};
|
};
|
||||||
(@impl $($t:ident)*) => {
|
(@impl $($t:ident)*) => {
|
||||||
impl<'dyn_any, $($t: StaticTypeSized,)*> StaticTypeSized for ($($t,)*) {
|
impl< $($t: StaticTypeSized,)*> StaticType for ($($t,)*) {
|
||||||
type Static = ($(<$t as $crate::StaticTypeSized>::Static,)*);
|
type Static = ($(<$t as $crate::StaticTypeSized>::Static,)*);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,8 +7,11 @@ use std::{
|
||||||
|
|
||||||
pub trait BorrowStack<'n> {
|
pub trait BorrowStack<'n> {
|
||||||
type Item;
|
type Item;
|
||||||
|
/// # Safety
|
||||||
unsafe fn push(&'n self, value: Self::Item);
|
unsafe fn push(&'n self, value: Self::Item);
|
||||||
|
/// # Safety
|
||||||
unsafe fn pop(&'n self);
|
unsafe fn pop(&'n self);
|
||||||
|
/// # Safety
|
||||||
unsafe fn get(&'n self) -> &'n [Self::Item];
|
unsafe fn get(&'n self) -> &'n [Self::Item];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +40,10 @@ impl<'n, T: Unpin> FixedSizeStack<'n, T> {
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.len.load(Ordering::SeqCst)
|
self.len.load(Ordering::SeqCst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.len.load(Ordering::SeqCst) == 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'n, T> BorrowStack<'n> for FixedSizeStack<'n, T> {
|
impl<'n, T> BorrowStack<'n> for FixedSizeStack<'n, T> {
|
||||||
|
|
|
@ -10,7 +10,7 @@ license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
std = ["dyn-any"]
|
std = ["dyn-any"]
|
||||||
default = ["gpu", "async"]
|
default = ["async"]
|
||||||
gpu = ["spirv-std"]
|
gpu = ["spirv-std"]
|
||||||
async = ["async-trait"]
|
async = ["async-trait"]
|
||||||
nightly = []
|
nightly = []
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
|
@ -18,12 +19,35 @@ pub trait Node<T> {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
||||||
fn eval(self, input: T) -> Self::Output;
|
fn eval(self, input: T) -> Self::Output;
|
||||||
|
fn input(&self) -> &str {
|
||||||
|
core::any::type_name::<T>()
|
||||||
|
}
|
||||||
|
fn output(&self) -> &str {
|
||||||
|
core::any::type_name::<Self::Output>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Input<I> {
|
trait Input<I> {
|
||||||
unsafe fn input(&self, input: I);
|
unsafe fn input(&self, input: I);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait RefNode<T> {
|
||||||
|
type Output;
|
||||||
|
|
||||||
|
fn eval_ref(&self, input: T) -> Self::Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n, N: 'n, I> RefNode<I> for &'n N
|
||||||
|
where
|
||||||
|
&'n N: Node<I>,
|
||||||
|
Self: 'n,
|
||||||
|
{
|
||||||
|
type Output = <&'n N as Node<I>>::Output;
|
||||||
|
fn eval_ref(&self, input: I) -> Self::Output {
|
||||||
|
self.eval(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait AsyncNode<T> {
|
pub trait AsyncNode<T> {
|
||||||
|
@ -46,13 +70,23 @@ pub trait Cache {
|
||||||
fn clear(&mut self);
|
fn clear(&mut self);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "gpu"))]
|
#[cfg(feature = "async")]
|
||||||
extern crate alloc;
|
impl<N, I> Node<I> for Box<N>
|
||||||
#[cfg(not(feature = "gpu"))]
|
where
|
||||||
impl<'n, I, O: 'n> Node<'n, I> for alloc::boxed::Box<dyn Node<'n, I, Output = O>> {
|
N: Node<I>,
|
||||||
type Output = O;
|
{
|
||||||
|
type Output = <N as Node<I>>::Output;
|
||||||
fn eval(&'n self, input: &'n I) -> Self::Output {
|
fn eval(self, input: I) -> Self::Output {
|
||||||
|
(*self).eval(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(feature = "async")]
|
||||||
|
impl<'n, N, I> Node<I> for &'n Box<N>
|
||||||
|
where
|
||||||
|
&'n N: Node<I>,
|
||||||
|
{
|
||||||
|
type Output = <&'n N as Node<I>>::Output;
|
||||||
|
fn eval(self, input: I) -> Self::Output {
|
||||||
self.as_ref().eval(input)
|
self.as_ref().eval(input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,24 @@ impl<'n, L: Add<R, Output = O> + 'n, R, O: 'n> Node<(L, R)> for AddNode {
|
||||||
input.0 + input.1
|
input.0 + input.1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'n, L: Add<R, Output = O> + 'n, R, O: 'n> Node<(L, R)> for &'n AddNode {
|
||||||
|
type Output = <L as Add<R>>::Output;
|
||||||
|
fn eval(self, input: (L, R)) -> Self::Output {
|
||||||
|
input.0 + input.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'n, L: Add<R, Output = O> + 'n + Copy, R: Copy, O: 'n> Node<&'n (L, R)> for AddNode {
|
||||||
|
type Output = <L as Add<R>>::Output;
|
||||||
|
fn eval(self, input: &'n (L, R)) -> Self::Output {
|
||||||
|
input.0 + input.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'n, L: Add<R, Output = O> + 'n + Copy, R: Copy, O: 'n> Node<&'n (L, R)> for &'n AddNode {
|
||||||
|
type Output = <L as Add<R>>::Output;
|
||||||
|
fn eval(self, input: &'n (L, R)) -> Self::Output {
|
||||||
|
input.0 + input.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct CloneNode;
|
pub struct CloneNode;
|
||||||
|
@ -82,7 +100,7 @@ pub struct DupNode;
|
||||||
impl<'n, T: Clone + 'n> Node<T> for DupNode {
|
impl<'n, T: Clone + 'n> Node<T> for DupNode {
|
||||||
type Output = (T, T);
|
type Output = (T, T);
|
||||||
fn eval(self, input: T) -> Self::Output {
|
fn eval(self, input: T) -> Self::Output {
|
||||||
(input.clone(), input) //TODO: use Copy/Clone implementation
|
(input.clone(), input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +113,12 @@ impl<'n, T: 'n> Node<T> for IdNode {
|
||||||
input
|
input
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'n, T: 'n> Node<T> for &'n IdNode {
|
||||||
|
type Output = T;
|
||||||
|
fn eval(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)>);
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MutWrapper<N>(pub N);
|
/*pub struct MutWrapper<N>(pub N);
|
||||||
|
|
||||||
impl<'n, T: Clone, N> Node<&'n mut T> for &'n MutWrapper<N>
|
impl<'n, T: Clone, N> Node<&'n mut T> for &'n MutWrapper<N>
|
||||||
where
|
where
|
||||||
|
@ -44,7 +44,7 @@ where
|
||||||
fn eval(self, value: &'n mut T) {
|
fn eval(self, value: &'n mut T) {
|
||||||
*value = (&self.0).eval(value.clone());
|
*value = (&self.0).eval(value.clone());
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
@ -54,8 +54,8 @@ mod test {
|
||||||
fn map_node() {
|
fn map_node() {
|
||||||
let array = &mut [Color::from_rgbaf32(1.0, 0.0, 0.0, 1.0).unwrap()];
|
let array = &mut [Color::from_rgbaf32(1.0, 0.0, 0.0, 1.0).unwrap()];
|
||||||
(&GrayscaleNode).eval(Color::from_rgbf32_unchecked(1., 0., 0.));
|
(&GrayscaleNode).eval(Color::from_rgbf32_unchecked(1., 0., 0.));
|
||||||
let map = ForEachNode(MutWrapper(GrayscaleNode));
|
/*let map = ForEachNode(MutWrapper(GrayscaleNode));
|
||||||
(&map).eval(array.iter_mut());
|
(&map).eval(array.iter_mut());
|
||||||
assert_eq!(array[0], Color::from_rgbaf32(0.33333334, 0.33333334, 0.33333334, 1.0).unwrap());
|
assert_eq!(array[0], Color::from_rgbaf32(0.33333334, 0.33333334, 0.33333334, 1.0).unwrap());*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use crate::Node;
|
use crate::{Node, RefNode};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct ComposeNode<First, Second, Input> {
|
pub struct ComposeNode<First, Second, Input> {
|
||||||
first: First,
|
first: First,
|
||||||
second: Second,
|
second: Second,
|
||||||
|
@ -25,25 +26,40 @@ 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: Node<Input, Output = Inter> + Copy,
|
First: RefNode<Input, Output = Inter> + Copy,
|
||||||
Second: Node<Inter> + Copy,
|
Second: RefNode<Inter> + Copy,
|
||||||
{
|
{
|
||||||
type Output = Second::Output;
|
type Output = <Second as RefNode<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(input);
|
let arg: Inter = (self.first).eval_ref(input);
|
||||||
(&self.second).eval(arg)
|
(self.second).eval_ref(arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<Input, Inter, First, Second> RefNode<Input> for ComposeNode<First, Second, Input>
|
||||||
impl<'n, Input, First: 'n, Second: 'n> ComposeNode<First, Second, Input>
|
|
||||||
where
|
where
|
||||||
First: Node<Input>,
|
First: RefNode<Input, Output = Inter> + Copy,
|
||||||
Second: Node<First::Output>,
|
Second: RefNode<Inter> + Copy,
|
||||||
{
|
{
|
||||||
|
type Output = <Second as RefNode<Inter>>::Output;
|
||||||
|
|
||||||
|
fn eval_ref(&self, input: Input) -> Self::Output {
|
||||||
|
// evaluate the first node with the given input
|
||||||
|
// and then pipe the result from the first computation
|
||||||
|
// into the second node
|
||||||
|
let arg: Inter = (self.first).eval_ref(input);
|
||||||
|
(self.second).eval_ref(arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
impl<Input: 'static, First: 'static, Second: 'static> dyn_any::StaticType for ComposeNode<First, Second, Input> {
|
||||||
|
type Static = ComposeNode<First, Second, Input>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n, Input, First: 'n, Second: 'n> ComposeNode<First, Second, Input> {
|
||||||
pub const fn new(first: First, second: Second) -> Self {
|
pub const fn new(first: First, second: Second) -> Self {
|
||||||
ComposeNode::<First, Second, Input> { first, second, _phantom: PhantomData }
|
ComposeNode::<First, Second, Input> { first, second, _phantom: PhantomData }
|
||||||
}
|
}
|
||||||
|
@ -79,6 +95,24 @@ pub trait AfterRef<Inter>: Sized {
|
||||||
}
|
}
|
||||||
impl<'n, Second: 'n, I> AfterRef<I> for Second where &'n Second: Node<I> {}
|
impl<'n, Second: 'n, I> AfterRef<I> for Second where &'n Second: Node<I> {}
|
||||||
|
|
||||||
|
#[cfg(feature = "async")]
|
||||||
|
pub trait AfterBox<Inter> {
|
||||||
|
fn after<'n, First: 'n, Input>(self, first: First) -> ComposeNode<First, Self, Input>
|
||||||
|
where
|
||||||
|
First: Node<Input, Output = Inter> + Copy,
|
||||||
|
alloc::boxed::Box<Self>: Node<Inter>,
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
ComposeNode::<First, Self, Input> {
|
||||||
|
first,
|
||||||
|
second: self,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(feature = "async")]
|
||||||
|
impl<'n, Second: 'n, I> AfterBox<I> for alloc::boxed::Box<Second> where &'n alloc::boxed::Box<Second>: Node<I> {}
|
||||||
|
|
||||||
pub struct ConsNode<Root>(pub Root);
|
pub struct ConsNode<Root>(pub Root);
|
||||||
|
|
||||||
impl<Root, Input> Node<Input> for ConsNode<Root>
|
impl<Root, Input> Node<Input> for ConsNode<Root>
|
||||||
|
|
|
@ -15,7 +15,7 @@ default = ["derive", "memoization"]
|
||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
graphene-core = {path = "../gcore"}
|
graphene-core = {path = "../gcore", features = ["async", "std"]}
|
||||||
borrow_stack = {path = "../borrow_stack"}
|
borrow_stack = {path = "../borrow_stack"}
|
||||||
dyn-any = {path = "../../libraries/dyn-any", features = ["derive"]}
|
dyn-any = {path = "../../libraries/dyn-any", features = ["derive"]}
|
||||||
graph-proc-macros = {path = "../proc-macro", optional = true}
|
graph-proc-macros = {path = "../proc-macro", optional = true}
|
||||||
|
|
161
node-graph/gstd/src/any.rs
Normal file
161
node-graph/gstd/src/any.rs
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
use dyn_any::{DynAny, StaticType};
|
||||||
|
pub use graphene_core::{generic, ops /*, structural*/, Node, RefNode};
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
fn fmt_error<I>() -> String {
|
||||||
|
format!("DynAnyNode: input is not of correct type, expected {}", std::any::type_name::<I>())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DynAnyNode<'n, N: RefNode<I>, I>(pub N, pub PhantomData<&'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>;
|
||||||
|
fn eval(self, input: &'n dyn DynAny<'n>) -> Self::Output {
|
||||||
|
let output = self.0.eval_ref(dyn_any::downcast_ref(input).expect(fmt_error::<I>().as_str()));
|
||||||
|
Box::new(output)
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
/*
|
||||||
|
impl<'n, I: StaticType, N: RefNode<&'n I, Output = O> + Copy + 'n, O: 'n + StaticType> Node<&'n dyn DynAny<'n>> for &'n DynAnyNode<'n, N, I> {
|
||||||
|
type Output = Box<dyn dyn_any::DynAny<'n> + 'n>;
|
||||||
|
fn eval(self, input: &'n dyn DynAny<'n>) -> Self::Output {
|
||||||
|
let output = self.0.eval_ref(dyn_any::downcast_ref(input).unwrap_or_else(|| panic!("{}", fmt_error::<I>())));
|
||||||
|
Box::new(output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'n, I: StaticType, N: RefNode<'n, I, Output = O> + 'n, O: 'n + StaticType> Node<Box<dyn DynAny<'n>>> for DynAnyNode<'n, N, I> {
|
||||||
|
type Output = Box<dyn dyn_any::DynAny<'n> + 'n>;
|
||||||
|
fn eval(self, input: Box<dyn DynAny<'n>>) -> Self::Output {
|
||||||
|
let input: Box<I> = dyn_any::downcast(input).unwrap_or_else(|| panic!("{}", fmt_error::<I>()));
|
||||||
|
Box::new(self.0.eval_ref(*input))
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
impl<'n, I: StaticType, N: RefNode<I, Output = O> + Copy + 'n, O: 'n + StaticType> Node<Any<'n>> for &'n DynAnyNode<'n, N, I> {
|
||||||
|
type Output = Any<'n>;
|
||||||
|
fn eval(self, input: Any<'n>) -> Self::Output {
|
||||||
|
let input: Box<I> = dyn_any::downcast(input).unwrap_or_else(|| panic!("{}", fmt_error::<I>()));
|
||||||
|
Box::new(self.0.eval_ref(*input))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n, I: StaticType, N: RefNode<I, Output = O> + 'n + Copy, O: 'n + StaticType> DynAnyNode<'n, N, I>
|
||||||
|
where
|
||||||
|
N::Output: StaticType,
|
||||||
|
{
|
||||||
|
pub fn new(n: N) -> Self {
|
||||||
|
DynAnyNode(n, PhantomData)
|
||||||
|
}
|
||||||
|
pub fn into_erased(&'n self) -> impl RefNode<Any<'n>, Output = Any<'n>> {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/*pub fn as_ref(&'n self) -> &'n AnyNode<'n> {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
pub fn into_ref_box(self) -> Box<dyn RefNode<Box<(dyn DynAny<'n> + 'n)>, Output = Box<(dyn DynAny<'n> + 'n)>> + 'n> {
|
||||||
|
Box::new(self)
|
||||||
|
}*/
|
||||||
|
pub fn into_ref(self: &'n &'n Self) -> &'n (dyn RefNode<Any<'n>, Output = Any<'n>> + 'n) {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*impl<'n: 'static, I: StaticType, N, O: 'n + StaticType> DynAnyNode<'n, N, I>
|
||||||
|
where
|
||||||
|
N: RefNode<I, Output = O> + 'n + Copy,
|
||||||
|
{
|
||||||
|
/*pub fn into_owned_erased(self) -> impl RefNode<Any<'n>, Output = Any<'n>> + 'n {
|
||||||
|
self
|
||||||
|
}*/
|
||||||
|
pub fn as_owned(&'n self) -> &'n (dyn RefNode<Any<'n>, Output = Any<'n>> + 'n) {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
/*pub fn into_owned_box(&self) -> Box<dyn DynNodeOwned<'n>> {
|
||||||
|
Box::new(self)
|
||||||
|
}*/
|
||||||
|
}*/
|
||||||
|
pub type Any<'n> = Box<dyn DynAny<'n> + 'n>;
|
||||||
|
pub type AnyNode<'n> = dyn RefNode<Any<'n>, Output = Any<'n>>;
|
||||||
|
|
||||||
|
pub trait DynNodeRef<'n>: RefNode<&'n dyn DynAny<'n>, Output = Box<dyn DynAny<'n> + 'n>> + 'n {}
|
||||||
|
impl<'n, N: RefNode<&'n dyn DynAny<'n>, Output = Box<dyn DynAny<'n> + 'n>> + 'n> DynNodeRef<'n> for N {}
|
||||||
|
|
||||||
|
pub trait DynNodeOwned<'n>: RefNode<Any<'n>, Output = Any<'n>> + 'n {}
|
||||||
|
impl<'n, N: RefNode<Any<'n>, Output = Any<'n>> + 'n> DynNodeOwned<'n> for N {}
|
||||||
|
|
||||||
|
/*impl<'n> Node<Box<dyn DynAny<'n>>> for &'n Box<dyn DynNodeOwned<'n>> {
|
||||||
|
type Output = Box<dyn DynAny<'n> + 'n>;
|
||||||
|
fn eval(self, input: Box<dyn DynAny<'n>>) -> Self::Output {
|
||||||
|
(&*self as &dyn Node<Box<dyn DynAny<'n> + 'n>, Output = Box<dyn DynAny<'n> + 'n>>).eval(input)
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use graphene_core::ops::{AddNode, IdNode};
|
||||||
|
use graphene_core::value::ValueNode;
|
||||||
|
/*#[test]
|
||||||
|
pub fn dyn_input_compositon() {
|
||||||
|
use graphene_core::structural::After;
|
||||||
|
use graphene_core::structural::ComposeNode;
|
||||||
|
let id: DynAnyNode<_, u32> = DynAnyNode::new(IdNode);
|
||||||
|
let add: DynAnyNode<_, (u32, u32)> = DynAnyNode::new(AddNode);
|
||||||
|
let value: DynAnyNode<_, ()> = DynAnyNode::new(ValueNode((3u32, 4u32)));
|
||||||
|
let id = &id.as_owned();
|
||||||
|
let add = add.as_owned();
|
||||||
|
let value = value.as_owned();
|
||||||
|
|
||||||
|
/*let computation = ComposeNode::new(value, add);
|
||||||
|
let computation = id.after(add.after(value));
|
||||||
|
let result: u32 = *dyn_any::downcast(computation.eval(&())).unwrap();*/
|
||||||
|
}*/
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
pub fn dyn_input_invalid_eval_panic() {
|
||||||
|
static ADD: &DynAnyNode<&AddNode, (u32, u32)> = &DynAnyNode(&AddNode, PhantomData);
|
||||||
|
|
||||||
|
let add = ADD.into_ref();
|
||||||
|
add.eval_ref(Box::new(&("32", 32u32)));
|
||||||
|
}
|
||||||
|
/*#[test]
|
||||||
|
pub fn dyn_input_storage() {
|
||||||
|
let mut vec: Vec<Box<dyn DynNodeRef>> = vec![];
|
||||||
|
let id: DynAnyNode<_, u32> = DynAnyNode::new(IdNode);
|
||||||
|
let add: DynAnyNode<_, (u32, u32)> = DynAnyNode::new(AddNode);
|
||||||
|
let value: DynAnyNode<_, ()> = DynAnyNode::new(ValueNode((3u32, 4u32)));
|
||||||
|
|
||||||
|
vec.push(add.into_ref_box());
|
||||||
|
vec.push(id.into_ref_box());
|
||||||
|
vec.push(value.into_ref_box());
|
||||||
|
}*/
|
||||||
|
#[test]
|
||||||
|
pub fn dyn_input_storage_composition() {
|
||||||
|
let mut vec: Vec<&(dyn RefNode<Any, Output = Any>)> = vec![];
|
||||||
|
//let id: DynAnyNode<_, u32> = DynAnyNode::new(IdNode);
|
||||||
|
let value: &DynAnyNode<&ValueNode<(u32, u32)>, ()> = &DynAnyNode(&ValueNode((3u32, 4u32)), PhantomData);
|
||||||
|
let add: &DynAnyNode<&AddNode, &(u32, u32)> = &DynAnyNode(&AddNode, PhantomData);
|
||||||
|
|
||||||
|
let value_ref = (&value).into_ref();
|
||||||
|
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();
|
||||||
|
|
||||||
|
let n_value = vec[0];
|
||||||
|
let n_add = vec[1];
|
||||||
|
//let id = vec[2];
|
||||||
|
|
||||||
|
assert_eq!(*(dyn_any::downcast::<&(u32, u32)>(n_value.eval_ref(Box::new(()))).unwrap()), &(3u32, 4u32));
|
||||||
|
fn compose<'n>(
|
||||||
|
first: &'n (dyn RefNode<Box<(dyn DynAny<'n> + 'n)>, Output = Box<(dyn DynAny<'n> + 'n)>> + 'n),
|
||||||
|
second: &'n (dyn RefNode<Box<(dyn DynAny<'n> + 'n)>, Output = Box<(dyn DynAny<'n> + 'n)>> + 'n),
|
||||||
|
input: Any<'n>,
|
||||||
|
) -> Any<'n> {
|
||||||
|
second.eval_ref(first.eval_ref(input))
|
||||||
|
}
|
||||||
|
let result = compose(n_value, n_add, Box::new(()));
|
||||||
|
assert_eq!(*dyn_any::downcast::<u32>(result).unwrap(), 7u32);
|
||||||
|
//let result: u32 = *dyn_any::downcast(computation.eval(Box::new(()))).unwrap();
|
||||||
|
}
|
||||||
|
}
|
94
node-graph/gstd/src/document.rs
Normal file
94
node-graph/gstd/src/document.rs
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
|
use graphene_core::{structural::After, structural::ComposeNode, value::ValueNode, Node, RefNode};
|
||||||
|
|
||||||
|
use crate::any::Any;
|
||||||
|
use crate::any::DynAnyNode;
|
||||||
|
|
||||||
|
pub trait DocumentNode<I>: RefNode<I> {
|
||||||
|
fn input_hints(&self) -> &'static [&'static str];
|
||||||
|
fn input_types(&self) -> &'static [&'static str];
|
||||||
|
fn inputs(&self) -> Vec<String> {
|
||||||
|
self.input_hints().iter().zip(self.input_types()).map(|(a, b)| format!("{}{}", a, b)).collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct InjectNode<N: Node<I> + Copy, I>(N, PhantomData<I>);
|
||||||
|
|
||||||
|
impl<'n, N: Node<I> + Copy, I> Node<&'n [&'n AnyNode<'n>]> for &'n InjectNode<N, I> {
|
||||||
|
type Output = Box<dyn RefNode<Any<'n>, Output = Any<'n>> + 'n>;
|
||||||
|
fn eval(self, input: &'n [&'n AnyNode<'n>]) -> Self::Output {
|
||||||
|
assert_eq!(input.len(), 1);
|
||||||
|
Box::new(ComposeNode::new(&DynAnyNode(input[0]), &DynAnyNode(self.0)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Node<I> + Copy, I> InjectNode<N, I> {
|
||||||
|
const TYPES: &'static [&'static str] = &[core::any::type_name::<I>()];
|
||||||
|
const HINTS: &'static [&'static str] = &["input: "];
|
||||||
|
}
|
||||||
|
impl<'n, N: Node<I> + Copy, I> DocumentNode<&'n [&'n AnyNode<'n>]> for &'n InjectNode<N, I> {
|
||||||
|
fn input_hints(&self) -> &'static [&'static str] {
|
||||||
|
InjectNode::<N, I>::HINTS
|
||||||
|
}
|
||||||
|
fn input_types(&self) -> &'static [&'static str] {
|
||||||
|
InjectNode::<N, I>::TYPES
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type NodeId = u32;
|
||||||
|
|
||||||
|
type AnyNode<'n> = dyn RefNode<Any<'n>, Output = Any<'n>>;
|
||||||
|
|
||||||
|
pub struct DocumentGraphNode<'n> {
|
||||||
|
pub id: NodeId,
|
||||||
|
pub inputs: Vec<NodeInput>,
|
||||||
|
pub node: NodeWrapper<'n>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n> DocumentGraphNode<'n> {
|
||||||
|
pub fn new(id: NodeId, inputs: Vec<NodeInput>, node: NodeWrapper<'n>) -> Self {
|
||||||
|
Self { id, inputs, node }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NodeWrapper<'n> {
|
||||||
|
pub node: &'n (dyn Node<Any<'n>, Output = Any<'n>> + 'n),
|
||||||
|
|
||||||
|
pub path: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'n> NodeWrapper<'n> {
|
||||||
|
pub fn new(node: &'n (dyn Node<Any<'n>, Output = Any<'n>> + 'n), path: &'static str) -> Self {
|
||||||
|
Self { node, path }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum NodeInput {
|
||||||
|
Node(NodeId),
|
||||||
|
Default(ValueNode<Any<'static>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use crate::any::DynAnyNode;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use graphene_core::value::ValueNode;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn inject_node() {
|
||||||
|
let inject_node = InjectNode(&ValueNode(4u32), PhantomData);
|
||||||
|
use super::DocumentNode;
|
||||||
|
/*assert_eq!(
|
||||||
|
(&inject_node as &dyn DocumentNode<&[&AnyNode], Output = ComposeNode<&AnyNode, ValueNode<u32>, ()>>).inputs(),
|
||||||
|
vec!["input: ()"]
|
||||||
|
);*/
|
||||||
|
let any_inject = DynAnyNode(&inject_node, PhantomData);
|
||||||
|
let any_inject = Box::leak(Box::new(any_inject));
|
||||||
|
let wrapped = NodeWrapper::new((&any_inject) as &(dyn Node<&[&AnyNode], Output = Any>), "grahpene_core::document::InjectNode");
|
||||||
|
let document_node = DocumentGraphNode::new(0, vec![], wrapped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
|
@ -1,22 +1,17 @@
|
||||||
//pub mod value;
|
//pub mod value;
|
||||||
pub use graphene_core::{generic, ops /*, structural*/};
|
//#![feature(const_type_name)]
|
||||||
|
|
||||||
#[cfg(feature = "memoization")]
|
#[cfg(feature = "memoization")]
|
||||||
pub mod memo;
|
pub mod memo;
|
||||||
|
|
||||||
pub mod raster;
|
pub mod raster;
|
||||||
|
|
||||||
|
pub mod any;
|
||||||
|
|
||||||
|
pub mod document;
|
||||||
|
|
||||||
pub use graphene_core::*;
|
pub use graphene_core::*;
|
||||||
|
|
||||||
/*use dyn_any::DynAny;
|
|
||||||
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);
|
|
||||||
pub trait DynamicInput<'n> {
|
|
||||||
fn set_kwarg_by_name(&mut self, name: &str, value: DynAnyNode<'n>);
|
|
||||||
fn set_arg_by_index(&mut self, index: usize, value: DynAnyNode<'n>);
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::{Expr, ExprPath, Type};
|
use syn::{Expr, ExprPath, Type};
|
||||||
|
|
||||||
|
@ -31,6 +26,7 @@ pub struct NodeGraph {
|
||||||
pub output: Type,
|
pub output: Type,
|
||||||
pub input: Type,
|
pub input: Type,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum NodeKind {
|
pub enum NodeKind {
|
||||||
Value(Expr),
|
Value(Expr),
|
||||||
Input,
|
Input,
|
||||||
|
|
|
@ -99,6 +99,7 @@ fn main() {
|
||||||
];
|
];
|
||||||
|
|
||||||
//println!("{}", node_graph(1));
|
//println!("{}", node_graph(1));
|
||||||
|
//
|
||||||
|
|
||||||
let _nodegraph = NodeGraph {
|
let _nodegraph = NodeGraph {
|
||||||
nodes,
|
nodes,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use graphene_core::{Cache, Node};
|
use graphene_core::{Cache, Node};
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
/// Caches the output of a given Node and acts as a proxy
|
/// Caches the output of a given Node and acts as a proxy
|
||||||
pub struct CacheNode<CachedNode: Node<I>, I> {
|
pub struct CacheNode<CachedNode: Node<I>, I> {
|
||||||
|
|
|
@ -2,13 +2,7 @@ use core::marker::PhantomData;
|
||||||
use graphene_core::ops::FlatMapResultNode;
|
use graphene_core::ops::FlatMapResultNode;
|
||||||
use graphene_core::raster::color::Color;
|
use graphene_core::raster::color::Color;
|
||||||
use graphene_core::structural::{ComposeNode, ConsNode};
|
use graphene_core::structural::{ComposeNode, ConsNode};
|
||||||
use graphene_core::{
|
use graphene_core::{generic::FnNode, ops::MapResultNode, structural::After, value::ValueNode, Node};
|
||||||
generic::FnNode,
|
|
||||||
ops::MapResultNode,
|
|
||||||
structural::{After, AfterRef},
|
|
||||||
value::ValueNode,
|
|
||||||
Node,
|
|
||||||
};
|
|
||||||
use image::Pixel;
|
use image::Pixel;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
|
BIN
node-graph/gstd/test-image-1-result.png
Normal file
BIN
node-graph/gstd/test-image-1-result.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
Loading…
Add table
Add a link
Reference in a new issue