mirror of
https://github.com/SpaceManiac/SpacemanDMM.git
synced 2025-12-23 05:36:47 +00:00
Add TGM output
Vars are now a LinkedHashMap to preserve order in the case that they aren't alphabetized in the input.
This commit is contained in:
parent
cdadc8c5ba
commit
90f8c87ddc
5 changed files with 111 additions and 8 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
|
@ -110,6 +110,11 @@ name = "libc"
|
|||
version = "0.2.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "matrixmultiply"
|
||||
version = "0.1.13"
|
||||
|
|
@ -124,6 +129,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"flame 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"inflate 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"linked-hash-map 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ndarray 0.10.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"petgraph 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"png 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -339,6 +345,7 @@ dependencies = [
|
|||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9e5e58fa1a4c3b915a561a78a22ee0cac6ab97dca2504428bc1cb074375f8d5"
|
||||
"checksum libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "56cce3130fd040c28df6f495c8492e5ec5808fb4c9093c310df02b0c8f030148"
|
||||
"checksum linked-hash-map 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2aab0478615bb586559b0114d94dd8eca4fdbb73b443adcb0d00b61692b4bf"
|
||||
"checksum matrixmultiply 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7ce012d2c43046267a74283eaa7e9a51941479901e2b86702be10f27e2779158"
|
||||
"checksum ndarray 0.10.11 (registry+https://github.com/rust-lang/crates.io-index)" = "61f6cb6e2d51afc73d17e19ca3e711b6bd0221773867dbd6453698612d7af95f"
|
||||
"checksum num-complex 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "503e668405c5492d67cf662a81e05be40efe2e6bcf10f7794a07bd9865e704e6"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ png = "0.11.0"
|
|||
inflate = "0.3.3"
|
||||
ndarray = "0.10.11"
|
||||
rand = "0.3.17"
|
||||
linked-hash-map = "0.5.0"
|
||||
flame = { version = "0.2.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
|||
106
src/dmm.rs
106
src/dmm.rs
|
|
@ -1,13 +1,16 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::path::Path;
|
||||
use std::fs::File;
|
||||
use std::io::{self, BufReader};
|
||||
use std::io::{self, BufReader, BufWriter};
|
||||
use std::fmt;
|
||||
|
||||
use ndarray::{self, Array3, Axis};
|
||||
use linked_hash_map::LinkedHashMap;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Map {
|
||||
pub key_length: u8,
|
||||
// sorted order
|
||||
pub dictionary: BTreeMap<u32, Vec<Prefab>>,
|
||||
pub grid: Array3<u32>, // Z/Y/X order
|
||||
}
|
||||
|
|
@ -17,8 +20,8 @@ pub type Grid<'a> = ndarray::ArrayBase<ndarray::ViewRepr<&'a u32>, ndarray::Dim<
|
|||
#[derive(Debug, Default)]
|
||||
pub struct Prefab {
|
||||
pub path: String,
|
||||
// important that this is a BTreeMap, so it's ordered alphabetically
|
||||
pub vars: BTreeMap<String, String>,
|
||||
// insertion order, sort of most of the time alphabetical but not quite
|
||||
pub vars: LinkedHashMap<String, String>,
|
||||
}
|
||||
|
||||
impl Map {
|
||||
|
|
@ -26,13 +29,18 @@ impl Map {
|
|||
flame!("Map::from_file");
|
||||
let mut map = Map {
|
||||
key_length: 0,
|
||||
dictionary: BTreeMap::new(),
|
||||
dictionary: Default::default(),
|
||||
grid: Array3::default((1, 255, 255)),
|
||||
};
|
||||
parse_map(&mut map, File::open(path)?)?;
|
||||
Ok(map)
|
||||
}
|
||||
|
||||
pub fn to_file(&self, path: &Path) -> io::Result<()> {
|
||||
// DMM saver later
|
||||
save_tgm(self, File::create(path)?)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn dim_z(&self) -> usize {
|
||||
self.grid.dim().0
|
||||
|
|
@ -42,6 +50,90 @@ impl Map {
|
|||
pub fn z_level(&self, z: usize) -> Grid {
|
||||
self.grid.subview(Axis(0), z)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn format_key(&self, key: u32) -> FormatKey {
|
||||
FormatKey(self.key_length, key)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Map Writer
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct FormatKey(u8, u32);
|
||||
|
||||
impl FormatKey {
|
||||
#[inline]
|
||||
pub fn new(key_length: u8, key: u32) -> FormatKey {
|
||||
FormatKey(key_length, key)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FormatKey {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use std::fmt::Write;
|
||||
let FormatKey(key_length, key) = *self;
|
||||
|
||||
if key >= 52u32.pow(key_length as u32) {
|
||||
panic!(); // TODO be more reasonable
|
||||
}
|
||||
|
||||
let mut current = 52usize.pow(key_length as u32 - 1);
|
||||
for i in 0..key_length {
|
||||
f.write_char(BASE_52[(key as usize / current) % 52] as char)?;
|
||||
current /= 52;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
const BASE_52: &[u8] = b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
const TGM_HEADER: &str = "//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE";
|
||||
|
||||
fn save_tgm(map: &Map, f: File) -> io::Result<()> {
|
||||
use std::io::Write;
|
||||
|
||||
let mut f = BufWriter::new(f);
|
||||
write!(f, "{}\n", TGM_HEADER)?;
|
||||
|
||||
// dictionary
|
||||
for (&key, prefabs) in map.dictionary.iter() {
|
||||
write!(f, "\"{}\" = (\n", map.format_key(key))?;
|
||||
for (i, fab) in prefabs.iter().enumerate() {
|
||||
write!(f, "{}", fab.path)?;
|
||||
if !fab.vars.is_empty() {
|
||||
write!(f, "{{")?;
|
||||
for (i, (var, value)) in fab.vars.iter().enumerate() {
|
||||
write!(f, "\n\t{} = {}", var, value)?;
|
||||
if i + 1 != fab.vars.len() {
|
||||
write!(f, ";")?;
|
||||
}
|
||||
}
|
||||
write!(f, "\n\t}}")?;
|
||||
}
|
||||
if i + 1 != prefabs.len() {
|
||||
write!(f, ",\n")?;
|
||||
}
|
||||
}
|
||||
write!(f, ")\n")?;
|
||||
}
|
||||
|
||||
// grid in Y-major
|
||||
for (z, z_grid) in map.grid.axis_iter(Axis(0)).enumerate() {
|
||||
write!(f, "\n")?;
|
||||
for (x, x_col) in z_grid.axis_iter(Axis(1)).enumerate() {
|
||||
write!(f, "({},1,{}) = {{\"\n", x + 1, z + 1)?;
|
||||
for &elem in x_col.iter() {
|
||||
write!(f, "{}\n", map.format_key(elem))?;
|
||||
}
|
||||
write!(f, "\"}}\n")?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
@ -125,7 +217,7 @@ fn parse_map(map: &mut Map, f: File) -> io::Result<()> {
|
|||
if ch == '"' {
|
||||
curr_datum.push(ch);
|
||||
in_quote_block = true;
|
||||
} else if ch == '=' {
|
||||
} else if ch == '=' && curr_var.is_empty() {
|
||||
curr_var = take(&mut curr_datum);
|
||||
let length = curr_var.trim_right().len();
|
||||
curr_var.truncate(length);
|
||||
|
|
@ -134,7 +226,9 @@ fn parse_map(map: &mut Map, f: File) -> io::Result<()> {
|
|||
curr_prefab.vars.insert(take(&mut curr_var), take(&mut curr_datum));
|
||||
skip_whitespace = true;
|
||||
} else if ch == '}' {
|
||||
curr_prefab.vars.insert(take(&mut curr_var), take(&mut curr_datum));
|
||||
if !curr_var.is_empty() {
|
||||
curr_prefab.vars.insert(take(&mut curr_var), take(&mut curr_datum));
|
||||
}
|
||||
in_varedit_block = false;
|
||||
} else {
|
||||
curr_datum.push(ch);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ extern crate petgraph;
|
|||
extern crate png;
|
||||
extern crate inflate;
|
||||
|
||||
extern crate linked_hash_map;
|
||||
#[macro_use] extern crate ndarray;
|
||||
extern crate rand;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use petgraph::graph::{Graph, NodeIndex};
|
|||
use xml::EventReader;
|
||||
use xml::reader::XmlEvent;
|
||||
|
||||
pub type Vars = BTreeMap<String, String>;
|
||||
pub type Vars = ::linked_hash_map::LinkedHashMap<String, String>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ObjectTree {
|
||||
|
|
@ -54,7 +54,7 @@ impl ObjectTree {
|
|||
let mut tree = ObjectTree {
|
||||
graph: Graph::new(),
|
||||
types: BTreeMap::new(),
|
||||
blank_vars: BTreeMap::new(),
|
||||
blank_vars: Default::default(),
|
||||
};
|
||||
let root = tree.graph.add_node(Type {
|
||||
name: String::new(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue