azalea_world/
container.rs1use std::{
2 collections::HashMap,
3 sync::{Arc, Weak},
4};
5
6use azalea_core::{registry_holder::RegistryHolder, resource_location::ResourceLocation};
7use bevy_ecs::{component::Component, system::Resource};
8use derive_more::{Deref, DerefMut};
9use nohash_hasher::IntMap;
10use parking_lot::RwLock;
11use rustc_hash::FxHashMap;
12use tracing::{debug, error};
13
14use crate::{ChunkStorage, Instance};
15
16#[derive(Default, Resource)]
19pub struct InstanceContainer {
20 pub instances: FxHashMap<ResourceLocation, Weak<RwLock<Instance>>>,
33}
34
35impl InstanceContainer {
36 pub fn new() -> Self {
37 InstanceContainer::default()
38 }
39
40 pub fn get(&self, name: &InstanceName) -> Option<Arc<RwLock<Instance>>> {
43 self.instances.get(name).and_then(|world| world.upgrade())
44 }
45
46 #[must_use = "the world will be immediately forgotten if unused"]
49 pub fn insert(
50 &mut self,
51 name: ResourceLocation,
52 height: u32,
53 min_y: i32,
54 ) -> Arc<RwLock<Instance>> {
55 if let Some(existing_lock) = self.instances.get(&name).and_then(|world| world.upgrade()) {
56 let existing = existing_lock.read();
57 if existing.chunks.height != height {
58 error!(
59 "Shared dimension height mismatch: {} != {height}",
60 existing.chunks.height
61 );
62 }
63 if existing.chunks.min_y != min_y {
64 error!(
65 "Shared world min_y mismatch: {} != {min_y}",
66 existing.chunks.min_y
67 );
68 }
69 existing_lock.clone()
70 } else {
71 let world = Arc::new(RwLock::new(Instance {
72 chunks: ChunkStorage::new(height, min_y),
73 entities_by_chunk: HashMap::new(),
74 entity_by_id: IntMap::default(),
75 registries: RegistryHolder::default(),
76 }));
77 debug!("Added new instance {name}");
78 self.instances.insert(name, Arc::downgrade(&world));
79 world
80 }
81 }
82}
83
84#[derive(Component, Clone, Debug, PartialEq, Deref, DerefMut)]
88pub struct InstanceName(pub ResourceLocation);