Add summary messages

This commit is contained in:
Matthias Schiffer 2023-09-20 00:38:19 +02:00
parent a8eb2da95d
commit 7d37f6a5d0
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
3 changed files with 97 additions and 34 deletions

View file

@ -5,7 +5,7 @@ use std::{ffi::OsStr, path::Path, time::SystemTime};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use indexmap::IndexSet; use indexmap::IndexSet;
use rayon::prelude::*; use rayon::prelude::*;
use tracing::{debug, error}; use tracing::{debug, error, info};
use super::common::*; use super::common::*;
use crate::{ use crate::{
@ -132,7 +132,7 @@ impl<'a> RegionProcessor<'a> {
} }
/// Processes a single region file /// Processes a single region file
fn process_region(&self, coords: TileCoords) -> Result<()> { fn process_region(&self, coords: TileCoords) -> Result<bool> {
/// Width/height of the region data /// Width/height of the region data
const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32;
@ -150,7 +150,7 @@ impl<'a> RegionProcessor<'a> {
if Some(input_timestamp) <= output_timestamp && Some(input_timestamp) <= lightmap_timestamp if Some(input_timestamp) <= output_timestamp && Some(input_timestamp) <= lightmap_timestamp
{ {
debug!("Skipping unchanged region r.{}.{}.mca", coords.x, coords.z); debug!("Skipping unchanged region r.{}.{}.mca", coords.x, coords.z);
return Ok(()); return Ok(false);
} }
debug!("Processing region r.{}.{}.mca", coords.x, coords.z); debug!("Processing region r.{}.{}.mca", coords.x, coords.z);
@ -188,7 +188,7 @@ impl<'a> RegionProcessor<'a> {
Self::save_lightmap(&lightmap_path, &lightmap, input_timestamp)?; Self::save_lightmap(&lightmap_path, &lightmap, input_timestamp)?;
} }
Ok(()) Ok(true)
} }
/// Iterates over all region files of a Minecraft save directory /// Iterates over all region files of a Minecraft save directory
@ -203,11 +203,31 @@ impl<'a> RegionProcessor<'a> {
fs::create_dir_all(&self.config.processed_dir)?; fs::create_dir_all(&self.config.processed_dir)?;
fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, 0))?; fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, 0))?;
regions.par_iter().for_each(|&coords| { info!("Processing region files...");
if let Err(err) = self.process_region(coords) {
error!("Failed to process region {:?}: {:?}", coords, err); let mut results = vec![];
} regions
}); .par_iter()
.map(|&coords| {
let result = self.process_region(coords);
if let Err(err) = &result {
error!("Failed to process region {:?}: {:?}", coords, err);
}
result
})
.collect_into_vec(&mut results);
let processed = results
.iter()
.filter(|result| matches!(result, Ok(true)))
.count();
let errors = results.iter().filter(|result| result.is_err()).count();
info!(
"Processed region files ({} processed, {} unchanged, {} errors)",
processed,
results.len() - processed,
errors,
);
Ok(regions) Ok(regions)
} }

View file

@ -2,7 +2,7 @@
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use rayon::prelude::*; use rayon::prelude::*;
use tracing::{debug, warn}; use tracing::{debug, info, warn};
use super::common::*; use super::common::*;
use crate::{io::fs, types::*}; use crate::{io::fs, types::*};
@ -58,7 +58,7 @@ impl<'a> TileMipmapper<'a> {
level: usize, level: usize,
coords: TileCoords, coords: TileCoords,
prev: &TileCoordMap, prev: &TileCoordMap,
) -> Result<()> ) -> Result<(bool, bool)>
where where
[P::Subpixel]: image::EncodableLayout, [P::Subpixel]: image::EncodableLayout,
image::ImageBuffer<P, Vec<P::Subpixel>>: Into<image::DynamicImage>, image::ImageBuffer<P, Vec<P::Subpixel>>: Into<image::DynamicImage>,
@ -93,7 +93,7 @@ impl<'a> TileMipmapper<'a> {
.collect(); .collect();
let Some(input_timestamp) = sources.iter().map(|(_, _, ts)| *ts).max() else { let Some(input_timestamp) = sources.iter().map(|(_, _, ts)| *ts).max() else {
return Ok(()); return Ok((false, false));
}; };
if Some(input_timestamp) <= output_timestamp { if Some(input_timestamp) <= output_timestamp {
@ -104,7 +104,7 @@ impl<'a> TileMipmapper<'a> {
.expect("tile path must be in output directory") .expect("tile path must be in output directory")
.display(), .display(),
); );
return Ok(()); return Ok((true, false));
} }
debug!( debug!(
@ -143,7 +143,9 @@ impl<'a> TileMipmapper<'a> {
image image
.write_to(file, image::ImageFormat::Png) .write_to(file, image::ImageFormat::Png)
.context("Failed to save image") .context("Failed to save image")
}) })?;
Ok((true, true))
} }
/// Runs the mipmap generation /// Runs the mipmap generation
@ -165,24 +167,48 @@ impl<'a> TileMipmapper<'a> {
break; break;
} }
info!("Generating level {} mipmaps...", level);
fs::create_dir_all(&self.config.tile_dir(TileKind::Map, level))?; fs::create_dir_all(&self.config.tile_dir(TileKind::Map, level))?;
fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, level))?; fs::create_dir_all(&self.config.tile_dir(TileKind::Lightmap, level))?;
let next = Self::map_coords(prev); let next = Self::map_coords(prev);
next.0.par_iter().try_for_each(|(&z, xs)| { let (total, processed) = next
xs.par_iter().try_for_each(|&x| { .0
let coords = TileCoords { x, z }; .par_iter()
self.render_mipmap::<image::Rgba<u8>>(TileKind::Map, level, coords, prev)?; .flat_map(|(&z, xs)| {
self.render_mipmap::<image::LumaA<u8>>( let mipmapper = &self;
TileKind::Lightmap, xs.par_iter().map(move |&x| {
level, let coords = TileCoords { x, z };
coords, let (found_map, processed_map) = mipmapper
prev, .render_mipmap::<image::Rgba<u8>>(TileKind::Map, level, coords, prev)?;
)?; let (found_light, processed_light) = mipmapper
anyhow::Ok(()) .render_mipmap::<image::LumaA<u8>>(
TileKind::Lightmap,
level,
coords,
prev,
)?;
anyhow::Ok((
usize::from(found_map) + usize::from(found_light),
usize::from(processed_map) + usize::from(processed_light),
))
})
}) })
})?; .try_reduce(
|| (0, 0),
|(found_a, processed_a), (found_b, processed_b)| {
Ok((found_a + found_b, processed_a + processed_b))
},
)?;
info!(
"Generated level {} mipmaps ({} processed, {} unchanged)",
level,
processed,
total - processed,
);
tile_stack.push(next); tile_stack.push(next);
} }

View file

@ -12,7 +12,7 @@ use glam::Vec3;
use lru::LruCache; use lru::LruCache;
use rayon::prelude::*; use rayon::prelude::*;
use tokio::sync::OnceCell; use tokio::sync::OnceCell;
use tracing::debug; use tracing::{debug, info};
use super::{common::*, region_group::RegionGroup}; use super::{common::*, region_group::RegionGroup};
use crate::{ use crate::{
@ -263,7 +263,7 @@ impl<'a> TileRenderer<'a> {
} }
/// Renders and saves a region tile image /// Renders and saves a region tile image
fn render_tile(&self, coords: TileCoords) -> Result<()> { fn render_tile(&self, coords: TileCoords) -> Result<bool> {
/// Width/height of a tile image /// Width/height of a tile image
const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32; const N: u32 = (BLOCKS_PER_CHUNK * CHUNKS_PER_REGION) as u32;
@ -280,7 +280,7 @@ impl<'a> TileRenderer<'a> {
.expect("tile path must be in output directory") .expect("tile path must be in output directory")
.display(), .display(),
); );
return Ok(()); return Ok(false);
} }
debug!( debug!(
@ -307,18 +307,35 @@ impl<'a> TileRenderer<'a> {
.write_to(file, image::ImageFormat::Png) .write_to(file, image::ImageFormat::Png)
.context("Failed to save image") .context("Failed to save image")
}, },
) )?;
Ok(true)
} }
/// Runs the tile generation /// Runs the tile generation
pub fn run(self) -> Result<()> { pub fn run(self) -> Result<()> {
fs::create_dir_all(&self.config.tile_dir(TileKind::Map, 0))?; fs::create_dir_all(&self.config.tile_dir(TileKind::Map, 0))?;
info!("Rendering map tiles...");
// Use par_bridge to process items in order (for better use of region cache) // Use par_bridge to process items in order (for better use of region cache)
self.regions.iter().par_bridge().try_for_each(|&coords| { let processed = self
self.render_tile(coords) .regions
.with_context(|| format!("Failed to render tile {:?}", coords)) .iter()
})?; .par_bridge()
.map(|&coords| {
anyhow::Ok(usize::from(
self.render_tile(coords)
.with_context(|| format!("Failed to render tile {:?}", coords))?,
))
})
.try_reduce(|| 0, |a, b| Ok(a + b))?;
info!(
"Rendered map tiles ({} processed, {} unchanged)",
processed,
self.regions.len() - processed,
);
Ok(()) Ok(())
} }