Remove Synchronicity::AnyStorage indirection
This commit is contained in:
parent
1530933464
commit
7c554f731a
@ -6,11 +6,11 @@ mod util;
|
|||||||
use petgraph::visit::{IntoEdgeReferences, NodeIndexable};
|
use petgraph::visit::{IntoEdgeReferences, NodeIndexable};
|
||||||
use petgraph::{graph::NodeIndex, stable_graph::StableDiGraph, visit::EdgeRef};
|
use petgraph::{graph::NodeIndex, stable_graph::StableDiGraph, visit::EdgeRef};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::cell::{Cell, Ref, RefCell, RefMut};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::Deref;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -18,13 +18,6 @@ use std::rc::Rc;
|
|||||||
type NodeGraph<S: Synchronicity> = StableDiGraph<ErasedNode<S>, (), u32>;
|
type NodeGraph<S: Synchronicity> = StableDiGraph<ErasedNode<S>, (), u32>;
|
||||||
|
|
||||||
pub trait Synchronicity: 'static {
|
pub trait Synchronicity: 'static {
|
||||||
type AnyStorage;
|
|
||||||
fn make_any_storage<T: Any>(value: T) -> Self::AnyStorage;
|
|
||||||
fn unbox_any_storage<T: 'static>(storage: &Self::AnyStorage) -> impl Deref<Target = T>;
|
|
||||||
fn unbox_any_storage_mut<T: 'static>(
|
|
||||||
storage: &mut Self::AnyStorage,
|
|
||||||
) -> impl DerefMut<Target = T>;
|
|
||||||
|
|
||||||
type UpdateFn;
|
type UpdateFn;
|
||||||
fn make_update_fn<V: 'static>() -> Self::UpdateFn;
|
fn make_update_fn<V: 'static>() -> Self::UpdateFn;
|
||||||
|
|
||||||
@ -35,22 +28,6 @@ pub trait Synchronicity: 'static {
|
|||||||
pub enum Synchronous {}
|
pub enum Synchronous {}
|
||||||
|
|
||||||
impl Synchronicity for Synchronous {
|
impl Synchronicity for Synchronous {
|
||||||
type AnyStorage = Box<dyn Any>;
|
|
||||||
|
|
||||||
fn make_any_storage<T: Any>(value: T) -> Self::AnyStorage {
|
|
||||||
Box::new(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unbox_any_storage<T: 'static>(storage: &Self::AnyStorage) -> impl Deref<Target = T> {
|
|
||||||
storage.downcast_ref().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unbox_any_storage_mut<T: 'static>(
|
|
||||||
storage: &mut Self::AnyStorage,
|
|
||||||
) -> impl DerefMut<Target = T> {
|
|
||||||
storage.downcast_mut().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdateFn = Box<dyn Fn(&mut Box<dyn Any>) -> ()>;
|
type UpdateFn = Box<dyn Fn(&mut Box<dyn Any>) -> ()>;
|
||||||
|
|
||||||
fn make_update_fn<V: 'static>() -> Self::UpdateFn {
|
fn make_update_fn<V: 'static>() -> Self::UpdateFn {
|
||||||
@ -68,23 +45,8 @@ impl Synchronicity for Synchronous {
|
|||||||
pub enum Asynchronous {}
|
pub enum Asynchronous {}
|
||||||
|
|
||||||
impl Synchronicity for Asynchronous {
|
impl Synchronicity for Asynchronous {
|
||||||
type AnyStorage = Rc<RefCell<Box<dyn Any>>>;
|
type UpdateFn =
|
||||||
|
Box<dyn for<'a> Fn(&'a mut Box<dyn Any>) -> Pin<Box<dyn Future<Output = ()> + 'a>>>;
|
||||||
fn make_any_storage<T: Any>(value: T) -> Self::AnyStorage {
|
|
||||||
Rc::new(RefCell::new(Box::new(value)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unbox_any_storage<T: 'static>(storage: &Self::AnyStorage) -> impl Deref<Target = T> {
|
|
||||||
Ref::map(storage.borrow(), |any| any.downcast_ref().unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unbox_any_storage_mut<T: 'static>(
|
|
||||||
storage: &mut Self::AnyStorage,
|
|
||||||
) -> impl DerefMut<Target = T> {
|
|
||||||
RefMut::map(storage.borrow_mut(), |any| any.downcast_mut().unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdateFn = Box<dyn Fn(Rc<RefCell<Box<dyn Any>>>) -> Pin<Box<dyn Future<Output = ()>>>>;
|
|
||||||
|
|
||||||
fn make_update_fn<V: 'static>() -> Self::UpdateFn {
|
fn make_update_fn<V: 'static>() -> Self::UpdateFn {
|
||||||
Box::new(|any| Box::pin(Asynchronous::do_async_update::<V>(any)))
|
Box::new(|any| Box::pin(Asynchronous::do_async_update::<V>(any)))
|
||||||
@ -98,9 +60,8 @@ impl Synchronicity for Asynchronous {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Asynchronous {
|
impl Asynchronous {
|
||||||
async fn do_async_update<V: 'static>(any: Rc<RefCell<Box<dyn Any>>>) {
|
async fn do_async_update<V: 'static>(any: &mut Box<dyn Any>) {
|
||||||
let mut any_ = any.borrow_mut();
|
let x = any.downcast_mut::<Box<dyn Node<V, Self>>>().unwrap();
|
||||||
let x = any_.downcast_mut::<Box<dyn Node<V, Self>>>().unwrap();
|
|
||||||
x.update().await;
|
x.update().await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -362,8 +323,9 @@ impl<Output: Clone + 'static> FrozenGraph<Output, Asynchronous> {
|
|||||||
Box::pin(self.update_node_async(source)).await;
|
Box::pin(self.update_node_async(source)).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = &self.node_graph.borrow()[idx];
|
let mut graph = self.node_graph.borrow_mut();
|
||||||
(node.update)(Rc::clone(&node.any)).await;
|
let node = &mut graph[idx];
|
||||||
|
(node.update)(&mut node.any).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,10 +386,10 @@ fn invalidate_nodes<S: Synchronicity>(
|
|||||||
// TODO: i really want Input to be able to implement Deref somehow
|
// TODO: i really want Input to be able to implement Deref somehow
|
||||||
|
|
||||||
pub struct ErasedNode<Synch: Synchronicity> {
|
pub struct ErasedNode<Synch: Synchronicity> {
|
||||||
any: Synch::AnyStorage,
|
any: Box<dyn Any>,
|
||||||
is_valid: Box<dyn Fn(&Synch::AnyStorage) -> bool>,
|
is_valid: Box<dyn Fn(&Box<dyn Any>) -> bool>,
|
||||||
invalidate: Box<dyn Fn(&mut Synch::AnyStorage) -> ()>,
|
invalidate: Box<dyn Fn(&mut Box<dyn Any>) -> ()>,
|
||||||
visit_inputs: Box<dyn Fn(&mut Synch::AnyStorage, &mut dyn FnMut(NodeIndex<u32>) -> ()) -> ()>,
|
visit_inputs: Box<dyn Fn(&mut Box<dyn Any>, &mut dyn FnMut(NodeIndex<u32>) -> ()) -> ()>,
|
||||||
update: Synch::UpdateFn,
|
update: Synch::UpdateFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,18 +397,19 @@ impl<S: Synchronicity> ErasedNode<S> {
|
|||||||
fn new<N: Node<V, S> + 'static, V: 'static>(base: N) -> Self {
|
fn new<N: Node<V, S> + 'static, V: 'static>(base: N) -> Self {
|
||||||
// i don't love the double boxing, but i'm not sure how else to do this
|
// i don't love the double boxing, but i'm not sure how else to do this
|
||||||
let thing: Box<dyn Node<V, S>> = Box::new(base);
|
let thing: Box<dyn Node<V, S>> = Box::new(base);
|
||||||
|
let any: Box<dyn Any> = Box::new(thing);
|
||||||
Self {
|
Self {
|
||||||
any: S::make_any_storage(thing),
|
any,
|
||||||
is_valid: Box::new(|any| {
|
is_valid: Box::new(|any| {
|
||||||
let x = S::unbox_any_storage::<Box<dyn Node<V, S>>>(any);
|
let x = any.downcast_ref::<Box<dyn Node<V, S>>>().unwrap();
|
||||||
x.is_valid()
|
x.is_valid()
|
||||||
}),
|
}),
|
||||||
invalidate: Box::new(|any| {
|
invalidate: Box::new(|any| {
|
||||||
let mut x = S::unbox_any_storage_mut::<Box<dyn Node<V, S>>>(any);
|
let x = any.downcast_mut::<Box<dyn Node<V, S>>>().unwrap();
|
||||||
x.invalidate();
|
x.invalidate();
|
||||||
}),
|
}),
|
||||||
visit_inputs: Box::new(|any, visitor| {
|
visit_inputs: Box::new(|any, visitor| {
|
||||||
let mut x = S::unbox_any_storage_mut::<Box<dyn Node<V, S>>>(any);
|
let x = any.downcast_mut::<Box<dyn Node<V, S>>>().unwrap();
|
||||||
x.visit_inputs(visitor);
|
x.visit_inputs(visitor);
|
||||||
}),
|
}),
|
||||||
update: S::make_update_fn::<V>(),
|
update: S::make_update_fn::<V>(),
|
||||||
@ -454,7 +417,9 @@ impl<S: Synchronicity> ErasedNode<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn expect_type<'a, V: 'static>(&'a self) -> impl Deref<Target = Box<dyn Node<V, S>>> + 'a {
|
fn expect_type<'a, V: 'static>(&'a self) -> impl Deref<Target = Box<dyn Node<V, S>>> + 'a {
|
||||||
S::unbox_any_storage::<Box<dyn Node<V, S>>>(&self.any)
|
self.any
|
||||||
|
.downcast_ref::<Box<dyn Node<V, S>>>()
|
||||||
|
.expect("node should match expected type")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_valid(&self) -> bool {
|
fn is_valid(&self) -> bool {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user