mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-04 13:30:48 +00:00
Implement borrow stack for node graph
This commit is contained in:
parent
09deee0c4d
commit
49c171b419
10 changed files with 163 additions and 19 deletions
4
node-graph/Cargo.lock
generated
4
node-graph/Cargo.lock
generated
|
@ -257,11 +257,15 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "graphene-core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"dyn-any",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "graphene-std"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"borrow_stack",
|
||||
"dyn-any",
|
||||
"graph-proc-macros",
|
||||
"graphene-core",
|
||||
|
|
|
@ -1,13 +1,72 @@
|
|||
trait BorrowStack {
|
||||
type Item;
|
||||
unsafe fn push(&mut self, T) -> &Item;
|
||||
unsafe fn pop(&mut self) -> T;
|
||||
unsafe fn get(&self) -> &T;
|
||||
use std::{
|
||||
marker::PhantomData,
|
||||
mem::MaybeUninit,
|
||||
pin::Pin,
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
};
|
||||
|
||||
pub trait BorrowStack<'n> {
|
||||
type Item;
|
||||
unsafe fn push(&'n self, value: Self::Item);
|
||||
unsafe fn pop(&'n self);
|
||||
unsafe fn get(&'n self) -> &'n [Self::Item];
|
||||
}
|
||||
|
||||
struct BorrowStack<S> {
|
||||
data: S,
|
||||
#[derive(Debug)]
|
||||
pub struct FixedSizeStack<'n, T> {
|
||||
data: Pin<Box<[MaybeUninit<T>]>>,
|
||||
capacity: usize,
|
||||
len: AtomicUsize,
|
||||
_phantom: PhantomData<&'n ()>,
|
||||
}
|
||||
|
||||
impl<'n, T: Unpin> FixedSizeStack<'n, T> {
|
||||
pub fn new(capacity: usize) -> Self {
|
||||
let layout = std::alloc::Layout::array::<MaybeUninit<T>>(capacity).unwrap();
|
||||
let array = unsafe { std::alloc::alloc(layout) };
|
||||
let array = Pin::new(unsafe {
|
||||
Box::from_raw(
|
||||
std::slice::from_raw_parts_mut(array as *mut MaybeUninit<T>, capacity)
|
||||
as *mut [MaybeUninit<T>],
|
||||
)
|
||||
});
|
||||
|
||||
Self {
|
||||
data: array,
|
||||
capacity,
|
||||
len: AtomicUsize::new(0),
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.len.load(Ordering::SeqCst)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, T> BorrowStack<'n> for FixedSizeStack<'n, T> {
|
||||
type Item = T;
|
||||
|
||||
unsafe fn push(&'n self, value: Self::Item) {
|
||||
let len = self.len.load(Ordering::SeqCst);
|
||||
assert!(len < self.capacity);
|
||||
let ptr = self.data[len].as_ptr();
|
||||
(ptr as *mut T).write(value);
|
||||
self.len.fetch_add(1, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
unsafe fn pop(&'n self) {
|
||||
let ptr = self.data[self.len.load(Ordering::SeqCst)].as_ptr();
|
||||
Box::from_raw(ptr as *mut T);
|
||||
self.len.fetch_sub(1, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
unsafe fn get(&'n self) -> &'n [Self::Item] {
|
||||
std::slice::from_raw_parts(
|
||||
self.data.as_ptr() as *const T,
|
||||
self.len.load(Ordering::SeqCst),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -12,4 +12,4 @@ authors = ["Dennis Kobert <dennis@kobert.dev>"]
|
|||
#default = ["std"]
|
||||
|
||||
[dependencies]
|
||||
#dyn-any = {path = "../dyn-any", features = ["derive"], optional = true}
|
||||
dyn-any = {path = "../dyn-any", features = ["derive"]}
|
||||
|
|
|
@ -22,3 +22,12 @@ impl<'n, T: Node<'n, ()>> Exec<'n> for T {}
|
|||
pub trait Cache {
|
||||
fn clear(&mut self);
|
||||
}
|
||||
|
||||
extern crate alloc;
|
||||
impl<'n, I, O: 'n> Node<'n, I> for alloc::boxed::Box<dyn Node<'n, I, Output = O>> {
|
||||
type Output = O;
|
||||
|
||||
fn eval(&'n self, input: &'n I) -> Self::Output {
|
||||
self.as_ref().eval(input)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ impl<'n, const N: u32> Node<'n, ()> for IntNode<N> {
|
|||
}
|
||||
}
|
||||
|
||||
use dyn_any::{DynAny, StaticType, StaticTypeSized};
|
||||
#[derive(Default)]
|
||||
pub struct ValueNode<'n, T>(T, PhantomData<&'n ()>);
|
||||
impl<'n, T: 'n> Node<'n, ()> for ValueNode<'n, T> {
|
||||
|
@ -18,6 +19,11 @@ impl<'n, T: 'n> Node<'n, ()> for ValueNode<'n, T> {
|
|||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, T: StaticTypeSized> StaticType for ValueNode<'n, T> {
|
||||
type Static = ValueNode<'static, <T as StaticTypeSized>::Static>;
|
||||
}
|
||||
|
||||
impl<'n, T> ValueNode<'n, T> {
|
||||
pub const fn new(value: T) -> ValueNode<'n, T> {
|
||||
ValueNode(value, PhantomData)
|
||||
|
|
|
@ -17,6 +17,7 @@ default = ["derive", "memoization"]
|
|||
|
||||
[dependencies]
|
||||
graphene-core = {path = "../gcore"}
|
||||
borrow_stack = {path = "../borrow_stack"}
|
||||
dyn-any = {path = "../dyn-any", features = ["derive"]}
|
||||
graph-proc-macros = {path = "../proc-macro", optional = true}
|
||||
once_cell = {version= "1.10", optional = true}
|
||||
|
|
|
@ -9,7 +9,6 @@ pub mod memo;
|
|||
pub use graphene_core::*;
|
||||
|
||||
use dyn_any::{downcast_ref, DynAny, StaticType};
|
||||
use std::any::Any;
|
||||
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);
|
||||
|
||||
|
@ -18,11 +17,11 @@ pub trait DynamicInput<'n> {
|
|||
fn set_arg_by_index(&mut self, index: usize, value: DynAnyNode<'n>);
|
||||
}
|
||||
|
||||
pub trait AnyRef<'n, I: StaticType<'n>>: Node<'n, I> {
|
||||
pub trait AnyRef<'n, I: StaticType>: Node<'n, I> {
|
||||
fn any(&'n self, input: &'n dyn DynAny<'n>) -> Self::Output;
|
||||
}
|
||||
|
||||
impl<'n, T: Node<'n, I>, I: StaticType<'n>> AnyRef<'n, I> for T {
|
||||
impl<'n, T: Node<'n, I>, I: StaticType + 'n> AnyRef<'n, I> for T {
|
||||
fn any(&'n self, input: &'n dyn DynAny<'n>) -> Self::Output {
|
||||
self.eval(downcast_ref::<I>(input).unwrap_or_else(|| {
|
||||
panic!(
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use borrow_stack::BorrowStack;
|
||||
//#![feature(generic_associated_types)]
|
||||
use dyn_any::StaticType;
|
||||
use graphene_std::value::{AnyRefNode, ValueNode};
|
||||
use dyn_any::{DynAny, StaticType};
|
||||
use graphene_std::value::{AnyRefNode, AnyValueNode, StorageNode, ValueNode};
|
||||
use graphene_std::*;
|
||||
|
||||
/*fn mul(#[dyn_any(default)] a: f32, b: f32) -> f32 {
|
||||
|
@ -70,9 +71,39 @@ mod mul {
|
|||
}
|
||||
}
|
||||
}
|
||||
type SNode<'n> = dyn Node<'n, (), Output = &'n dyn DynAny<'n>>;
|
||||
|
||||
struct NodeStore<'n>(borrow_stack::FixedSizeStack<'n, Box<SNode<'n>>>);
|
||||
|
||||
impl<'n> NodeStore<'n> {
|
||||
fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
fn push(&'n mut self, f: fn(&'n [Box<SNode>]) -> Box<SNode<'n>>) {
|
||||
unsafe { self.0.push(f(self.0.get())) };
|
||||
}
|
||||
|
||||
/*fn get_index(&'n self, index: usize) -> &'n SNode<'n> {
|
||||
assert!(index < self.0.len());
|
||||
&unsafe { self.0.get()[index] }
|
||||
}*/
|
||||
}
|
||||
|
||||
fn main() {
|
||||
//let mut mul = mul::MulNode::new();
|
||||
let mut stack: borrow_stack::FixedSizeStack<Box<dyn Node<'_, (), Output = &dyn DynAny>>> =
|
||||
borrow_stack::FixedSizeStack::new(42);
|
||||
unsafe { stack.push(Box::new(AnyValueNode::new(1f32))) };
|
||||
//let node = unsafe { stack.get(0) };
|
||||
//let boxed = Box::new(StorageNode::new(node));
|
||||
//unsafe { stack.push(boxed) };
|
||||
let result = unsafe { &stack.get()[0] }.eval(&());
|
||||
/*unsafe {
|
||||
stack
|
||||
.push(Box::new(AnyRefNode::new(stack.get(0).as_ref()))
|
||||
as Box<dyn Node<(), Output = &dyn DynAny>>)
|
||||
};*/
|
||||
let f = (3.2f32, 3.1f32);
|
||||
let a = ValueNode::new(1.);
|
||||
let id = std::any::TypeId::of::<&f32>();
|
||||
|
|
|
@ -30,6 +30,7 @@ impl<'n, CachedNode: Node<'n, Input>, Input> Cache for CacheNode<'n, CachedNode,
|
|||
}
|
||||
}
|
||||
|
||||
use dyn_any::{DynAny, StaticType};
|
||||
/*use dyn_any::{DynAny, StaticType};
|
||||
#[derive(DynAny)]
|
||||
struct Boo<'a>(&'a u8);
|
||||
*/
|
||||
|
|
|
@ -2,21 +2,55 @@ use core::marker::PhantomData;
|
|||
pub use graphene_core::value::*;
|
||||
use graphene_core::Node;
|
||||
|
||||
use dyn_any::{DynAny, StaticType};
|
||||
pub struct AnyRefNode<'n, N: Node<'n, I, Output = &'n O>, I, O>(
|
||||
use dyn_any::{DynAny, StaticType, StaticTypeSized};
|
||||
|
||||
pub struct AnyRefNode<'n, N: Node<'n, I, Output = O>, I, O>(
|
||||
&'n N,
|
||||
PhantomData<&'n I>,
|
||||
PhantomData<&'n O>,
|
||||
);
|
||||
impl<'n, N: Node<'n, I, Output = &'n O>, I, O: DynAny<'n>> Node<'n, I> for AnyRefNode<'n, N, I, O> {
|
||||
|
||||
impl<'n, N: Node<'n, I, Output = &'n O>, I, O: DynAny<'n>> Node<'n, I>
|
||||
for AnyRefNode<'n, N, I, &'n O>
|
||||
{
|
||||
type Output = &'n (dyn DynAny<'n>);
|
||||
fn eval(&'n self, input: &'n I) -> Self::Output {
|
||||
let value: &O = self.0.eval(input);
|
||||
value
|
||||
}
|
||||
}
|
||||
impl<'n, N: Node<'n, I, Output = &'n O>, I, O: 'static> AnyRefNode<'n, N, I, O> {
|
||||
pub fn new(n: &'n N) -> AnyRefNode<'n, N, I, O> {
|
||||
impl<'n, N: Node<'n, I, Output = &'n O>, I, O: 'n + ?Sized> AnyRefNode<'n, N, I, &'n O> {
|
||||
pub fn new(n: &'n N) -> AnyRefNode<'n, N, I, &'n O> {
|
||||
AnyRefNode(n, PhantomData, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StorageNode<'n>(&'n dyn Node<'n, (), Output = &'n dyn DynAny<'n>>);
|
||||
|
||||
impl<'n> Node<'n, ()> for StorageNode<'n> {
|
||||
type Output = &'n (dyn DynAny<'n>);
|
||||
fn eval(&'n self, input: &'n ()) -> Self::Output {
|
||||
let value = self.0.eval(input);
|
||||
value
|
||||
}
|
||||
}
|
||||
impl<'n> StorageNode<'n> {
|
||||
pub fn new<N: Node<'n, (), Output = &'n dyn DynAny<'n>>>(n: &'n N) -> StorageNode<'n> {
|
||||
StorageNode(n)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct AnyValueNode<'n, T>(T, PhantomData<&'n ()>);
|
||||
impl<'n, T: 'n + DynAny<'n>> Node<'n, ()> for AnyValueNode<'n, T> {
|
||||
type Output = &'n dyn DynAny<'n>;
|
||||
fn eval(&'n self, _input: &()) -> &'n dyn DynAny<'n> {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, T> AnyValueNode<'n, T> {
|
||||
pub const fn new(value: T) -> AnyValueNode<'n, T> {
|
||||
AnyValueNode(value, PhantomData)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue