diff options
Diffstat (limited to 'server/src/data.rs')
-rw-r--r-- | server/src/data.rs | 74 |
1 files changed, 40 insertions, 34 deletions
diff --git a/server/src/data.rs b/server/src/data.rs index c5ed25ad..966fd0d2 100644 --- a/server/src/data.rs +++ b/server/src/data.rs @@ -179,23 +179,16 @@ impl Gamedata { demands_in: Vec<DemandDecl>, recipes_in: Vec<RecipeDecl>, ) -> Result<Self> { - let item_names = RwLock::new(Vec::new()); - let tile_names = RwLock::new(Vec::new()); + let reg = ItemTileRegistry::default(); let mut recipes = Vec::new(); let mut demands = Vec::new(); let mut entities = Vec::new(); for mut r in recipes_in { let r2 = r.clone(); - let mut inputs = r - .inputs - .into_iter() - .map(|i| ItemIndex(register(&item_names, i))); - let mut outputs = r - .outputs - .into_iter() - .map(|o| ItemIndex(register(&item_names, o))); - let tile = r.tile.map(|t| TileIndex(register(&tile_names, t))); + let mut inputs = r.inputs.into_iter().map(|i| reg.register_item(i)); + let mut outputs = r.outputs.into_iter().map(|o| reg.register_item(o)); + let tile = r.tile.map(|t| reg.register_tile(t)); match r.action { Action::Never => {} Action::Passive => recipes.push(Recipe::Passive { @@ -228,8 +221,8 @@ impl Gamedata { for d in demands_in { demands.push(Demand { - from: ItemIndex(register(&item_names, d.from)), - to: d.to.map(|to| ItemIndex(register(&item_names, to))), + from: reg.register_item(d.from), + to: d.to.map(|to| reg.register_item(to)), duration: d.duration, points: d.points, }) @@ -253,18 +246,25 @@ impl Gamedata { .ok_or(anyhow!("tile {tile} is undefined"))? .clone(); if let Some(ent) = map_in.tile_entities.get(&tile) { - entities.push(construct_entity(Some(pos), ent)?); + entities.push(construct_entity(Some(pos), ent, ®)?); } let itemname = map_in.items.get(&tile).cloned(); - let tile = TileIndex(register(&tile_names, tilename)); - let item = itemname.map(|i| ItemIndex(register(&item_names, i))); + let tile = reg.register_tile(tilename); + let item = itemname.map(|i| reg.register_item(i)); initial_map.insert(pos, (tile, item)); } } - let item_names = item_names.into_inner().unwrap(); - let tile_names = tile_names.into_inner().unwrap(); + entities.extend( + map_in + .entities + .iter() + .map(|decl| construct_entity(None, decl, ®)) + .try_collect::<Vec<_>>()?, + ); + let item_names = reg.items.into_inner().unwrap(); + let tile_names = reg.tiles.into_inner().unwrap(); let tile_collide = tile_names .iter() .map(|i| !map_in.walkable.contains(i)) @@ -274,14 +274,6 @@ impl Gamedata { .map(|i| !map_in.collider.contains(i) && !map_in.walkable.contains(i)) .collect(); - entities.extend( - map_in - .entities - .iter() - .map(|decl| construct_entity(None, decl)) - .try_collect::<Vec<_>>()?, - ); - Ok(Gamedata { spec, demands, @@ -299,14 +291,28 @@ impl Gamedata { } } -fn register(db: &RwLock<Vec<String>>, name: String) -> usize { - let mut db = db.write().unwrap(); - if let Some(index) = db.iter().position(|e| e == &name) { - index - } else { - let index = db.len(); - db.push(name); - index +#[derive(Default)] +pub struct ItemTileRegistry { + tiles: RwLock<Vec<String>>, + items: RwLock<Vec<String>>, +} + +impl ItemTileRegistry { + pub fn register_tile(&self, name: String) -> TileIndex { + TileIndex(Self::register(&self.tiles, name)) + } + pub fn register_item(&self, name: String) -> ItemIndex { + ItemIndex(Self::register(&self.items, name)) + } + fn register(db: &RwLock<Vec<String>>, name: String) -> usize { + let mut db = db.write().unwrap(); + if let Some(index) = db.iter().position(|e| e == &name) { + index + } else { + let index = db.len(); + db.push(name); + index + } } } |