mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-03-04 17:23:33 +01:00
core: merge entity data for all regions into one file
Introduce the EntityCollector, using the TileCollector and TileMerger traits.
This commit is contained in:
parent
1143396068
commit
cde6a4b6e6
3 changed files with 132 additions and 1 deletions
|
@ -141,6 +141,8 @@ pub struct Config {
|
|||
pub processed_dir: PathBuf,
|
||||
/// Path for storage of processed entity data files
|
||||
pub entities_dir: PathBuf,
|
||||
/// Path for storage of the final merged processed entity data file
|
||||
pub entities_path_final: PathBuf,
|
||||
/// Path of viewer metadata file
|
||||
pub metadata_path: PathBuf,
|
||||
}
|
||||
|
@ -157,7 +159,8 @@ impl Config {
|
|||
let region_dir = [&args.input_dir, Path::new("region")].iter().collect();
|
||||
let level_dat_path = [&args.input_dir, Path::new("level.dat")].iter().collect();
|
||||
let processed_dir: PathBuf = [&args.output_dir, Path::new("processed")].iter().collect();
|
||||
let entities_dir = [&processed_dir, Path::new("entities")].iter().collect();
|
||||
let entities_dir: PathBuf = [&processed_dir, Path::new("entities")].iter().collect();
|
||||
let entities_path_final = [&entities_dir, Path::new("entities.bin")].iter().collect();
|
||||
let metadata_path = [&args.output_dir, Path::new("info.json")].iter().collect();
|
||||
|
||||
Config {
|
||||
|
@ -167,6 +170,7 @@ impl Config {
|
|||
output_dir: args.output_dir.clone(),
|
||||
processed_dir,
|
||||
entities_dir,
|
||||
entities_path_final,
|
||||
metadata_path,
|
||||
}
|
||||
}
|
||||
|
|
123
src/core/entity_collector.rs
Normal file
123
src/core/entity_collector.rs
Normal file
|
@ -0,0 +1,123 @@
|
|||
//! The [EntityCollector]
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use tracing::{info, warn};
|
||||
|
||||
use super::{common::*, tile_collector::TileCollector, tile_merger::TileMerger};
|
||||
use crate::io::{fs, storage};
|
||||
|
||||
/// Generates mipmap tiles from full-resolution tile images
|
||||
pub struct EntityCollector<'a> {
|
||||
/// Common MinedMap configuration from command line
|
||||
config: &'a Config,
|
||||
/// List of populated tiles for base mipmap level (level 0)
|
||||
regions: &'a [TileCoords],
|
||||
}
|
||||
|
||||
impl<'a> TileMerger for EntityCollector<'a> {
|
||||
fn file_meta_version(&self) -> fs::FileMetaVersion {
|
||||
ENTITIES_FILE_META_VERSION
|
||||
}
|
||||
|
||||
fn tile_path(&self, level: usize, coords: TileCoords) -> std::path::PathBuf {
|
||||
self.config.entities_path(level, coords)
|
||||
}
|
||||
|
||||
fn write_tile(
|
||||
&self,
|
||||
file: &mut std::io::BufWriter<std::fs::File>,
|
||||
sources: &[super::tile_merger::Source],
|
||||
) -> Result<()> {
|
||||
Self::merge_entity_lists(file, sources.iter().map(|source| &source.1))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TileCollector for EntityCollector<'a> {
|
||||
type CollectOutput = ();
|
||||
|
||||
fn tiles(&self) -> &[TileCoords] {
|
||||
self.regions
|
||||
}
|
||||
|
||||
fn prepare(&self, level: usize) -> Result<()> {
|
||||
fs::create_dir_all(&self.config.entities_dir(level))
|
||||
}
|
||||
|
||||
fn finish(
|
||||
&self,
|
||||
_level: usize,
|
||||
_outputs: impl Iterator<Item = Self::CollectOutput>,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn collect_one(
|
||||
&self,
|
||||
level: usize,
|
||||
coords: TileCoords,
|
||||
prev: &TileCoordMap,
|
||||
) -> Result<Self::CollectOutput> {
|
||||
self.merge_tiles(level, coords, prev)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> EntityCollector<'a> {
|
||||
/// Constructs a new EntityCollector
|
||||
pub fn new(config: &'a Config, regions: &'a [TileCoords]) -> Self {
|
||||
EntityCollector { config, regions }
|
||||
}
|
||||
|
||||
/// Merges multiple entity lists into one
|
||||
fn merge_entity_lists<P: AsRef<Path>>(
|
||||
file: &mut std::io::BufWriter<std::fs::File>,
|
||||
sources: impl Iterator<Item = P>,
|
||||
) -> Result<()> {
|
||||
let mut output = ProcessedEntities::default();
|
||||
|
||||
for source_path in sources {
|
||||
let mut source: ProcessedEntities =
|
||||
match storage::read_file(source_path.as_ref(), storage::Format::Json) {
|
||||
Ok(source) => source,
|
||||
Err(err) => {
|
||||
warn!(
|
||||
"Failed to read entity data file {}: {:?}",
|
||||
source_path.as_ref().display(),
|
||||
err,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
output.block_entities.append(&mut source.block_entities);
|
||||
}
|
||||
|
||||
storage::write(file, &output, storage::Format::Json).context("Failed to write entity data")
|
||||
}
|
||||
|
||||
/// Runs the mipmap generation
|
||||
pub fn run(self) -> Result<()> {
|
||||
info!("Collecting entity data...");
|
||||
|
||||
let tile_stack = self.collect_tiles()?;
|
||||
|
||||
// Final merge
|
||||
let level = tile_stack.len() - 1;
|
||||
let tile_map = &tile_stack[level];
|
||||
let sources: Vec<_> = [(-1, -1), (-1, 0), (0, -1), (0, 0)]
|
||||
.into_iter()
|
||||
.map(|(x, z)| TileCoords { x, z })
|
||||
.filter(|&coords| tile_map.contains(coords))
|
||||
.map(|coords| self.tile_path(level, coords))
|
||||
.collect();
|
||||
|
||||
fs::create_with_tmpfile(&self.config.entities_path_final, |file| {
|
||||
Self::merge_entity_lists(file, sources.iter())
|
||||
})?;
|
||||
|
||||
info!("Collected entity data.");
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
//! Core functions of the MinedMap CLI
|
||||
|
||||
mod common;
|
||||
mod entity_collector;
|
||||
mod metadata_writer;
|
||||
mod region_group;
|
||||
mod region_processor;
|
||||
|
@ -21,6 +22,8 @@ use region_processor::RegionProcessor;
|
|||
use tile_mipmapper::TileMipmapper;
|
||||
use tile_renderer::TileRenderer;
|
||||
|
||||
use self::entity_collector::EntityCollector;
|
||||
|
||||
/// MinedMap version number
|
||||
const VERSION: &str = git_version!(
|
||||
args = ["--abbrev=7", "--match=v*", "--dirty=-modified"],
|
||||
|
@ -77,6 +80,7 @@ pub fn cli() -> Result<()> {
|
|||
let regions = RegionProcessor::new(&config).run()?;
|
||||
TileRenderer::new(&config, &rt, ®ions).run()?;
|
||||
let tiles = TileMipmapper::new(&config, ®ions).run()?;
|
||||
EntityCollector::new(&config, ®ions).run()?;
|
||||
MetadataWriter::new(&config, &tiles).run()?;
|
||||
|
||||
Ok(())
|
||||
|
|
Loading…
Add table
Reference in a new issue