From 353d89cd2520424963204e8e4785e50a0f83496a Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Thu, 12 Sep 2019 09:54:12 -0700 Subject: [PATCH] more synthetic fixes: redo mouseover when model changes, avoid panic with 0-len new road line, fix reused IDs, fix contains_pt for some precomputed polygons --- ezgui/src/world.rs | 5 +---- fix_map_geom/src/main.rs | 8 ++++++-- geom/src/polygon.rs | 2 +- synthetic/src/lib.rs | 15 ++++++++++++--- synthetic/src/main.rs | 23 +++++++++++++++++------ 5 files changed, 37 insertions(+), 16 deletions(-) diff --git a/ezgui/src/world.rs b/ezgui/src/world.rs index 372a0f46e5..2f64cd0822 100644 --- a/ezgui/src/world.rs +++ b/ezgui/src/world.rs @@ -51,9 +51,6 @@ impl World { } pub fn handle_mouseover(&mut self, ctx: &EventCtx) { - if !ctx.redo_mouseover() { - return; - } self.current_selection = None; let cursor = if let Some(pt) = ctx.canvas.get_cursor_in_map_space() { @@ -111,6 +108,6 @@ impl World { pub fn delete_obj(&mut self, id: ID) { let obj = self.objects.remove(&id).unwrap(); - self.quadtree.remove(obj.quadtree_id); + self.quadtree.remove(obj.quadtree_id).unwrap(); } } diff --git a/fix_map_geom/src/main.rs b/fix_map_geom/src/main.rs index 4f0f1e3562..d1f70525b1 100644 --- a/fix_map_geom/src/main.rs +++ b/fix_map_geom/src/main.rs @@ -76,7 +76,9 @@ impl GUI for UI { ref mut osd, } => { { - self.world.handle_mouseover(ctx); + if ctx.redo_mouseover() { + self.world.handle_mouseover(ctx); + } let len = self.hints.hints.len(); let mut txt = Text::prompt("Fix Map Geometry"); @@ -284,7 +286,9 @@ impl GUI for UI { } State::BanTurnsBetween { from, ref mut osd } => { ctx.canvas.handle_event(ctx.input); - self.world.handle_mouseover(ctx); + if ctx.redo_mouseover() { + self.world.handle_mouseover(ctx); + } if ctx.input.key_pressed(Key::Escape, "cancel") { self.state = State::main(ctx); diff --git a/geom/src/polygon.rs b/geom/src/polygon.rs index 46a67adc3b..c7ccba6aa8 100644 --- a/geom/src/polygon.rs +++ b/geom/src/polygon.rs @@ -148,7 +148,7 @@ impl Polygon { top_left.offset(width, height), top_left.offset(Distance::ZERO, height), ], - indices: vec![0, 1, 2, 2, 3, 0], + indices: vec![0, 1, 2, 0, 2, 3], } } diff --git a/synthetic/src/lib.rs b/synthetic/src/lib.rs index 656dc2c21d..d94d2a0833 100644 --- a/synthetic/src/lib.rs +++ b/synthetic/src/lib.rs @@ -38,6 +38,8 @@ pub struct Model { intersections: BTreeMap, roads: BTreeMap, buildings: BTreeMap, + // Never reuse IDs, and don't worry about being sequential + id_counter: usize, world: World, } @@ -137,6 +139,7 @@ impl Model { intersections: BTreeMap::new(), roads: BTreeMap::new(), buildings: BTreeMap::new(), + id_counter: 0, world: World::new(&Bounds::new()), } } @@ -263,6 +266,7 @@ impl Model { roads: HashSet::new(), }; m.intersections.insert(*id, i); + m.id_counter = m.id_counter.max(id.0 + 1); } for (id, r) in &data.roads { @@ -279,6 +283,7 @@ impl Model { ); m.intersections.get_mut(&i1).unwrap().roads.insert(*id); m.intersections.get_mut(&i2).unwrap().roads.insert(*id); + m.id_counter = m.id_counter.max(id.0 + 1); } if !exclude_bldgs { @@ -288,6 +293,7 @@ impl Model { center: b.polygon.center(), }; m.buildings.insert(idx, b); + m.id_counter = m.id_counter.max(idx + 1); } } @@ -328,7 +334,8 @@ impl Model { } pub fn create_i(&mut self, center: Pt2D, prerender: &Prerender) { - let id = StableIntersectionID(self.intersections.len()); + let id = StableIntersectionID(self.id_counter); + self.id_counter += 1; self.intersections.insert( id, Intersection { @@ -431,7 +438,8 @@ impl Model { println!("Road already exists"); return; } - let id = StableRoadID(self.roads.len()); + let id = StableRoadID(self.id_counter); + self.id_counter += 1; self.roads.insert( id, Road { @@ -514,7 +522,8 @@ impl Model { } pub fn create_b(&mut self, center: Pt2D, prerender: &Prerender) { - let id = self.buildings.len(); + let id = self.id_counter; + self.id_counter += 1; self.buildings.insert( id, Building { diff --git a/synthetic/src/main.rs b/synthetic/src/main.rs index 3d1151fc0b..7b785c995a 100644 --- a/synthetic/src/main.rs +++ b/synthetic/src/main.rs @@ -40,7 +40,9 @@ impl UI { impl GUI for UI { fn event(&mut self, ctx: &mut EventCtx) -> EventLoopMode { ctx.canvas.handle_event(ctx.input); - self.model.handle_mouseover(ctx); + if ctx.redo_mouseover() { + self.model.handle_mouseover(ctx); + } let cursor = { if let Some(c) = ctx.canvas.get_cursor_in_map_space() { @@ -99,10 +101,12 @@ impl GUI for UI { State::CreatingRoad(i1) => { if ctx.input.key_pressed(Key::Escape, "stop defining road") { self.state = State::Viewing; + self.model.handle_mouseover(ctx); } else if let Some(ID::Intersection(i2)) = self.model.get_selection() { if i1 != i2 && ctx.input.key_pressed(Key::R, "finalize road") { self.model.create_road(i1, i2, ctx.prerender); self.state = State::Viewing; + self.model.handle_mouseover(ctx); } } } @@ -113,8 +117,10 @@ impl GUI for UI { { self.model.edit_lanes(id, s, ctx.prerender); self.state = State::Viewing; + self.model.handle_mouseover(ctx); } else if wizard.aborted() { self.state = State::Viewing; + self.model.handle_mouseover(ctx); } } State::SavingModel(ref mut wizard) => { @@ -134,6 +140,7 @@ impl GUI for UI { self.state = State::CreatingRoad(i); } else if ctx.input.key_pressed(Key::Backspace, "delete intersection") { self.model.remove_i(i); + self.model.handle_mouseover(ctx); } else if ctx.input.key_pressed(Key::T, "toggle intersection type") { self.model.toggle_i_type(i, ctx.prerender); } else if ctx.input.key_pressed(Key::L, "label intersection") { @@ -144,6 +151,7 @@ impl GUI for UI { self.state = State::MovingBuilding(b); } else if ctx.input.key_pressed(Key::Backspace, "delete building") { self.model.remove_b(b); + self.model.handle_mouseover(ctx); } else if ctx.input.key_pressed(Key::L, "label building") { self.state = State::LabelingBuilding(b, Wizard::new()); } @@ -153,6 +161,7 @@ impl GUI for UI { .key_pressed(Key::Backspace, &format!("delete road {}", r)) { self.model.remove_road(r); + self.model.handle_mouseover(ctx); } else if ctx.input.key_pressed(Key::E, "edit lanes") { self.state = State::EditingRoad(r, Wizard::new()); } else if ctx.input.key_pressed(Key::S, "swap lanes") { @@ -170,8 +179,12 @@ impl GUI for UI { } } else if ctx.input.key_pressed(Key::I, "create intersection") { self.model.create_i(cursor, ctx.prerender); + self.model.handle_mouseover(ctx); + // TODO Silly bug: Mouseover doesn't actually work! I think the cursor being + // dead-center messes up the precomputed triangles. } else if ctx.input.key_pressed(Key::B, "create building") { self.model.create_b(cursor, ctx.prerender); + self.model.handle_mouseover(ctx); } } } @@ -187,11 +200,9 @@ impl GUI for UI { match self.state { State::CreatingRoad(i1) => { if let Some(cursor) = g.get_cursor_in_map_space() { - g.draw_line( - Color::GREEN, - Distance::meters(5.0), - &Line::new(self.model.get_i_center(i1), cursor), - ); + if let Some(l) = Line::maybe_new(self.model.get_i_center(i1), cursor) { + g.draw_line(Color::GREEN, Distance::meters(5.0), &l); + } } } State::LabelingBuilding(_, ref wizard)