use crate::{
connect_node_update::NodeUpdate,
connect_structs::Connect,
node_traits::{AnyDynNode, ConnectNode, DynComputedNode},
utils::is_value_pointer_equal,
};
fn is_dependency_equal_modified(dependency: &ConnectNode, modified: &AnyDynNode) -> bool {
match (dependency, modified) {
(ConnectNode::Observed(dependency), AnyDynNode::Observed(modified))
| (ConnectNode::ObservedAny(dependency), AnyDynNode::Observed(modified)) => {
is_value_pointer_equal(dependency.as_ptr(), modified.as_ptr())
}
(ConnectNode::Computed(dependency), AnyDynNode::Computed(modified))
| (ConnectNode::ComputedAny(dependency), AnyDynNode::Computed(modified))
| (ConnectNode::Effected(dependency), AnyDynNode::Computed(modified))
| (ConnectNode::EffectedAny(dependency), AnyDynNode::Computed(modified)) => {
is_value_pointer_equal(dependency.as_ptr(), modified.as_ptr())
}
_ => false,
}
}
pub(crate) trait ConnectDependencies {
fn remove_computed_from_derived_lists(&self, computed: &DynComputedNode);
fn add_computed_to_derived_lists(&self, computed: &DynComputedNode);
fn recalculate_value_and_set_dependencies(
&mut self,
computed: &DynComputedNode,
modified_nodes: &mut Vec<AnyDynNode>,
);
fn is_any_dependency_changed(
&self,
computed: &DynComputedNode,
modified_nodes: &[AnyDynNode],
) -> bool;
}
impl ConnectDependencies for Connect {
fn remove_computed_from_derived_lists(&self, computed: &DynComputedNode) {
let computed_clone = computed.clone();
let computed_borrow = computed_clone.borrow();
let dependencies = computed_borrow.get_dependencies();
for dependency in dependencies {
self.remove_from_derived(computed, dependency);
}
}
fn add_computed_to_derived_lists(&self, computed: &DynComputedNode) {
let computed_clone = computed.clone();
let computed_borrow = computed_clone.borrow();
let dependencies = computed_borrow.get_dependencies();
for dependency in dependencies {
self.add_to_derived(computed, dependency);
}
}
fn recalculate_value_and_set_dependencies(
&mut self,
computed: &DynComputedNode,
modified_nodes: &mut Vec<AnyDynNode>,
) {
let (is_changed, dependencies) =
self.get_computed_value(|c| computed.borrow_mut().recalculate(c));
computed.borrow_mut().run_effect();
computed.borrow_mut().set_dependencies(dependencies);
if is_changed {
modified_nodes.push(AnyDynNode::Computed(computed.clone()));
}
}
fn is_any_dependency_changed(
&self,
computed: &DynComputedNode,
modified_nodes: &[AnyDynNode],
) -> bool {
for dependency in computed.borrow().get_dependencies() {
if modified_nodes.iter().any(|modified_node| {
is_dependency_equal_modified(dependency, modified_node)
}) {
return true;
}
}
false
}
}