mindustry logic execution, map- and schematic- parsing and rendering
remove leaky hashmap reference rwlock shenanigans
| -rw-r--r-- | Cargo.toml | 3 | ||||
| -rw-r--r-- | build.rs | 4 | ||||
| -rw-r--r-- | src/data/map.rs | 103 | ||||
| -rw-r--r-- | src/data/renderer.rs | 19 | ||||
| -rw-r--r-- | src/exe/map.rs | 10 |
5 files changed, 69 insertions, 70 deletions
@@ -1,6 +1,6 @@ [package] name = "mindus" -version = "3.0.3" +version = "3.0.5" edition = "2021" description = "A library for working with mindustry data formats (eg schematics and maps) (fork of plandustry)" authors = [ @@ -22,7 +22,6 @@ thiserror = "1.0" bobbin-bits = "0.1" blurslice = { version = "0.1" } enum_dispatch = "0.3" -ahash = { version = "0.8.3", default-features = false, features = ["std", "no-rng"] } [features] bin = ["image/png"] @@ -82,7 +82,9 @@ fn main() { let (mx, my) = if p.width() + p.height() == 48+48 { (32, 32) // vents (dont match VENT_CONDENSER, do match (RHYOLITE_VENT) - } else if path.contains("_VENT") { + } else if path.contains("_VENT") + // talls + || matches!(path.as_str(), "YELLOWCORAL" | "WHITE_TREE" | "WHITE_TREE_DEAD" | "REDWEED" | "SPORE_CLUSTER" | "CRYSTAL_BLOCKS" | "CRYSTAL_CLUSTER" | "VIBRANT_CRYSTAL_CLUSTER" | "CRYSTAL_ORBS") { (32, 32) } else { (p.height(), p.width()) diff --git a/src/data/map.rs b/src/data/map.rs index 2545a65..aceddbc 100644 --- a/src/data/map.rs +++ b/src/data/map.rs @@ -71,7 +71,6 @@ //! - entity read use std::collections::HashMap; use std::ops::{Index, IndexMut}; -use std::sync::RwLock; use thiserror::Error; use crate::block::content::Type as BlockEnum; @@ -97,6 +96,15 @@ pub struct Tile<'l> { build: Option<Build<'l>>, } +macro_rules! lo { + ($v:expr => [$(|)? $($k:literal $(|)?)+], $scale: ident) => { paste::paste! { + match $v { + $(BlockEnum::[<$k:camel>] => load!($k, $scale),)+ + n => unreachable!("{n:?}"), + } + } }; +} + pub type EntityMapping = HashMap<u8, Box<dyn Content>>; impl<'l> Tile<'l> { #[must_use] @@ -138,22 +146,8 @@ impl<'l> Tile<'l> { 1 } - /// Draw the floor of this tile - /// - /// # Safety - /// - /// UB if called before [`warmup`](crate::warmup) - pub unsafe fn floor_image(&self, s: Scale) -> ImageHolder { - macro_rules! lo { - ($v:expr => [$(|)? $($k:literal $(|)?)+], $scale: ident) => { paste::paste! { - match $v { - $(BlockEnum::[<$k:camel>] => load!($k, $scale),)+ - n => unreachable!("{n:?}"), - } } - } - } - let floor = || { - lo!(self.floor => [ + pub(crate) unsafe fn floor(&self, s: Scale) -> ImageHolder { + lo!(self.floor => [ | "darksand" | "sand-floor" | "dacite" @@ -162,62 +156,57 @@ impl<'l> Tile<'l> { | "basalt" | "moss" | "mud" - | "magmarock" | "grass" - | "ice-snow" - | "hotrock" - | "char" - | "snow" - | "salt" + | "ice-snow" | "snow" | "salt" | "ice" + | "hotrock" | "char" | "magmarock" | "shale" | "metal-floor" | "metal-floor-2" | "metal-floor-3" | "metal-floor-4" | "metal-floor-5" | "metal-floor-damaged" | "dark-panel-1" | "dark-panel-2" | "dark-panel-3" | "dark-panel-4" | "dark-panel-5" | "dark-panel-6" - | "darksand-tainted-water" - | "darksand-water" - | "deep-tainted-water" - | "molten-slag" - | "deep-water" - | "sand-water" - | "shallow-water" + | "darksand-tainted-water" | "darksand-water" | "deep-tainted-water" | "deep-water" | "sand-water" | "shallow-water" | "tainted-water" + | "tar" | "pooled-cryofluid" | "molten-slag" | "space" | "stone" | "bluemat" | "ferric-craters" | "beryllic-stone" - | "rhyolite-crater" + | "rhyolite" | "rough-rhyolite" | "rhyolite-crater" | "rhyolite-vent" | "core-zone" | "crater-stone" - | "crystal-floor" - | "dense-red-stone" | "redmat" | "red-ice" | "spore-moss" - | "arkyic-vent" | "red-stone-vent" | "rhyolite-vent" | "carbon-vent" | "crystalline-vent" | "yellow-stone-vent" | "regolith" - | "rhyolite" - | "tainted-water" - | "tar" - | "empty" - ], s) - }; - if self.ore != BlockEnum::Air { - type Floor = BlockEnum; - type Ore = BlockEnum; - // todo Rgb - static ORE_LAYS: RwLock<HashMap<(Floor, Ore), &'static RgbaImage, ahash::RandomState>> = - RwLock::new(HashMap::with_hasher(ahash::RandomState::with_seeds( - 401, 41209, 83123, 2110, - ))); - if let Some(v) = ORE_LAYS.read().unwrap().get(&(self.floor, self.ore)) { - return ImageHolder::from(*v); - } - return ImageHolder::from(*ORE_LAYS.write().unwrap().entry((self.floor, self.ore)).or_insert_with(|| { - let mut base = floor(); - base.overlay(lo!(self.ore => ["ore-copper" | "ore-beryllium" | "ore-lead" | "ore-scrap" | "ore-coal" | "ore-thorium" | "ore-titanium" | "ore-tungsten" | "pebbles" | "tendrils"], s).borrow()); - Box::leak(Box::new(base)) - })); + | "ferric-stone" + | "arkyic-stone" | "arkyic-vent" + | "yellow-stone" | "yellow-stone-plates" | "yellow-stone-vent" + | "red-stone" | "red-stone-vent" | "dense-red-stone" + | "carbon-stone" | "carbon-vent" + | "crystal-floor" | "crystalline-stone" | "crystalline-vent" + | "empty"], s) + } + + #[must_use] + pub(crate) unsafe fn ore(&self, s: Scale) -> ImageHolder { + lo!(self.ore => ["ore-copper" | "ore-beryllium" | "ore-lead" | "ore-scrap" | "ore-coal" | "ore-thorium" | "ore-titanium" | "ore-tungsten" | "pebbles" | "tendrils" | "ore-wall-tungsten" | "ore-wall-beryllium" | "ore-wall-thorium" | "spawn" | "ore-crystal-thorium"], s) + } + + #[must_use] + pub fn has_ore(&self) -> bool { + self.ore != BlockEnum::Air + } + + /// Draw the floor of this tile + /// + /// # Safety + /// + /// UB if called before [`warmup`](crate::warmup) + #[must_use] + pub unsafe fn floor_image(&self, s: Scale) -> ImageHolder { + let mut floor = self.floor(s); + if self.has_ore() { + floor.overlay(&self.ore(s)); } - floor() + floor } /// Draw this tiles build. diff --git a/src/data/renderer.rs b/src/data/renderer.rs index 8289ce1..b209c5a 100644 --- a/src/data/renderer.rs +++ b/src/data/renderer.rs @@ -276,11 +276,18 @@ impl Renderable for Map<'_> { ) }) { // draw the floor first. - let img: &RgbaImage = &tile.floor_image(scale); + let flo: &RgbaImage = &tile.floor(scale); // println!("draw {tile:?} ({x}, {y}) + {scale:?}"); - debug_assert_eq!(img.width(), scale.px() as u32); - debug_assert_eq!(img.height(), scale.px() as u32); - floor.overlay_at(img, scale * x as u32, scale * y as u32); + // debug_assert_eq!(floor.width(), scale.px() as u32); + // debug_assert_eq!(floor.height(), scale.px() as u32); + floor.overlay_at(flo, scale * x as u32, scale * y as u32); + if tile.has_ore() { + let ore: &RgbaImage = &tile.ore(scale); + // debug_assert_eq!(ore.width(), scale.px() as u32); + // debug_assert_eq!(ore.height(), scale.px() as u32); + floor.overlay_at(ore, scale * x as u32, scale * y as u32); + } + if let Some(build) = tile.build() { let s = build.block.get_size(); let x = x - ((s - 1) / 2) as usize; @@ -300,8 +307,8 @@ impl Renderable for Map<'_> { None }; let img: &RgbaImage = &tile.build_image(ctx.as_ref(), scale); - debug_assert_eq!(img.width(), scale * build.block.get_size() as u32); - debug_assert_eq!(img.height(), scale * build.block.get_size() as u32); + // debug_assert_eq!(img.width(), scale * build.block.get_size() as u32); + // debug_assert_eq!(img.height(), scale * build.block.get_size() as u32); top.overlay_at(img, scale * x as u32, scale * y as u32); } } diff --git a/src/exe/map.rs b/src/exe/map.rs index c976696..51c05c6 100644 --- a/src/exe/map.rs +++ b/src/exe/map.rs @@ -9,6 +9,7 @@ use super::print_err; pub fn main(args: Args) { let reg = build_registry(); let mut ms = MapSerializer(®); + let runs = std::env::var("RUNS").map_or(10u8, |x| x.parse().unwrap_or(10u8)); // process schematics from command line println!("starting timing"); @@ -31,17 +32,18 @@ pub fn main(args: Args) { } } let starting_render = Instant::now(); - for _ in 0..10 { + for _ in 0..runs { unsafe { m.render() }; } let renders_took = starting_render.elapsed(); let took = then.elapsed(); println!( - "μ total: {:.2}s (10 runs) (deser: {}ms, warmup: {}ms, render: {:.2}s) on map {}", - took.as_secs_f32() / 10., + "μ total: {:.2}s ({} runs) (deser: {}ms, warmup: {}ms, render: {:.2}s) on map {}", + took.as_secs_f32() / runs as f32, + runs, deser_took.as_millis(), warmup_took.as_millis(), - renders_took.as_secs_f32() / 10., + renders_took.as_secs_f32() / runs as f32, m.tags.get("mapname").unwrap(), ); } |