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 default_registries: &RegistryHolder,
55 ) -> Arc<RwLock<Instance>> {
56 match self.instances.get(&name).and_then(|world| world.upgrade()) {
57 Some(existing_lock) => {
58 let existing = existing_lock.read();
59 if existing.chunks.height != height {
60 error!(
61 "Shared dimension height mismatch: {} != {height}",
62 existing.chunks.height
63 );
64 }
65 if existing.chunks.min_y != min_y {
66 error!(
67 "Shared world min_y mismatch: {} != {min_y}",
68 existing.chunks.min_y
69 );
70 }
71 existing_lock.clone()
72 }
73 _ => {
74 let world = Arc::new(RwLock::new(Instance {
75 chunks: ChunkStorage::new(height, min_y),
76 entities_by_chunk: HashMap::new(),
77 entity_by_id: IntMap::default(),
78 registries: default_registries.clone(),
79 }));
80 debug!("Added new instance {name}");
81 self.instances.insert(name, Arc::downgrade(&world));
82 world
83 }
84 }
85 }
86}
87
88#[derive(Component, Clone, Debug, PartialEq, Deref, DerefMut)]
92pub struct InstanceName(pub ResourceLocation);