diff options
Diffstat (limited to 'azalea-world/src/container.rs')
| -rw-r--r-- | azalea-world/src/container.rs | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/azalea-world/src/container.rs b/azalea-world/src/container.rs new file mode 100644 index 00000000..acdc9b05 --- /dev/null +++ b/azalea-world/src/container.rs @@ -0,0 +1,54 @@ +use crate::WeakWorld; +use azalea_core::ResourceLocation; +use log::error; +use std::{ + collections::HashMap, + sync::{Arc, Weak}, +}; + +/// A container of [`WeakWorld`]s. Worlds are stored as a Weak pointer here, so +/// if no clients are using a world it will be forgotten. +#[derive(Default)] +pub struct WeakWorldContainer { + pub worlds: HashMap<ResourceLocation, Weak<WeakWorld>>, +} + +impl WeakWorldContainer { + pub fn new() -> Self { + WeakWorldContainer { + worlds: HashMap::new(), + } + } + + /// Get a world from the container. + pub fn get(&self, name: &ResourceLocation) -> Option<Arc<WeakWorld>> { + self.worlds.get(name).and_then(|world| world.upgrade()) + } + + /// Add an empty world to the container (or not if it already exists) and + /// returns a strong reference to the world. + #[must_use = "the world will be immediately forgotten if unused"] + pub fn insert(&mut self, name: ResourceLocation, height: u32, min_y: i32) -> Arc<WeakWorld> { + if let Some(existing) = self.worlds.get(&name).and_then(|world| world.upgrade()) { + if existing.height() != height { + error!( + "Shared dimension height mismatch: {} != {}", + existing.height(), + height, + ); + } + if existing.min_y() != min_y { + error!( + "Shared world min_y mismatch: {} != {}", + existing.min_y(), + min_y, + ); + } + existing + } else { + let world = Arc::new(WeakWorld::new(height, min_y)); + self.worlds.insert(name, Arc::downgrade(&world)); + world + } + } +} |
