Improve boundary selection. When removing a block, search the whole
perimeter for another neighborhood to donate to, before concluding we're
near the map boundary.
@@ -210,7 +210,17 @@ impl SelectBoundary {
// focusing on a different neigbhorhood
fn try_block_changed(&mut self, app: &mut App, id: BlockID) -> Result<Option<NeighborhoodID>> {
if self.selected.contains(&id) {
- // We're taking a block from another neighborhood
+ self.add_block_to_current(app, id)
+ } else {
+ self.remove_block_from_current(app, id)
+ }
+ }
+
+ fn add_block_to_current(
+ &mut self,
+ app: &mut App,
+ id: BlockID,
+ ) -> Result<Option<NeighborhoodID>> {
let old_owner = app
.session
.partitioning
@@ -235,13 +245,13 @@ impl SelectBoundary {
})
.collect();
if old_blocks.is_empty() {
+ // The old neighborhood is destroyed!
app.session
.partitioning
.neighborhoods
.get_mut(&self.id)
.unwrap()
.0 = current_neighborhood_block;
- // The old neighborhood is destroyed!
app.session
.partitioning
.neighborhoods
@@ -266,10 +276,15 @@ impl SelectBoundary {
self.block_to_neighborhood.insert(id, self.id);
Ok(None)
- } else {
- // We're getting rid of a block. Who are we giving it to?
+ }
- // Find _any_ RoadSideID in the block matching the current neighborhood perimeter
+ fn remove_block_from_current(
+ &mut self,
+ app: &mut App,
+ id: BlockID,
+ ) -> Result<Option<NeighborhoodID>> {
+ // Find all RoadSideIDs in the block matching the current neighborhood perimeter. Look for
+ // the first one that borders another neighborhood, and transfer the block there.
// TODO This can get unintuitive -- if we remove a block bordering two other
// neighborhoods, which one should we donate to?
let current_perim_set: BTreeSet<RoadSideID> = app.session.partitioning.neighborhoods
@@ -280,14 +295,11 @@ impl SelectBoundary {
.iter()
.cloned()
.collect();
- if let Some(road_side) = self.blocks[&id]
- .perimeter
- .roads
- .iter()
- .find(|x| current_perim_set.contains(x))
- {
- // Is there another neighborhood that has the other side of this road on its
- // perimeter?
+ for road_side in &self.blocks[&id].perimeter.roads {
+ if !current_perim_set.contains(road_side) {
+ continue;
+ }
+ // Is there another neighborhood that has the other side of this road on its perimeter?
// TODO We could map road -> BlockID then use block_to_neighborhood
let other_side = road_side.other_side();
if let Some((new_owner, _)) = app
@@ -357,16 +369,13 @@ impl SelectBoundary {
.0 = new_neighborhood_block;
self.block_to_neighborhood.insert(id, new_owner);
- Ok(None)
- } else {
- // We're jettisoning a block near the edge of the map (or a buggy area missing
- // blocks). Create a new neighborhood with just this block.
- bail!("TODO: Make a new neighborhood");
- }
- } else {
- bail!("This should be impossible -- a block isn't in the frontier?");
+ return Ok(None);
}
}
+
+ // We didn't find any match, so we're jettisoning a block near the edge of the map (or a
+ // buggy area missing blocks). Create a new neighborhood with just this block.
+ bail!("TODO: Make a new neighborhood");
}
}
