diff --git a/Cargo.lock b/Cargo.lock index 17c6122..2b755fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -558,17 +558,16 @@ version = "0.1.0" dependencies = [ "anyhow", "bincode", - "bytemuck", "clap", "enumflags2", "fastnbt", - "flate2", "futures-util", "glam", "image", "indexmap", - "itertools", "lru", + "minedmap-nbt", + "minedmap-types", "num-integer", "num_cpus", "rayon", @@ -579,6 +578,26 @@ dependencies = [ "zstd", ] +[[package]] +name = "minedmap-nbt" +version = "0.1.0" +dependencies = [ + "anyhow", + "bytemuck", + "fastnbt", + "flate2", + "minedmap-types", + "serde", +] + +[[package]] +name = "minedmap-types" +version = "0.1.0" +dependencies = [ + "itertools", + "serde", +] + [[package]] name = "miniz_oxide" version = "0.7.1" diff --git a/Cargo.toml b/Cargo.toml index bbbc171..7c9ab32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,6 @@ +[workspace] +members = ["crates/*"] + [package] name = "minedmap" version = "0.1.0" @@ -5,23 +8,19 @@ edition = "2021" license = "MIT" default-run = "minedmap" -[lib] -name = "minedmap_core" - [dependencies] anyhow = "1.0.68" bincode = "1.3.3" -bytemuck = "1.13.0" clap = { version = "4.1.4", features = ["derive"] } enumflags2 = { version = "0.7.5", features = ["serde"] } fastnbt = "2.3.2" -flate2 = "1.0.25" futures-util = "0.3.28" glam = "0.24.0" image = { version = "0.24.5", default-features = false, features = ["png"] } indexmap = { version = "2.0.0", features = ["serde"] } -itertools = "0.11.0" lru = "0.11.0" +minedmap-nbt = { version = "0.1.0", path = "crates/nbt", default-features = false } +minedmap-types = { version = "0.1.0", path = "crates/types" } num-integer = "0.1.45" num_cpus = "1.16.0" rayon = "1.7.0" @@ -33,4 +32,4 @@ zstd = "0.12.3" [features] default = ["zlib-ng"] -zlib-ng = ["flate2/zlib-ng"] +zlib-ng = ["minedmap-nbt/zlib-ng"] diff --git a/crates/nbt/Cargo.toml b/crates/nbt/Cargo.toml new file mode 100644 index 0000000..ff1d7d2 --- /dev/null +++ b/crates/nbt/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "minedmap-nbt" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.75" +bytemuck = "1.13.1" +fastnbt = "2.4.4" +flate2 = "1.0.27" +minedmap-types = { version = "0.1.0", path = "../types" } +serde = "1.0.183" + +[features] +zlib-ng = ["flate2/zlib-ng"] diff --git a/src/io/data.rs b/crates/nbt/src/data.rs similarity index 100% rename from src/io/data.rs rename to crates/nbt/src/data.rs diff --git a/crates/nbt/src/lib.rs b/crates/nbt/src/lib.rs new file mode 100644 index 0000000..0b817b1 --- /dev/null +++ b/crates/nbt/src/lib.rs @@ -0,0 +1,7 @@ +//! MinedMap's of Minecraft NBT data and region files + +#![warn(missing_docs)] +#![warn(clippy::missing_docs_in_private_items)] + +pub mod data; +pub mod region; diff --git a/src/io/region.rs b/crates/nbt/src/region.rs similarity index 99% rename from src/io/region.rs rename to crates/nbt/src/region.rs index 82f5604..8a52b9d 100644 --- a/src/io/region.rs +++ b/crates/nbt/src/region.rs @@ -10,7 +10,7 @@ use anyhow::{bail, Context, Result}; use flate2::read::ZlibDecoder; use serde::de::DeserializeOwned; -use crate::types::*; +use minedmap_types::*; /// Data block size of region data files /// diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml new file mode 100644 index 0000000..fae230b --- /dev/null +++ b/crates/types/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "minedmap-types" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +itertools = "0.11.0" +serde = "1.0.183" diff --git a/src/types.rs b/crates/types/src/lib.rs similarity index 96% rename from src/types.rs rename to crates/types/src/lib.rs index 045750b..2e4ea61 100644 --- a/src/types.rs +++ b/crates/types/src/lib.rs @@ -1,5 +1,8 @@ //! Common types used by MinedMap +#![warn(missing_docs)] +#![warn(clippy::missing_docs_in_private_items)] + use std::{ fmt::Debug, iter::FusedIterator, @@ -32,6 +35,7 @@ macro_rules! coord_type { /// Constructs a new value /// /// Will panic if the value is not in the valid range + #[inline] pub fn new>(value: T) -> Self { Self( value @@ -43,6 +47,7 @@ macro_rules! coord_type { } /// Returns an iterator over all possible values of the type + #[inline] pub fn iter() -> impl Iterator> + DoubleEndedIterator + ExactSizeIterator @@ -95,6 +100,7 @@ impl LayerBlockCoords { /// Many chunk data structures store block and biome data in the same /// order. This method computes the offset at which the data for the /// block at a given coordinate is stored. + #[inline] pub fn offset(&self) -> usize { use BLOCKS_PER_CHUNK as N; let x = self.x.0 as usize; @@ -112,12 +118,14 @@ pub struct LayerBlockArray(pub [[T; BLOCKS_PER_CHUNK]; BLOCKS_PER_CHUNK]); impl Index for LayerBlockArray { type Output = T; + #[inline] fn index(&self, index: LayerBlockCoords) -> &Self::Output { &self.0[index.z.0 as usize][index.x.0 as usize] } } impl IndexMut for LayerBlockArray { + #[inline] fn index_mut(&mut self, index: LayerBlockCoords) -> &mut Self::Output { &mut self.0[index.z.0 as usize][index.x.0 as usize] } @@ -138,6 +146,7 @@ impl SectionBlockCoords { /// Many chunk data structures store block and biome data in the same /// order. This method computes the offset at which the data for the /// block at a given coordinate is stored. + #[inline] pub fn offset(&self) -> usize { use BLOCKS_PER_CHUNK as N; let y = self.y.0 as usize; @@ -194,16 +203,19 @@ pub struct ChunkArray(pub [[T; CHUNKS_PER_REGION]; CHUNKS_PER_REGION]); impl ChunkArray { /// Iterates over all possible chunk coordinate pairs used as [ChunkArray] keys + #[inline] pub fn keys() -> impl Iterator + Clone + Debug { iproduct!(ChunkZ::iter(), ChunkX::iter()).map(|(z, x)| ChunkCoords { x, z }) } /// Iterates over all values stored in the [ChunkArray] + #[inline] pub fn values(&self) -> impl Iterator + Clone + Debug { Self::keys().map(|k| &self[k]) } /// Iterates over pairs of chunk coordinate pairs and corresponding stored values + #[inline] pub fn iter(&self) -> impl Iterator + Clone + Debug { Self::keys().map(|k| (k, &self[k])) } @@ -212,12 +224,14 @@ impl ChunkArray { impl Index for ChunkArray { type Output = T; + #[inline] fn index(&self, index: ChunkCoords) -> &Self::Output { &self.0[index.z.0 as usize][index.x.0 as usize] } } impl IndexMut for ChunkArray { + #[inline] fn index_mut(&mut self, index: ChunkCoords) -> &mut Self::Output { &mut self.0[index.z.0 as usize][index.x.0 as usize] } diff --git a/src/bin/nbtdump.rs b/src/bin/nbtdump.rs index da5e502..a83a199 100644 --- a/src/bin/nbtdump.rs +++ b/src/bin/nbtdump.rs @@ -18,7 +18,7 @@ struct Args { fn main() -> Result<()> { let args = Args::parse(); - let value: fastnbt::Value = minedmap_core::io::data::from_file(args.file.as_path())?; + let value: fastnbt::Value = minedmap_nbt::data::from_file(args.file.as_path())?; println!("{:#x?}", value); Ok(()) diff --git a/src/bin/regiondump.rs b/src/bin/regiondump.rs index 21351f7..c8e87b4 100644 --- a/src/bin/regiondump.rs +++ b/src/bin/regiondump.rs @@ -18,7 +18,7 @@ struct Args { fn main() -> Result<()> { let args = Args::parse(); - minedmap_core::io::region::from_file(args.file.as_path())?.foreach_chunk( + minedmap_nbt::region::from_file(args.file.as_path())?.foreach_chunk( |coords, value: fastnbt::Value| { println!("Chunk {:?}: {:#x?}", coords, value); Ok(()) diff --git a/src/bin/minedmap/common.rs b/src/core/common.rs similarity index 98% rename from src/bin/minedmap/common.rs rename to src/core/common.rs index 4183b64..a6d9a44 100644 --- a/src/bin/minedmap/common.rs +++ b/src/core/common.rs @@ -9,7 +9,7 @@ use std::{ use indexmap::IndexSet; use serde::{Deserialize, Serialize}; -use super::core::{io::fs::FileMetaVersion, resource::Biome, types::*, world::layer}; +use crate::{io::fs::FileMetaVersion, resource::Biome, types::*, world::layer}; /// MinedMap data version number /// diff --git a/src/bin/minedmap/metadata_writer.rs b/src/core/metadata_writer.rs similarity index 94% rename from src/bin/minedmap/metadata_writer.rs rename to src/core/metadata_writer.rs index 2ba6038..5783356 100644 --- a/src/bin/minedmap/metadata_writer.rs +++ b/src/core/metadata_writer.rs @@ -3,10 +3,7 @@ use anyhow::{Context, Result}; use serde::Serialize; -use super::{ - common::*, - core::{self, io::fs, world::de}, -}; +use crate::{core::common::*, io::fs, world::de}; /// Minimum and maximum X and Z tile coordinates for a mipmap level #[derive(Debug, Serialize)] @@ -101,7 +98,7 @@ impl<'a> MetadataWriter<'a> { /// Reads and deserializes the `level.dat` of the Minecraft save data fn read_level_dat(&self) -> Result { - core::io::data::from_file(&self.config.level_dat_path).context("Failed to read level.dat") + crate::nbt::data::from_file(&self.config.level_dat_path).context("Failed to read level.dat") } /// Generates [Spawn] data from a [de::LevelDat] diff --git a/src/bin/minedmap/main.rs b/src/core/mod.rs similarity index 87% rename from src/bin/minedmap/main.rs rename to src/core/mod.rs index 925a38b..a94cf2c 100644 --- a/src/bin/minedmap/main.rs +++ b/src/core/mod.rs @@ -1,7 +1,4 @@ -//! The minedmap generator renders map tile images from Minecraft save data - -#![warn(missing_docs)] -#![warn(clippy::missing_docs_in_private_items)] +//! Core functions of the MinedMap CLI mod common; mod metadata_writer; @@ -10,8 +7,6 @@ mod region_processor; mod tile_mipmapper; mod tile_renderer; -use minedmap_core as core; - use std::path::PathBuf; use anyhow::{Context, Result}; @@ -46,7 +41,8 @@ fn setup_threads(num_threads: usize) -> Result<()> { .context("Failed to configure thread pool") } -fn main() -> Result<()> { +/// MinedMap CLI main function +pub fn cli() -> Result<()> { let args = Args::parse(); let config = Config::new(&args); diff --git a/src/bin/minedmap/region_group.rs b/src/core/region_group.rs similarity index 100% rename from src/bin/minedmap/region_group.rs rename to src/core/region_group.rs diff --git a/src/bin/minedmap/region_processor.rs b/src/core/region_processor.rs similarity index 96% rename from src/bin/minedmap/region_processor.rs rename to src/core/region_processor.rs index 7168ebd..6e32d94 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/core/region_processor.rs @@ -6,17 +6,14 @@ use anyhow::{Context, Result}; use indexmap::IndexSet; use rayon::prelude::*; -use super::{ - common::*, - core::{ +use super::common::*; +use crate::{ + io::{fs, storage}, + resource::{self, Biome}, + types::*, + world::{ self, - io::{fs, storage}, - resource::{self, Biome}, - types::*, - world::{ - self, - layer::{self, LayerData}, - }, + layer::{self, LayerData}, }, }; @@ -157,7 +154,7 @@ impl<'a> RegionProcessor<'a> { println!("Processing region r.{}.{}.mca", coords.x, coords.z); - core::io::region::from_file(path)?.foreach_chunk( + crate::nbt::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { let Some(layer::LayerData { blocks, diff --git a/src/bin/minedmap/tile_mipmapper.rs b/src/core/tile_mipmapper.rs similarity index 98% rename from src/bin/minedmap/tile_mipmapper.rs rename to src/core/tile_mipmapper.rs index 59c2880..52fff09 100644 --- a/src/bin/minedmap/tile_mipmapper.rs +++ b/src/core/tile_mipmapper.rs @@ -3,10 +3,8 @@ use anyhow::{Context, Result}; use rayon::prelude::*; -use super::{ - common::*, - core::{io::fs, types::*}, -}; +use super::common::*; +use crate::{io::fs, types::*}; /// Generates mipmap tiles from full-resolution tile images pub struct TileMipmapper<'a> { diff --git a/src/bin/minedmap/tile_renderer.rs b/src/core/tile_renderer.rs similarity index 98% rename from src/bin/minedmap/tile_renderer.rs rename to src/core/tile_renderer.rs index d5b7644..c26c559 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/core/tile_renderer.rs @@ -13,15 +13,12 @@ use lru::LruCache; use rayon::prelude::*; use tokio::sync::OnceCell; -use super::{ - common::*, - core::{ - io::{fs, storage}, - resource::{block_color, needs_biome}, - types::*, - util::coord_offset, - }, - region_group::RegionGroup, +use super::{common::*, region_group::RegionGroup}; +use crate::{ + io::{fs, storage}, + resource::{block_color, needs_biome}, + types::*, + util::coord_offset, }; /// Type for referencing loaded [ProcessedRegion] data diff --git a/src/io/mod.rs b/src/io/mod.rs index 590ca2a..bfe2a2c 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -1,6 +1,4 @@ //! Input/output functions -pub mod data; pub mod fs; -pub mod region; pub mod storage; diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index 14d97f9..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! Common library for MinedMap generator and dump utilities - -#![warn(missing_docs)] -#![warn(clippy::missing_docs_in_private_items)] - -pub mod io; -pub mod resource; -pub mod types; -pub mod util; -pub mod world; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..9bbe0ab --- /dev/null +++ b/src/main.rs @@ -0,0 +1,19 @@ +//! The minedmap generator renders map tile images from Minecraft save data + +#![warn(missing_docs)] +#![warn(clippy::missing_docs_in_private_items)] + +mod core; +mod io; +mod resource; +mod util; +mod world; + +use minedmap_nbt as nbt; +use minedmap_types as types; + +use anyhow::Result; + +fn main() -> Result<()> { + core::cli() +} diff --git a/src/resource/mod.rs b/src/resource/mod.rs index 459e783..a0854c5 100644 --- a/src/resource/mod.rs +++ b/src/resource/mod.rs @@ -46,6 +46,7 @@ pub struct BlockType { impl BlockType { /// Checks whether a block type has a given [BlockFlag] set + #[inline] pub fn is(&self, flag: BlockFlag) -> bool { self.flags.contains(flag) }