use std::{
cell::{Ref, RefCell, RefMut},
rc::{Rc, Weak},
};
use crate::connect_structs::Connect;
pub type DynNode = Rc<RefCell<dyn Node>>;
pub type DynComputedNode = Rc<RefCell<dyn ComputedNode>>;
pub(crate) type WeakDynComputedNode = Weak<RefCell<dyn ComputedNode>>;
pub(crate) enum AnyDynNode {
Observed(DynNode),
Computed(DynComputedNode),
}
impl RefNode for AnyDynNode {
fn get_derived(&self) -> Ref<Vec<WeakDynComputedNode>> {
match &self {
AnyDynNode::Observed(observed) => {
Ref::map(observed.borrow(), |observed| observed.get_derived())
}
AnyDynNode::Computed(computed) => {
Ref::map(computed.borrow(), |computed| computed.get_derived())
}
}
}
fn get_mut_derived(&self) -> RefMut<Vec<WeakDynComputedNode>> {
match self {
AnyDynNode::Observed(observed) => {
RefMut::map(observed.borrow_mut(), |observed| observed.get_mut_derived())
}
AnyDynNode::Computed(computed) => {
RefMut::map(computed.borrow_mut(), |computed| computed.get_mut_derived())
}
}
}
}
impl Clone for AnyDynNode {
fn clone(&self) -> Self {
match self {
AnyDynNode::Observed(node) => AnyDynNode::Observed(node.clone()),
AnyDynNode::Computed(node) => AnyDynNode::Computed(node.clone()),
}
}
}
pub enum ConnectNode {
Observed(DynNode),
ObservedAny(DynNode),
Computed(DynComputedNode),
ComputedAny(DynComputedNode),
Effected(DynComputedNode),
EffectedAny(DynComputedNode),
}
impl From<ConnectNode> for AnyDynNode {
fn from(connect_node: ConnectNode) -> Self {
match connect_node {
ConnectNode::Observed(node) | ConnectNode::ObservedAny(node) => {
AnyDynNode::Observed(node)
}
ConnectNode::Computed(node)
| ConnectNode::ComputedAny(node)
| ConnectNode::Effected(node)
| ConnectNode::EffectedAny(node) => AnyDynNode::Computed(node),
}
}
}
impl ConnectNode {
pub(crate) fn as_value_ptr(&self) -> *const () {
match &self {
Self::Observed(node) | Self::ObservedAny(node) => node.as_ptr() as *const (),
Self::Computed(node)
| Self::ComputedAny(node)
| Self::Effected(node)
| Self::EffectedAny(node) => node.as_ptr() as *const (),
}
}
}
impl Clone for ConnectNode {
fn clone(&self) -> Self {
match self {
ConnectNode::Observed(node) => ConnectNode::Observed(node.clone()),
ConnectNode::ObservedAny(node) => ConnectNode::ObservedAny(node.clone()),
ConnectNode::Computed(node) => ConnectNode::Computed(node.clone()),
ConnectNode::ComputedAny(node) => ConnectNode::ComputedAny(node.clone()),
ConnectNode::Effected(node) => ConnectNode::Effected(node.clone()),
ConnectNode::EffectedAny(node) => ConnectNode::EffectedAny(node.clone()),
}
}
}
pub trait ComputedNode: Node {
fn get_dependencies(&self) -> &Vec<ConnectNode>;
fn set_dependencies(&mut self, dependencies: Vec<ConnectNode>);
fn recalculate(&mut self, c: &mut Connect) -> bool;
fn run_effect(&mut self);
}
pub(crate) trait RefNode {
fn get_derived(&self) -> Ref<Vec<WeakDynComputedNode>>;
fn get_mut_derived(&self) -> RefMut<Vec<WeakDynComputedNode>>;
}
pub trait Node {
fn get_derived(&self) -> &Vec<WeakDynComputedNode>;
fn get_mut_derived(&mut self) -> &mut Vec<WeakDynComputedNode>;
}
impl RefNode for ConnectNode {
fn get_derived(&self) -> Ref<Vec<WeakDynComputedNode>> {
match &self {
ConnectNode::Observed(observed) | ConnectNode::ObservedAny(observed) => {
Ref::map(observed.borrow(), |observed| observed.get_derived())
}
ConnectNode::Computed(computed)
| ConnectNode::ComputedAny(computed)
| ConnectNode::Effected(computed)
| ConnectNode::EffectedAny(computed) => {
Ref::map(computed.borrow(), |computed| computed.get_derived())
}
}
}
fn get_mut_derived(&self) -> RefMut<Vec<WeakDynComputedNode>> {
match self {
ConnectNode::Observed(observed) | ConnectNode::ObservedAny(observed) => {
RefMut::map(observed.borrow_mut(), |observed| observed.get_mut_derived())
}
ConnectNode::Computed(computed)
| ConnectNode::ComputedAny(computed)
| ConnectNode::Effected(computed)
| ConnectNode::EffectedAny(computed) => {
RefMut::map(computed.borrow_mut(), |computed| computed.get_mut_derived())
}
}
}
}
pub trait NodeValueAccess {
type Value;
type CompFun;
fn get_inert(&self) -> Ref<Self::Value>;
fn set_inert(&self, value: Self::Value) -> Self::Value;
fn equal(&self, value: &Self::Value) -> bool;
}