use crate::{
Edge,
node::{self, Node},
visit,
};
use petgraph::visit::{
Data, EdgeRef, IntoEdgesDirected, IntoNodeReferences, NodeIndexable, NodeRef, Topo, Visitable,
};
use steel::steel_vm::engine::Engine;
pub fn visit<G>(g: G, path: &[node::Id], visitor: &mut dyn node::Visitor)
where
G: Data<EdgeWeight = Edge> + IntoEdgesDirected + IntoNodeReferences + NodeIndexable + Visitable,
G::NodeWeight: Node,
{
let mut path = path.to_vec();
let mut topo = Topo::new(g);
while let Some(n) = topo.next(g) {
let ix = g.to_index(n);
path.push(ix);
let inputs: Vec<_> = g
.edges_directed(n, petgraph::Direction::Incoming)
.map(|e_ref| (g.to_index(e_ref.source()), e_ref.weight().clone()))
.collect();
let ctx = visit::Ctx::new(&path, &inputs);
let nref = g.node_references().find(|nref| nref.id() == n).unwrap();
node::visit(ctx, nref.weight(), visitor);
path.pop();
}
}
pub fn register<G>(g: G, path: &[node::Id], vm: &mut Engine)
where
G: Data<EdgeWeight = Edge> + IntoEdgesDirected + IntoNodeReferences + NodeIndexable + Visitable,
G::NodeWeight: Node,
{
visit(g, path, &mut visit::Register(vm));
}