mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'src/data/renderer.rs')
| -rw-r--r-- | src/data/renderer.rs | 105 |
1 files changed, 35 insertions, 70 deletions
diff --git a/src/data/renderer.rs b/src/data/renderer.rs index e20b75a..cfd9c9b 100644 --- a/src/data/renderer.rs +++ b/src/data/renderer.rs @@ -1,13 +1,9 @@ //! schematic drawing use dashmap::mapref::one::Ref; use dashmap::DashMap; -use image::codecs::png::PngDecoder; pub(crate) use image::{DynamicImage, RgbaImage}; -use std::io::{BufReader, Cursor}; use std::ops::{Deref, DerefMut}; -use std::path::{Path, PathBuf}; -use std::sync::OnceLock; -use zip::ZipArchive; +use std::sync::LazyLock; pub(crate) use super::autotile::*; use crate::block::environment::METAL_FLOOR; @@ -20,13 +16,16 @@ pub(crate) use std::borrow::{Borrow, BorrowMut}; use super::schematic::Schematic; use super::GridPos; -type Cache = DashMap<PathBuf, RgbaImage>; -fn cache() -> &'static Cache { - CACHE.get_or_init(Cache::new) -} +type Cache = DashMap<String, RgbaImage>; +include!(concat!(env!("OUT_DIR"), "/asset")); // put function from here +static CACHE: LazyLock<Cache> = LazyLock::new(|| { + let mut map = Cache::new(); + put(&mut map); + map +}); pub enum ImageHolder { - Borrow(Ref<'static, PathBuf, RgbaImage>), + Borrow(Ref<'static, String, RgbaImage>), Own(RgbaImage), } @@ -37,6 +36,14 @@ impl ImageHolder { Self::Borrow(x) => x.clone(), } } + + pub fn rotate(&mut self, times: u8) { + if times == 0 { + return; + } + let p: &mut RgbaImage = self.borrow_mut(); + p.rotate(times); + } } impl Borrow<RgbaImage> for ImageHolder { @@ -73,14 +80,8 @@ impl DerefMut for ImageHolder { } } -impl From<Option<Ref<'static, PathBuf, RgbaImage>>> for ImageHolder { - fn from(value: Option<Ref<'static, PathBuf, RgbaImage>>) -> Self { - Self::Borrow(value.unwrap()) - } -} - -impl From<Ref<'static, PathBuf, RgbaImage>> for ImageHolder { - fn from(value: Ref<'static, PathBuf, RgbaImage>) -> Self { +impl From<Ref<'static, String, RgbaImage>> for ImageHolder { + fn from(value: Ref<'static, String, RgbaImage>) -> Self { Self::Borrow(value) } } @@ -91,69 +92,36 @@ impl From<RgbaImage> for ImageHolder { } } -static CACHE: OnceLock<Cache> = OnceLock::new(); -pub(crate) fn load(category: &str, name: &str) -> Option<Ref<'static, PathBuf, RgbaImage>> { - let key = Path::new(category).join(name); - use dashmap::mapref::entry::Entry::*; - Some(match cache().entry(key) { - Occupied(v) => v.into_ref().downgrade(), - Vacant(entry) => { - let mut p = Path::new("blocks").join(category).join(name); - p.set_extension("png"); - let Some(i) = load_raw(p) else { - return None; - }; - entry.insert(i).downgrade() - } - }) +pub(crate) fn try_load(name: &str) -> Option<Ref<'static, String, RgbaImage>> { + let key = name.to_string(); + CACHE.get(&key) } -#[cfg(not(unix))] -const P: &str = "target/out"; -#[cfg(unix)] -const P: &str = "/tmp/mindus-tmp"; - -fn load_raw(f: impl AsRef<Path>) -> Option<RgbaImage> { - let f = std::fs::File::open(Path::new(P).join(f)).ok()?; - let r = PngDecoder::new(BufReader::new(f)).unwrap(); - let p = DynamicImage::from_decoder(r).unwrap().into_rgba8(); - assert!(p.width() != 0); - assert!(p.height() != 0); - Some(p) +pub(crate) fn load(name: &str) -> ImageHolder { + ImageHolder::from( + try_load(name) + .ok_or_else(|| format!("failed to load {name}")) + .unwrap(), + ) } -fn load_zip() { - if !Path::new(P).exists() { - let mut zip = ZipArchive::new(Cursor::new( - include_bytes!(concat!(env!("OUT_DIR"), "/asset")).to_vec(), - )) - .unwrap(); - zip.extract(P).unwrap(); - } -} -pub const TOP: &str = "-top"; const SUFFIXES: &[&str; 9] = &[ - "-bottom", "-mid", "-base", "", "-left", "-right", TOP, "-over", "-team", + "-bottom", "-mid", "-base", "", "-left", "-right", "-top", "-over", "-team", ]; -pub(crate) fn read<S>(category: &str, name: &str, size: S) -> RgbaImage +pub(crate) fn read<S>(name: &str, size: S) -> ImageHolder where S: Into<u32> + Copy, { - read_with(category, name, SUFFIXES, size) + read_with(name, SUFFIXES, size) } -pub(crate) fn read_with<S>( - category: &str, - name: &str, - suffixes: &'static [&'static str], - size: S, -) -> RgbaImage +pub(crate) fn read_with<S>(name: &str, suffixes: &'static [&'static str], size: S) -> ImageHolder where S: Into<u32> + Copy, { let mut c = RgbaImage::new(size.into() * 32, size.into() * 32); for suffix in suffixes { - if let Some(p) = load(category, &format!("{name}{suffix}")) { + if let Some(p) = try_load(&format!("{name}{suffix}")) { if suffix == &"-team" { c.overlay(p.clone().tint(SHARDED.color())); continue; @@ -161,7 +129,7 @@ where c.overlay(&p); } } - c + ImageHolder::from(c) } /// trait for renderable objects @@ -180,7 +148,6 @@ impl Renderable for Schematic<'_> { /// let output /*: RgbaImage */ = s.render(); /// ``` fn render(&self) -> RgbaImage { - load_zip(); // fill background let mut bg = RgbaImage::new( ((self.width + 2) * 32) as u32, @@ -225,7 +192,6 @@ impl Renderable for Schematic<'_> { impl Renderable for Map<'_> { fn render(&self) -> RgbaImage { - load_zip(); let scale = if self.width + self.height < 2000 { 8 } else { @@ -291,7 +257,6 @@ impl Renderable for Map<'_> { #[test] fn all_blocks() { - load_zip(); use crate::block::content::Type; use crate::content::Content; let reg = crate::block::build_registry(); @@ -308,7 +273,7 @@ fn all_blocks() { continue; } - let t = reg.get(dbg!(t.get_name())).unwrap(); + let t = reg.get(t.get_name()).unwrap(); t.image( None, Some(&RenderingContext { |