use core::marker::PhantomData; use core::mem::MaybeUninit; use core::sync::atomic::AtomicBool; use crate::Node; #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub struct IntNode; impl Node<()> for IntNode { type Output = u32; fn eval(self, _: ()) -> u32 { N } } #[derive(Default, Debug)] pub struct ValueNode(pub T); impl<'n, T: 'n> Node<()> for ValueNode { type Output = T; fn eval(self, _: ()) -> Self::Output { self.0 } } impl<'n, T: 'n> Node<()> for &'n ValueNode { type Output = &'n T; fn eval(self, _: ()) -> Self::Output { &self.0 } } impl ValueNode { pub const fn new(value: T) -> ValueNode { ValueNode(value) } } impl From for ValueNode { fn from(value: T) -> Self { ValueNode::new(value) } } impl Clone for ValueNode { fn clone(&self) -> Self { Self(self.0.clone()) } } impl Copy for ValueNode {} #[derive(Default)] pub struct DefaultNode(PhantomData); impl Node<()> for DefaultNode { type Output = T; fn eval(self, _: ()) -> T { T::default() } } impl<'n, T: Default + 'n> Node<()> for &'n DefaultNode { type Output = T; fn eval(self, _: ()) -> T { T::default() } } #[repr(C)] /// Return the unit value #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub struct UnitNode; impl Node<()> for UnitNode { type Output = (); fn eval(self, _: ()) -> Self::Output {} } impl<'n> Node<()> for &'n UnitNode { type Output = (); fn eval(self, _: ()) -> Self::Output {} } pub struct InputNode(MaybeUninit, AtomicBool); impl<'n, T: 'n> Node<()> for InputNode { type Output = T; fn eval(self, _: ()) -> Self::Output { if self.1.load(core::sync::atomic::Ordering::SeqCst) { unsafe { self.0.assume_init() } } else { panic!("tried to access an input before setting it") } } } impl<'n, T: 'n> Node<()> for &'n InputNode { type Output = &'n T; fn eval(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 InputNode { pub const fn new() -> InputNode { InputNode(MaybeUninit::uninit(), AtomicBool::new(false)) } }