diff --git a/src/bin/minedmap/region_processor.rs b/src/bin/minedmap/region_processor.rs index d20f82b..a95f6ea 100644 --- a/src/bin/minedmap/region_processor.rs +++ b/src/bin/minedmap/region_processor.rs @@ -66,43 +66,46 @@ impl<'a> RegionProcessor<'a> { } fn save_region( - &self, - coords: TileCoords, + path: &Path, processed_region: &ProcessedRegion, timestamp: SystemTime, ) -> Result<()> { - let output_path = self.config.processed_path(coords); - storage::write(&output_path, processed_region, FILE_META_VERSION, timestamp) + storage::write(path, processed_region, FILE_META_VERSION, timestamp) } fn save_lightmap( - &self, - coords: TileCoords, + path: &Path, lightmap: &image::GrayAlphaImage, timestamp: SystemTime, ) -> Result<()> { - fs::create_with_timestamp( - &self.config.tile_path(TileKind::Lightmap, 0, coords), - FILE_META_VERSION, - timestamp, - |file| { - lightmap - .write_to(file, image::ImageFormat::Png) - .context("Failed to save image") - }, - ) + fs::create_with_timestamp(path, FILE_META_VERSION, timestamp, |file| { + lightmap + .write_to(file, image::ImageFormat::Png) + .context("Failed to save image") + }) } /// Processes a single region file fn process_region(&self, path: &Path, coords: TileCoords) -> Result<()> { const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; - println!("Processing region r.{}.{}.mca", coords.x, coords.z); - let mut processed_region = ProcessedRegion::default(); let mut lightmap = image::GrayAlphaImage::new(N, N); - let timestamp = fs::modified_timestamp(path)?; + let input_timestamp = fs::modified_timestamp(path)?; + + let output_path = self.config.processed_path(coords); + let output_timestamp = fs::read_timestamp(&output_path, FILE_META_VERSION); + let lightmap_path = self.config.tile_path(TileKind::Lightmap, 0, coords); + let lightmap_timestamp = fs::read_timestamp(&lightmap_path, FILE_META_VERSION); + + if Some(input_timestamp) <= output_timestamp && Some(input_timestamp) <= lightmap_timestamp + { + println!("Skipping unchanged region r.{}.{}.mca", coords.x, coords.z); + return Ok(()); + } + + println!("Processing region r.{}.{}.mca", coords.x, coords.z); minedmap::io::region::from_file(path)?.foreach_chunk( |chunk_coords, data: world::de::Chunk| { @@ -125,8 +128,12 @@ impl<'a> RegionProcessor<'a> { }, )?; - self.save_region(coords, &processed_region, timestamp)?; - self.save_lightmap(coords, &lightmap, timestamp)?; + if Some(input_timestamp) > output_timestamp { + Self::save_region(&output_path, &processed_region, input_timestamp)?; + } + if Some(input_timestamp) > lightmap_timestamp { + Self::save_lightmap(&lightmap_path, &lightmap, input_timestamp)?; + } Ok(()) } diff --git a/src/bin/minedmap/tile_mipmapper.rs b/src/bin/minedmap/tile_mipmapper.rs index 22b942d..40add3a 100644 --- a/src/bin/minedmap/tile_mipmapper.rs +++ b/src/bin/minedmap/tile_mipmapper.rs @@ -49,17 +49,7 @@ impl<'a> TileMipmapper<'a> { const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; let output_path = self.config.tile_path(kind, level, coords); - - println!( - "Rendering mipmap tile {}", - output_path - .strip_prefix(&self.config.output_dir) - .expect("tile path must be in output directory") - .display(), - ); - - let mut image: image::DynamicImage = - image::ImageBuffer::
>::new(N, N).into(); + let output_timestamp = fs::read_timestamp(&output_path, FILE_META_VERSION); let sources: Vec<_> = [(0, 0), (0, 1), (1, 0), (1, 1)] .into_iter() @@ -84,10 +74,32 @@ impl<'a> TileMipmapper<'a> { }) .collect(); - let Some(timestamp) = sources.iter().map(|(_, _, ts)| *ts).max() else { + let Some(input_timestamp) = sources.iter().map(|(_, _, ts)| *ts).max() else { return Ok(()); }; + if Some(input_timestamp) <= output_timestamp { + println!( + "Skipping unchanged mipmap tile {}", + output_path + .strip_prefix(&self.config.output_dir) + .expect("tile path must be in output directory") + .display(), + ); + return Ok(()); + } + + println!( + "Rendering mipmap tile {}", + output_path + .strip_prefix(&self.config.output_dir) + .expect("tile path must be in output directory") + .display(), + ); + + let mut image: image::DynamicImage = + image::ImageBuffer::
>::new(N, N).into();
+
for ((dx, dz), source_path, _) in sources {
let source = match image::open(&source_path) {
Ok(source) => source,
@@ -109,7 +121,7 @@ impl<'a> TileMipmapper<'a> {
);
}
- fs::create_with_timestamp(&output_path, FILE_META_VERSION, timestamp, |file| {
+ fs::create_with_timestamp(&output_path, FILE_META_VERSION, input_timestamp, |file| {
image
.write_to(file, image::ImageFormat::Png)
.context("Failed to save image")
diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs
index 0e91054..955c964 100644
--- a/src/bin/minedmap/tile_renderer.rs
+++ b/src/bin/minedmap/tile_renderer.rs
@@ -1,4 +1,4 @@
-use std::time::SystemTime;
+use std::path::Path;
use anyhow::{Context, Result};
@@ -19,12 +19,8 @@ impl<'a> TileRenderer<'a> {
TileRenderer { config }
}
- fn load_region(&self, coords: TileCoords) -> Result<(ProcessedRegion, SystemTime)> {
- let processed_path = self.config.processed_path(coords);
- let timestamp = fs::modified_timestamp(&processed_path)?;
- let region =
- storage::read(&processed_path).context("Failed to load processed region data")?;
- Ok((region, timestamp))
+ fn load_region(processed_path: &Path) -> Result