diff --git a/apps/ltn/src/logic/partition.rs b/apps/ltn/src/logic/partition.rs index 9078265aa7..4d1592d321 100644 --- a/apps/ltn/src/logic/partition.rs +++ b/apps/ltn/src/logic/partition.rs @@ -184,24 +184,15 @@ impl Partitioning { pub fn transfer_block( &mut self, map: &Map, - id: BlockID, + add_block: BlockID, new_owner: NeighbourhoodID, ) -> Result> { - let old_owner = self.block_to_neighbourhood(id); + let old_owner = self.block_to_neighbourhood(add_block); assert_ne!(old_owner, new_owner); // Is the newly expanded neighbourhood a valid perimeter? - let new_owner_blocks: Vec = self - .block_to_neighbourhood - .iter() - .filter_map(|(block, neighbourhood)| { - if *neighbourhood == new_owner || *block == id { - Some(*block) - } else { - None - } - }) - .collect(); + let mut new_owner_blocks = self.neighbourhood_to_blocks(new_owner); + new_owner_blocks.insert(add_block); let mut new_neighbourhood_blocks = self.make_merged_blocks(map, new_owner_blocks)?; if new_neighbourhood_blocks.len() != 1 { // This happens when a hole would be created by adding this block. There are probably @@ -212,22 +203,13 @@ impl Partitioning { // Is the old neighbourhood, minus this block, still valid? // TODO refactor Neighbourhood to BlockIDs? - let old_owner_blocks: Vec = self - .block_to_neighbourhood - .iter() - .filter_map(|(block, neighbourhood)| { - if *neighbourhood == old_owner && *block != id { - Some(*block) - } else { - None - } - }) - .collect(); + let mut old_owner_blocks = self.neighbourhood_to_blocks(old_owner); + old_owner_blocks.remove(&add_block); if old_owner_blocks.is_empty() { // We're deleting the old neighbourhood! self.neighbourhoods.get_mut(&new_owner).unwrap().block = new_neighbourhood_block; self.neighbourhoods.remove(&old_owner).unwrap(); - self.block_to_neighbourhood.insert(id, new_owner); + self.block_to_neighbourhood.insert(add_block, new_owner); // Tell the caller to recreate this SelectBoundary state, switching to the neighbourhood // we just donated to, since the old is now gone return Ok(Some(new_owner)); @@ -257,7 +239,7 @@ impl Partitioning { } self.neighbourhoods.get_mut(&new_owner).unwrap().block = new_neighbourhood_block; - self.block_to_neighbourhood.insert(id, new_owner); + self.block_to_neighbourhood.insert(add_block, new_owner); Ok(None) } @@ -389,11 +371,11 @@ impl Partitioning { self.block_to_neighbourhood[&id] } - pub fn all_blocks_in_neighbourhood(&self, id: NeighbourhoodID) -> Vec { - let mut result = Vec::new(); + pub fn neighbourhood_to_blocks(&self, id: NeighbourhoodID) -> BTreeSet { + let mut result = BTreeSet::new(); for (block, n) in &self.block_to_neighbourhood { if *n == id { - result.push(*block); + result.insert(*block); } } result @@ -434,7 +416,7 @@ impl Partitioning { // Possibly returns multiple merged blocks. The input is never "lost" -- if any perimeter fails // to become a block, fail the whole operation. - fn make_merged_blocks(&self, map: &Map, input: Vec) -> Result> { + fn make_merged_blocks(&self, map: &Map, input: BTreeSet) -> Result> { let mut perimeters = Vec::new(); for id in input { perimeters.push(self.get_block(id).perimeter.clone()); diff --git a/apps/ltn/src/pages/design_ltn/page.rs b/apps/ltn/src/pages/design_ltn/page.rs index 131e2d296b..4c822cde92 100644 --- a/apps/ltn/src/pages/design_ltn/page.rs +++ b/apps/ltn/src/pages/design_ltn/page.rs @@ -70,7 +70,7 @@ impl DesignLTN { highlight_cell: World::new(), edit: EditNeighbourhood::temporary(), preserve_state: crate::save::PreserveState::DesignLTN( - app.partitioning().all_blocks_in_neighbourhood(id), + app.partitioning().neighbourhood_to_blocks(id), ), show_unreachable_cell: Drawable::empty(ctx), diff --git a/apps/ltn/src/pages/per_resident_impact.rs b/apps/ltn/src/pages/per_resident_impact.rs index 3b0bcd0d6d..4cc5b9a9ad 100644 --- a/apps/ltn/src/pages/per_resident_impact.rs +++ b/apps/ltn/src/pages/per_resident_impact.rs @@ -107,7 +107,7 @@ impl PerResidentImpact { cell_outline: cell_outline.upload(ctx), buildings_inside, preserve_state: PreserveState::PerResidentImpact( - app.partitioning().all_blocks_in_neighbourhood(id), + app.partitioning().neighbourhood_to_blocks(id), current_target, ), diff --git a/apps/ltn/src/save/mod.rs b/apps/ltn/src/save/mod.rs index cd8e1375b7..f8b50841a8 100644 --- a/apps/ltn/src/save/mod.rs +++ b/apps/ltn/src/save/mod.rs @@ -1,6 +1,8 @@ mod perma; mod share; +use std::collections::BTreeSet; + use anyhow::Result; use serde::{Deserialize, Serialize}; @@ -599,8 +601,8 @@ pub enum PreserveState { Route, Crossings, // TODO app.session.edit_mode now has state for Shortcuts... - DesignLTN(Vec), - PerResidentImpact(Vec, Option), + DesignLTN(BTreeSet), + PerResidentImpact(BTreeSet, Option), CycleNetwork, }