use crate::Node; use core::ops::{Deref, DerefMut, Index, IndexMut}; pub struct SetNode { storage: Storage, } impl<'input, T: 'input, I: 'input, A: 'input + 'input, S0: 'input> Node<'input, (T, I)> for SetNode where A: DerefMut, A::Target: IndexMut, S0: for<'any_input> Node<'input, (), Output = A>, { type Output = (); #[inline] fn eval(&'input self, input: (T, I)) -> Self::Output { let mut storage = self.storage.eval(()); let (value, index) = input; *storage.deref_mut().index_mut(index).deref_mut() = value; } } impl<'input, S0: 'input> SetNode { pub const fn new(storage: S0) -> Self { Self { storage } } } pub struct ExtractXNode {} #[node_macro::node_fn(ExtractXNode)] fn extract_x_node(input: glam::UVec3) -> usize { input.x as usize } pub struct SetOwnedNode { storage: core::cell::RefCell, } impl SetOwnedNode { pub fn new(storage: Storage) -> Self { Self { storage: core::cell::RefCell::new(storage), } } } impl<'input, I: 'input, T: 'input, Storage, A: ?Sized> Node<'input, (T, I)> for SetOwnedNode where Storage: DerefMut + 'input, A: IndexMut + 'input, { type Output = (); fn eval(&'input self, input: (T, I)) -> Self::Output { let (value, index) = input; *self.storage.borrow_mut().index_mut(index) = value; } } pub struct GetNode { storage: Storage, } impl GetNode { pub fn new(storage: Storage) -> Self { Self { storage } } } impl<'input, I: 'input, T: 'input, Storage, SNode, A: ?Sized> Node<'input, I> for GetNode where SNode: Node<'input, (), Output = Storage>, Storage: Deref + 'input, A: Index + 'input, T: Clone, { type Output = T; fn eval(&'input self, index: I) -> Self::Output { let storage = self.storage.eval(()); storage.deref().index(index).deref().clone() } } #[cfg(test)] mod test { use crate::value::{CopiedNode, OnceCellNode}; use crate::Node; use super::*; #[test] fn get_node_array() { let storage = [1, 2, 3]; let node = GetNode::new(CopiedNode::new(&storage)); assert_eq!((&node as &dyn Node<'_, usize, Output = i32>).eval(1), 2); } #[test] fn get_node_vec() { let storage = vec![1, 2, 3]; let node = GetNode::new(CopiedNode::new(&storage)); assert_eq!(node.eval(1), 2); } #[test] fn get_node_slice() { let storage: &[i32] = &[1, 2, 3]; let node = GetNode::new(CopiedNode::new(storage)); let _ = &node as &dyn Node<'_, usize, Output = i32>; assert_eq!(node.eval(1), 2); } #[test] fn set_node_slice() { let mut backing_storage = [1, 2, 3]; let storage: &mut [i32] = &mut backing_storage; let storage_node = OnceCellNode::new(storage); let node = SetNode::new(storage_node); node.eval((4, 1)); assert_eq!(backing_storage, [1, 4, 3]); } #[test] fn set_owned_node_array() { let mut storage = [1, 2, 3]; let node = SetOwnedNode::new(&mut storage); node.eval((4, 1)); assert_eq!(storage, [1, 4, 3]); } #[test] fn set_owned_node_vec() { let mut storage = vec![1, 2, 3]; let node = SetOwnedNode::new(&mut storage); node.eval((4, 1)); assert_eq!(storage, [1, 4, 3]); } #[test] fn set_owned_node_slice() { let mut backing_storage = [1, 2, 3]; let storage: &mut [i32] = &mut backing_storage; let node = SetOwnedNode::new(storage); let node = &node as &dyn Node<'_, (i32, usize), Output = ()>; node.eval((4, 1)); assert_eq!(backing_storage, [1, 4, 3]); } }