mirror of https://codeberg.org/topola/topola.git
router: Implement basic cursor following
This commit is contained in:
parent
0e8a6d6e42
commit
7a06a9b02d
105
src/band.rs
105
src/band.rs
|
|
@ -12,25 +12,52 @@ pub struct Band {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Band {
|
impl Band {
|
||||||
pub fn new(
|
pub fn from_dot_prev(
|
||||||
from: DotIndex,
|
dot: DotIndex,
|
||||||
to: DotIndex,
|
|
||||||
graph: &StableDiGraph<TaggedWeight, Label, usize>,
|
graph: &StableDiGraph<TaggedWeight, Label, usize>,
|
||||||
) -> Self {
|
) -> Option<Self> {
|
||||||
let mut this = Self {
|
let mut next_index = dot.tag();
|
||||||
from,
|
let mut interior = vec![];
|
||||||
to,
|
|
||||||
interior: vec![],
|
while let Some(index) = untag!(next_index, Primitive::new(next_index, graph).tagged_next())
|
||||||
};
|
{
|
||||||
let mut prev_index = from.tag();
|
interior.push(index);
|
||||||
|
next_index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if interior.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(Self {
|
||||||
|
from: *interior.pop().unwrap().as_dot().unwrap(),
|
||||||
|
to: dot,
|
||||||
|
interior,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_dot_next(
|
||||||
|
dot: DotIndex,
|
||||||
|
graph: &StableDiGraph<TaggedWeight, Label, usize>,
|
||||||
|
) -> Option<Self> {
|
||||||
|
let mut prev_index = dot.tag();
|
||||||
|
let mut interior = vec![];
|
||||||
|
|
||||||
while let Some(index) = untag!(prev_index, Primitive::new(prev_index, graph).tagged_next())
|
while let Some(index) = untag!(prev_index, Primitive::new(prev_index, graph).tagged_next())
|
||||||
{
|
{
|
||||||
this.interior.push(index);
|
interior.push(index);
|
||||||
prev_index = index;
|
prev_index = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
this
|
if interior.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(Self {
|
||||||
|
from: dot,
|
||||||
|
to: *interior.pop().unwrap().as_dot().unwrap(),
|
||||||
|
interior,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,57 +73,3 @@ impl Ends<DotIndex, DotIndex> for Band {
|
||||||
(self.from, self.to)
|
(self.from, self.to)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*use petgraph::stable_graph::StableDiGraph;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
graph::{DotIndex, Ends, Interior, Label, Tag, TaggedIndex, TaggedWeight},
|
|
||||||
primitive::Primitive,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct Band {
|
|
||||||
from: DotIndex,
|
|
||||||
to: DotIndex,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Band {
|
|
||||||
pub fn new(from: DotIndex, to: DotIndex) -> Self {
|
|
||||||
Self { from, to }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct BandIterator<'a> {
|
|
||||||
graph: &'a StableDiGraph<TaggedWeight, Label, usize>,
|
|
||||||
index: TaggedIndex,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Iterator for BandIterator<'a> {
|
|
||||||
type Item = TaggedIndex;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
let index = self.index;
|
|
||||||
let next_index = untag!(index, Primitive::new(index, self.graph).tagged_next());
|
|
||||||
|
|
||||||
if let Some(next_index) = next_index {
|
|
||||||
self.index = next_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
next_index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Interior<'a, TaggedIndex> for Band {
|
|
||||||
type Iter = BandIterator<'a>;
|
|
||||||
|
|
||||||
fn interior(&self, graph: &'a StableDiGraph<TaggedWeight, Label, usize>) -> Self::Iter {
|
|
||||||
BandIterator {
|
|
||||||
graph,
|
|
||||||
index: self.from.tag(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Ends<DotIndex, DotIndex> for Band {
|
|
||||||
fn ends(&self) -> (DotIndex, DotIndex) {
|
|
||||||
(self.from, self.to)
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
|
||||||
|
|
@ -207,8 +207,12 @@ impl Layout {
|
||||||
Segbend::from_dot_next(dot, &self.graph)
|
Segbend::from_dot_next(dot, &self.graph)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn band(&self, from: DotIndex, to: DotIndex) -> Band {
|
pub fn prev_band(&self, to: DotIndex) -> Option<Band> {
|
||||||
Band::new(from, to, &self.graph)
|
Band::from_dot_prev(to, &self.graph)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_band(&self, from: DotIndex) -> Option<Band> {
|
||||||
|
Band::from_dot_next(from, &self.graph)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count()))]
|
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count()))]
|
||||||
|
|
|
||||||
70
src/main.rs
70
src/main.rs
|
|
@ -24,7 +24,8 @@ mod rules;
|
||||||
mod segbend;
|
mod segbend;
|
||||||
mod shape;
|
mod shape;
|
||||||
|
|
||||||
use graph::{SegWeight, Tag, TaggedIndex};
|
use geo::point;
|
||||||
|
use graph::{DotIndex, SegWeight, Tag, TaggedIndex};
|
||||||
use layout::Layout;
|
use layout::Layout;
|
||||||
use mesh::{MeshEdgeReference, VertexIndex};
|
use mesh::{MeshEdgeReference, VertexIndex};
|
||||||
use route::Route;
|
use route::Route;
|
||||||
|
|
@ -44,6 +45,12 @@ use crate::graph::DotWeight;
|
||||||
use crate::math::Circle;
|
use crate::math::Circle;
|
||||||
use crate::router::Router;
|
use crate::router::Router;
|
||||||
|
|
||||||
|
// Clunky enum to work around borrow checker.
|
||||||
|
enum RouterOrLayout<'a> {
|
||||||
|
Router(&'a mut Router),
|
||||||
|
Layout(&'a Layout),
|
||||||
|
}
|
||||||
|
|
||||||
struct DebugRouteStrategy<'a, RS: RouteStrategy> {
|
struct DebugRouteStrategy<'a, RS: RouteStrategy> {
|
||||||
strategy: RS,
|
strategy: RS,
|
||||||
event_pump: &'a mut sdl2::EventPump,
|
event_pump: &'a mut sdl2::EventPump,
|
||||||
|
|
@ -66,7 +73,14 @@ impl<'a, RS: RouteStrategy> DebugRouteStrategy<'a, RS> {
|
||||||
|
|
||||||
impl<'a, RS: RouteStrategy> RouteStrategy for DebugRouteStrategy<'a, RS> {
|
impl<'a, RS: RouteStrategy> RouteStrategy for DebugRouteStrategy<'a, RS> {
|
||||||
fn route_cost(&mut self, route: &Route, path: &[VertexIndex]) -> u64 {
|
fn route_cost(&mut self, route: &Route, path: &[VertexIndex]) -> u64 {
|
||||||
render_times(self.event_pump, self.canvas, route.layout, None, 25);
|
render_times(
|
||||||
|
self.event_pump,
|
||||||
|
self.canvas,
|
||||||
|
RouterOrLayout::Layout(route.layout),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
25,
|
||||||
|
);
|
||||||
self.strategy.route_cost(route, path)
|
self.strategy.route_cost(route, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -258,28 +272,37 @@ fn main() {
|
||||||
let head = router.draw_around_dot(head, dot6, false, 5.0).unwrap();
|
let head = router.draw_around_dot(head, dot6, false, 5.0).unwrap();
|
||||||
let _ = router.draw_finish(head, dot7, 5.0);*/
|
let _ = router.draw_finish(head, dot7, 5.0);*/
|
||||||
|
|
||||||
let _ = router.enroute(
|
/*let _ = router.enroute(
|
||||||
dot1_1,
|
dot1_1,
|
||||||
dot1_2,
|
dot1_2,
|
||||||
DebugRouteStrategy::new(DefaultRouteStrategy::new(), &mut event_pump, &mut canvas),
|
DebugRouteStrategy::new(DefaultRouteStrategy::new(), &mut event_pump, &mut canvas),
|
||||||
);
|
);
|
||||||
|
|
||||||
render_times(&mut event_pump, &mut canvas, &router.layout, None, -1);
|
render_times(&mut event_pump, &mut canvas, &router.layout, None, -1);*/
|
||||||
render_times(
|
render_times(
|
||||||
&mut event_pump,
|
&mut event_pump,
|
||||||
&mut canvas,
|
&mut canvas,
|
||||||
&router.layout,
|
RouterOrLayout::Router(&mut router),
|
||||||
Some(barrier1_dot1.tag()),
|
Some(dot1_1),
|
||||||
|
Some(dot1_2),
|
||||||
|
-1,
|
||||||
|
);
|
||||||
|
render_times(
|
||||||
|
&mut event_pump,
|
||||||
|
&mut canvas,
|
||||||
|
RouterOrLayout::Layout(&router.layout),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
-1,
|
-1,
|
||||||
);
|
);
|
||||||
render_times(&mut event_pump, &mut canvas, &router.layout, None, -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_times(
|
fn render_times(
|
||||||
event_pump: &mut EventPump,
|
event_pump: &mut EventPump,
|
||||||
canvas: &mut Canvas<Window>,
|
canvas: &mut Canvas<Window>,
|
||||||
layout: &Layout,
|
mut router_or_layout: RouterOrLayout,
|
||||||
follower: Option<TaggedIndex>,
|
from: Option<DotIndex>,
|
||||||
|
follower: Option<DotIndex>,
|
||||||
times: i64,
|
times: i64,
|
||||||
) {
|
) {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
|
@ -299,14 +322,29 @@ fn render_times(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(follower) = follower {
|
let layout = match router_or_layout {
|
||||||
let state = event_pump.mouse_state();
|
RouterOrLayout::Router(ref mut router) => {
|
||||||
|
if let Some(follower) = follower {
|
||||||
|
let state = event_pump.mouse_state();
|
||||||
|
|
||||||
/*let _ = router.move_dot(
|
/*let _ = router.layout.move_dot(
|
||||||
*follower.as_dot().unwrap(),
|
*follower.as_dot().unwrap(),
|
||||||
(state.x() as f64, state.y() as f64).into(),
|
(state.x() as f64, state.y() as f64).into(),
|
||||||
);*/
|
);*/
|
||||||
}
|
|
||||||
|
if let Some(from) = from {
|
||||||
|
router.reroute(
|
||||||
|
from,
|
||||||
|
point! {x: state.x() as f64, y: state.y() as f64},
|
||||||
|
&mut DefaultRouteStrategy::new(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&router.layout
|
||||||
|
}
|
||||||
|
RouterOrLayout::Layout(layout) => layout,
|
||||||
|
};
|
||||||
|
|
||||||
let result = panic::catch_unwind(|| {
|
let result = panic::catch_unwind(|| {
|
||||||
for shape in layout.shapes() {
|
for shape in layout.shapes() {
|
||||||
|
|
|
||||||
|
|
@ -53,11 +53,11 @@ struct RouterAstarStrategy<'a, RS: RouteStrategy> {
|
||||||
route: Route<'a>,
|
route: Route<'a>,
|
||||||
trace: Trace,
|
trace: Trace,
|
||||||
to: VertexIndex,
|
to: VertexIndex,
|
||||||
strategy: RS,
|
strategy: &'a mut RS,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, RS: RouteStrategy> RouterAstarStrategy<'a, RS> {
|
impl<'a, RS: RouteStrategy> RouterAstarStrategy<'a, RS> {
|
||||||
pub fn new(route: Route<'a>, trace: Trace, to: VertexIndex, strategy: RS) -> Self {
|
pub fn new(route: Route<'a>, trace: Trace, to: VertexIndex, strategy: &'a mut RS) -> Self {
|
||||||
Self {
|
Self {
|
||||||
route,
|
route,
|
||||||
trace,
|
trace,
|
||||||
|
|
@ -101,7 +101,7 @@ impl Router {
|
||||||
&mut self,
|
&mut self,
|
||||||
from: DotIndex,
|
from: DotIndex,
|
||||||
to: DotIndex,
|
to: DotIndex,
|
||||||
strategy: impl RouteStrategy,
|
strategy: &mut impl RouteStrategy,
|
||||||
) -> Result<(), InsertionError> {
|
) -> Result<(), InsertionError> {
|
||||||
// XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look
|
// XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look
|
||||||
// right.
|
// right.
|
||||||
|
|
@ -121,6 +121,31 @@ impl Router {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn reroute(
|
||||||
|
&mut self,
|
||||||
|
from: DotIndex,
|
||||||
|
to: Point,
|
||||||
|
strategy: &mut impl RouteStrategy,
|
||||||
|
) -> Result<(), InsertionError> {
|
||||||
|
let to_dot = if let Some(band) = self.layout.next_band(from) {
|
||||||
|
let to_dot = band.ends().1;
|
||||||
|
|
||||||
|
self.layout.remove_interior(&band);
|
||||||
|
self.layout.move_dot(to_dot, to);
|
||||||
|
to_dot
|
||||||
|
} else {
|
||||||
|
let from_weight = self.layout.primitive(from).weight();
|
||||||
|
self.layout
|
||||||
|
.add_dot(DotWeight {
|
||||||
|
net: from_weight.net,
|
||||||
|
circle: Circle { pos: to, r: 2.0 },
|
||||||
|
})
|
||||||
|
.unwrap() // TODO.
|
||||||
|
};
|
||||||
|
|
||||||
|
self.enroute(from, to_dot, strategy)
|
||||||
|
}
|
||||||
|
|
||||||
/*pub fn squeeze_around_dot(
|
/*pub fn squeeze_around_dot(
|
||||||
&mut self,
|
&mut self,
|
||||||
head: Head,
|
head: Head,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue