pub(crate) mod ortho;
mod report;
pub(crate) mod straight;
mod validate;
pub(crate) use report::cross;
pub use report::{Rule, Severity, Violation};
use crate::error::Error;
use crate::layout::ir::{PlacedNode, RoutedLink, Stray};
use crate::resolve::Program;
#[derive(Default)]
pub struct Routing {
pub links: Vec<RoutedLink>,
pub report: Vec<Violation>,
pub strays: Vec<Stray>,
}
pub fn route(program: &Program, nodes: &[PlacedNode]) -> Result<Routing, Error> {
let index = ortho::scene::SceneIndex::build(nodes);
let reqs = ortho::request::requests(program, &index)?;
let (mut routing, mut req_of) = ortho::route(&index, &reqs);
straight::route(&reqs, &mut routing, &mut req_of);
let mut drawn: Vec<(usize, RoutedLink)> =
req_of.drain(..).zip(routing.links.drain(..)).collect();
drawn.sort_by_key(|&(i, _)| i);
(req_of, routing.links) = drawn.into_iter().unzip();
ortho::labels::place(&mut routing.links, &req_of, &reqs, program, &index);
routing.links.extend(owned_links(nodes));
Ok(routing)
}
pub(crate) fn owned_links(nodes: &[PlacedNode]) -> Vec<RoutedLink> {
fn walk(n: &PlacedNode, ox: f64, oy: f64, out: &mut Vec<RoutedLink>) {
let (cx, cy) = (ox + n.cx, oy + n.cy);
for l in &n.links {
let mut l = l.clone();
for p in &mut l.path {
*p = (p.0 + cx, p.1 + cy);
}
for t in &mut l.texts {
t.position = (t.position.0 + cx, t.position.1 + cy);
}
out.push(l);
}
for c in &n.children {
walk(c, cx, cy, out);
}
}
let mut out = Vec::new();
for n in nodes {
walk(n, 0.0, 0.0, &mut out);
}
out
}
pub fn validate_routing(
nodes: &[PlacedNode],
links: &[RoutedLink],
report: &[Violation],
) -> Vec<Violation> {
validate::check(nodes, links, report)
}
pub fn node_rect(nodes: &[PlacedNode], path: &str) -> Option<(f64, f64, f64, f64)> {
let idx = ortho::scene::SceneIndex::build(nodes);
idx.rect(path).map(|r| (r.x0, r.y0, r.x1, r.y1))
}