Remove Synchronicity::AnyStorage indirection

This commit is contained in:
Shadowfacts 2024-10-31 11:00:48 -04:00
parent 1530933464
commit 7c554f731a

View File

@ -6,11 +6,11 @@ mod util;
use petgraph::visit::{IntoEdgeReferences, NodeIndexable};
use petgraph::{graph::NodeIndex, stable_graph::StableDiGraph, visit::EdgeRef};
use std::any::Any;
use std::cell::{Cell, Ref, RefCell, RefMut};
use std::cell::{Cell, RefCell};
use std::collections::HashMap;
use std::collections::VecDeque;
use std::future::Future;
use std::ops::{Deref, DerefMut};
use std::ops::Deref;
use std::pin::Pin;
use std::rc::Rc;
@ -18,13 +18,6 @@ use std::rc::Rc;
type NodeGraph<S: Synchronicity> = StableDiGraph<ErasedNode<S>, (), u32>;
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;
fn make_update_fn<V: 'static>() -> Self::UpdateFn;
@ -35,22 +28,6 @@ pub trait Synchronicity: 'static {
pub enum 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>) -> ()>;
fn make_update_fn<V: 'static>() -> Self::UpdateFn {
@ -68,23 +45,8 @@ impl Synchronicity for Synchronous {
pub enum Asynchronous {}
impl Synchronicity for Asynchronous {
type AnyStorage = Rc<RefCell<Box<dyn Any>>>;
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 = ()>>>>;
type UpdateFn =
Box<dyn for<'a> Fn(&'a mut Box<dyn Any>) -> Pin<Box<dyn Future<Output = ()> + 'a>>>;
fn make_update_fn<V: 'static>() -> Self::UpdateFn {
Box::new(|any| Box::pin(Asynchronous::do_async_update::<V>(any)))
@ -98,9 +60,8 @@ impl Synchronicity for Asynchronous {
}
impl Asynchronous {
async fn do_async_update<V: 'static>(any: Rc<RefCell<Box<dyn Any>>>) {
let mut any_ = any.borrow_mut();
let x = any_.downcast_mut::<Box<dyn Node<V, Self>>>().unwrap();
async fn do_async_update<V: 'static>(any: &mut Box<dyn Any>) {
let x = any.downcast_mut::<Box<dyn Node<V, Self>>>().unwrap();
x.update().await;
}
}
@ -362,8 +323,9 @@ impl<Output: Clone + 'static> FrozenGraph<Output, Asynchronous> {
Box::pin(self.update_node_async(source)).await;
}
let node = &self.node_graph.borrow()[idx];
(node.update)(Rc::clone(&node.any)).await;
let mut graph = self.node_graph.borrow_mut();
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
pub struct ErasedNode<Synch: Synchronicity> {
any: Synch::AnyStorage,
is_valid: Box<dyn Fn(&Synch::AnyStorage) -> bool>,
invalidate: Box<dyn Fn(&mut Synch::AnyStorage) -> ()>,
visit_inputs: Box<dyn Fn(&mut Synch::AnyStorage, &mut dyn FnMut(NodeIndex<u32>) -> ()) -> ()>,
any: Box<dyn Any>,
is_valid: Box<dyn Fn(&Box<dyn Any>) -> bool>,
invalidate: Box<dyn Fn(&mut Box<dyn Any>) -> ()>,
visit_inputs: Box<dyn Fn(&mut Box<dyn Any>, &mut dyn FnMut(NodeIndex<u32>) -> ()) -> ()>,
update: Synch::UpdateFn,
}
@ -435,18 +397,19 @@ impl<S: Synchronicity> ErasedNode<S> {
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
let thing: Box<dyn Node<V, S>> = Box::new(base);
let any: Box<dyn Any> = Box::new(thing);
Self {
any: S::make_any_storage(thing),
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()
}),
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();
}),
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);
}),
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 {
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 {