use std::{collections::BTreeSet, rc::Rc};
use vertigo_macro::store;
use crate::{Context, computed::GraphId};
use super::graph_id::GraphIdKind;
mod external_connections;
mod graph;
mod graph_connections;
mod graph_one_to_many;
pub mod hook;
mod refresh;
mod transaction_state;
use {graph::Graph, hook::Hooks, transaction_state::TransactionState};
pub struct Dependencies {
pub(crate) graph: Graph,
transaction_state: TransactionState,
pub(crate) hooks: Hooks,
}
#[store]
pub fn get_dependencies() -> Rc<Dependencies> {
Rc::new(Dependencies {
graph: Graph::new(),
transaction_state: TransactionState::new(),
hooks: Hooks::new(),
})
}
impl Dependencies {
pub fn transaction<R, F: FnOnce(&Context) -> R>(&self, func: F) -> R {
self.transaction_state.up();
let context = Context::transaction();
let result = func(&context);
let _ = context;
let edges_values = self.transaction_state.down();
let Some(client_ids) = edges_values else {
return result;
};
for id in client_ids {
self.graph.refresh.refresh(&id);
}
self.transaction_state.move_to_idle();
self.hooks.fire_end();
result
}
pub(crate) fn report_set(&self, value_id: GraphId) {
let mut client = BTreeSet::new();
for id in self.graph.connections.get_all_deps(value_id) {
match id.get_type() {
GraphIdKind::Value => {
unreachable!();
}
GraphIdKind::Computed => {
self.graph.refresh.clear_cache(&id);
}
GraphIdKind::Client => {
client.insert(id);
}
}
}
self.transaction_state.add_clients_to_refresh(client);
}
}