use hashbrown::HashMap;
use nurtex_registry::BlockKind;
use tokio::sync::RwLock;
use crate::protocol::types::{BlockPos, Chunk, ChunkPos};
use crate::world::Entity;
#[derive(Debug)]
pub struct Storage {
pub entities: RwLock<HashMap<i32, Entity>>,
pub chunks: RwLock<HashMap<ChunkPos, Chunk>>,
}
impl Storage {
pub fn null() -> Self {
Self {
entities: RwLock::new(HashMap::new()),
chunks: RwLock::new(HashMap::new()),
}
}
pub async fn add_entity(&self, id: i32, entity: Entity) {
let mut guard = self.entities.write().await;
guard.insert(id, entity);
}
pub async fn remove_entity(&self, id: &i32) {
let mut guard = self.entities.write().await;
guard.remove(id);
}
pub async fn get_entity(&self, id: &i32) -> Option<Entity> {
let guard = self.entities.read().await;
guard.get(id).cloned()
}
pub async fn entity_count(&self) -> usize {
self.entities.read().await.len()
}
pub async fn capture_entity<F>(&self, id: &i32, f: F)
where
F: AsyncFnOnce(&mut Entity),
{
let mut guard = self.entities.write().await;
if let Some(entity) = guard.get_mut(id) {
f(entity).await;
}
}
pub async fn capture_entities<F>(&self, f: F)
where
F: AsyncFnOnce(&mut HashMap<i32, Entity>),
{
let mut guard = self.entities.write().await;
f(&mut *guard).await;
}
pub async fn clear(&self) {
self.entities.write().await.clear();
self.chunks.write().await.clear();
}
pub async fn add_chunk(&self, chunk: Chunk) {
self.chunks.write().await.insert(chunk.position, chunk);
}
pub async fn get_block(&self, pos: BlockPos) -> Option<BlockKind> {
let chunk_pos = ChunkPos::from_block(pos);
let guard = self.chunks.read().await;
let chunk = guard.get(&chunk_pos)?;
if let Some(id) = chunk.get_block(pos) { BlockKind::from_id(id) } else { None }
}
pub async fn chunk_count(&self) -> usize {
self.chunks.read().await.len()
}
}