mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-03-05 01:24:53 +01:00
types: use const generics for more generic coordinate types
Enum support in const generics would be even nicer, but for now the integer generic is the best Rust can do.
This commit is contained in:
parent
80781c9c20
commit
e39f48d8fe
3 changed files with 39 additions and 23 deletions
|
@ -57,8 +57,8 @@ impl<'a> RegionProcessor<'a> {
|
||||||
|
|
||||||
image::GrayAlphaImage::from_fn(N, N, |x, z| {
|
image::GrayAlphaImage::from_fn(N, N, |x, z| {
|
||||||
let v: f32 = block_light[LayerBlockCoords {
|
let v: f32 = block_light[LayerBlockCoords {
|
||||||
x: BlockX(x as u8),
|
x: BlockX::new(x),
|
||||||
z: BlockZ(z as u8),
|
z: BlockZ::new(z),
|
||||||
}]
|
}]
|
||||||
.into();
|
.into();
|
||||||
image::LumaA([0, (192.0 * (1.0 - v / 15.0)) as u8])
|
image::LumaA([0, (192.0 * (1.0 - v / 15.0)) as u8])
|
||||||
|
|
|
@ -28,8 +28,8 @@ impl<'a> TileRenderer<'a> {
|
||||||
|
|
||||||
let chunk_image = image::RgbaImage::from_fn(N, N, |x, z| {
|
let chunk_image = image::RgbaImage::from_fn(N, N, |x, z| {
|
||||||
let coords = LayerBlockCoords {
|
let coords = LayerBlockCoords {
|
||||||
x: BlockX(x as u8),
|
x: BlockX::new(x),
|
||||||
z: BlockZ(z as u8),
|
z: BlockZ::new(z),
|
||||||
};
|
};
|
||||||
image::Rgba(
|
image::Rgba(
|
||||||
match (
|
match (
|
||||||
|
|
54
src/types.rs
54
src/types.rs
|
@ -7,38 +7,57 @@ use std::{
|
||||||
use itertools::iproduct;
|
use itertools::iproduct;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
macro_rules! coord_impl {
|
pub mod axis {
|
||||||
|
pub const X: u8 = 0;
|
||||||
|
pub const Y: u8 = 1;
|
||||||
|
pub const Z: u8 = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! coord_type {
|
||||||
($t:ident, $max:expr) => {
|
($t:ident, $max:expr) => {
|
||||||
impl $t {
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub struct $t<const AXIS: u8>(pub u8);
|
||||||
|
|
||||||
|
impl<const AXIS: u8> $t<AXIS> {
|
||||||
|
const MAX: usize = $max;
|
||||||
|
|
||||||
|
/// Constructs a new value
|
||||||
|
///
|
||||||
|
/// Will panic if the value is not in the valid range
|
||||||
|
pub fn new<T: TryInto<u8>>(value: T) -> Self {
|
||||||
|
Self(
|
||||||
|
value
|
||||||
|
.try_into()
|
||||||
|
.ok()
|
||||||
|
.filter(|&v| (v as usize) < Self::MAX)
|
||||||
|
.expect("coordinate should be in the valid range"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all possible values of the type
|
/// Returns an iterator over all possible values of the type
|
||||||
pub fn iter() -> impl Iterator<Item = $t>
|
pub fn iter() -> impl Iterator<Item = $t<AXIS>>
|
||||||
+ DoubleEndedIterator
|
+ DoubleEndedIterator
|
||||||
+ ExactSizeIterator
|
+ ExactSizeIterator
|
||||||
+ FusedIterator
|
+ FusedIterator
|
||||||
+ Clone
|
+ Clone
|
||||||
+ Debug {
|
+ Debug {
|
||||||
(0..$max as u8).map($t)
|
(0..Self::MAX as u8).map($t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const BLOCKS_PER_CHUNK: usize = 16;
|
pub const BLOCKS_PER_CHUNK: usize = 16;
|
||||||
|
coord_type!(BlockCoord, BLOCKS_PER_CHUNK);
|
||||||
|
|
||||||
/// A block X coordinate relative to a chunk
|
/// A block X coordinate relative to a chunk
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
pub type BlockX = BlockCoord<{ axis::X }>;
|
||||||
pub struct BlockX(pub u8);
|
|
||||||
coord_impl!(BlockX, BLOCKS_PER_CHUNK);
|
|
||||||
|
|
||||||
/// A block Y coordinate relative to a chunk section
|
/// A block Y coordinate relative to a chunk section
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
pub type BlockY = BlockCoord<{ axis::Y }>;
|
||||||
pub struct BlockY(pub u8);
|
|
||||||
coord_impl!(BlockY, BLOCKS_PER_CHUNK);
|
|
||||||
|
|
||||||
/// A block Z coordinate relative to a chunk
|
/// A block Z coordinate relative to a chunk
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
pub type BlockZ = BlockCoord<{ axis::Z }>;
|
||||||
pub struct BlockZ(pub u8);
|
|
||||||
coord_impl!(BlockZ, BLOCKS_PER_CHUNK);
|
|
||||||
|
|
||||||
/// X and Z coordinates of a block in a chunk
|
/// X and Z coordinates of a block in a chunk
|
||||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||||
|
@ -118,16 +137,13 @@ impl Debug for SectionBlockCoords {
|
||||||
pub struct SectionY(pub i32);
|
pub struct SectionY(pub i32);
|
||||||
|
|
||||||
pub const CHUNKS_PER_REGION: usize = 32;
|
pub const CHUNKS_PER_REGION: usize = 32;
|
||||||
|
coord_type!(ChunkCoord, CHUNKS_PER_REGION);
|
||||||
|
|
||||||
/// A chunk X coordinate relative to a region
|
/// A chunk X coordinate relative to a region
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
pub type ChunkX = ChunkCoord<{ axis::X }>;
|
||||||
pub struct ChunkX(pub u8);
|
|
||||||
coord_impl!(ChunkX, CHUNKS_PER_REGION);
|
|
||||||
|
|
||||||
/// A chunk Z coordinate relative to a region
|
/// A chunk Z coordinate relative to a region
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
pub type ChunkZ = ChunkCoord<{ axis::Z }>;
|
||||||
pub struct ChunkZ(pub u8);
|
|
||||||
coord_impl!(ChunkZ, CHUNKS_PER_REGION);
|
|
||||||
|
|
||||||
/// A pair of chunk coordinates relative to a region
|
/// A pair of chunk coordinates relative to a region
|
||||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||||
|
|
Loading…
Add table
Reference in a new issue