Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON file processing (MC assets) #175

Open
toqueteos opened this issue Jan 21, 2015 · 4 comments
Open

JSON file processing (MC assets) #175

toqueteos opened this issue Jan 21, 2015 · 4 comments

Comments

@toqueteos
Copy link
Contributor

There's three big blobs (one on block_state.rs, two on model.rs) which could be a lot simpler if we used the auto-derive capabilities of json::decode.

Example:

extern crate "rustc-serialize" as rustc_serialize;

use std::collections::BTreeMap;
use std::io::File;
use std::io::fs::walk_dir;

use rustc_serialize::Decodable;
use rustc_serialize::json::{self, Json};

#[derive(RustcDecodable, PartialEq, Show)]
struct FaceInfo {
    cullface: Option<String>,
    rotation: Option<i64>,
    texture: String,
    tintindex: Option<i64>,
    uv: Option<Vec<f64>>,
}

#[derive(RustcDecodable, PartialEq, Show)]
struct Faces {
    down: Option<FaceInfo>,
    east: Option<FaceInfo>,
    north: Option<FaceInfo>,
    south: Option<FaceInfo>,
    up: Option<FaceInfo>,
    west: Option<FaceInfo>,
}

#[derive(RustcDecodable, PartialEq, Show)]
struct Rotation {
    angle: f64,
    axis: String,
    origin: Vec<f64>,
    rescale: Option<bool>,
}

#[derive(RustcDecodable, PartialEq, Show)]
struct Element {
    from: Vec<f64>,
    to: Vec<f64>,
    rotation: Option<Rotation>,
    shade: Option<bool>,
    faces: Faces,
}

#[derive(RustcDecodable, PartialEq, Show)]
struct BlockModel {
    parent : Option<String>,
    ambientocclusion: Option<bool>,
    textures: Option<BTreeMap<String, String>>,
    elements: Option<Vec<Element>>,
}

fn main() {
    let path = Path::new("src/bin/block");
    let mut n = 0;

    for p in walk_dir(&path).unwrap() {
        let mut file = File::open(&p).unwrap();
        let body = Json::from_reader(&mut file).unwrap();

        let mut dec = json::Decoder::new(body);
        let bm: BlockModel = Decodable::decode(&mut dec).unwrap();

        // Use bm here

        n += 1;
    }

    println!("Read {} files.", n);
}

This thing, seems huge but it's mostly struct definitions, with optional fields mostly. It reads all files inside assets/minecraft/models/block (assuming they are inside src/bin/block and counts them.

Of course it lacks the real logic so it's not usable with the graphics code but still it's way easier to understand. Here is the real thing.

Let me know what you think.

@eddyb
Copy link
Contributor

eddyb commented Jan 22, 2015

I'm pretty sure Option only works with null turning into None, not missing fields (which I handle in NBT, differently than JSON).

@toqueteos
Copy link
Contributor Author

@eddyb Option does work with missing fields, 100% sure.

@eddyb
Copy link
Contributor

eddyb commented Jan 22, 2015

@toqueteos that must've changed since when I've written this.
I'll merge any cleanup based on this (awesome!) face - I think I never ended up using the NBT decoder - but that's mostly because there's a lot of bulk data which would be inefficiently treated by the decoder model (it's not streaming q_q).

@toqueteos
Copy link
Contributor Author

@eddyb I have already "ported" 2 of 3 JSON reader code sections.

EDIT: https://gist.github.com/toqueteos/caab6c807b558bbc2d7b

Also why it works now:

rust-lang/rust#12794
rust-lang/rust#16971

There's also this RFC, still pending, which provides same thing for streams which would be AWESOME: rust-lang/rfcs#22

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants