// Standard use std::collections::HashMap; // Library use vek::*; // Crate use crate::{ vol::{ BaseVol, ReadVol, WriteVol, VolSize, }, volumes::chunk::{Chunk, ChunkErr}, }; pub enum VolMapErr { NoSuchChunk, ChunkErr(ChunkErr), } // V = Voxel // S = Size (replace with a const when const generics is a thing) // M = Chunk metadata pub struct VolMap { chunks: HashMap, Chunk>, } impl VolMap { #[inline(always)] fn chunk_key(pos: Vec3) -> Vec3 { pos.map2(S::SIZE, |e, sz| e.div_euclid(sz as i32)) } #[inline(always)] fn chunk_offs(pos: Vec3) -> Vec3 { pos.map2(S::SIZE, |e, sz| e.rem_euclid(sz as i32)) } } impl BaseVol for VolMap { type Vox = V; type Err = VolMapErr; } impl ReadVol for VolMap { #[inline(always)] fn get(&self, pos: Vec3) -> Result<&V, VolMapErr> { let ck = Self::chunk_key(pos); self.chunks.get(&ck) .ok_or(VolMapErr::NoSuchChunk) .and_then(|chunk| { let co = Self::chunk_offs(pos); chunk.get(co).map_err(|err| VolMapErr::ChunkErr(err)) }) } } impl WriteVol for VolMap { #[inline(always)] fn set(&mut self, pos: Vec3, vox: V) -> Result<(), VolMapErr> { let ck = Self::chunk_key(pos); self.chunks.get_mut(&ck) .ok_or(VolMapErr::NoSuchChunk) .and_then(|chunk| { let co = Self::chunk_offs(pos); chunk.set(co, vox).map_err(|err| VolMapErr::ChunkErr(err)) }) } } impl VolMap { pub fn new() -> Self { Self { chunks: HashMap::new(), } } }