mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-03-04 17:23:33 +01:00
Add summary messages
This commit is contained in:
parent
a8eb2da95d
commit
7d37f6a5d0
3 changed files with 97 additions and 34 deletions
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue