~starkingdoms/starkingdoms

ref: f2b1d8d9e668bf26f21edea15a6b8ce449b50016 starkingdoms/spacetime_rs/src/configure/asset.rs -rw-r--r-- 7.2 KiB
f2b1d8d9 — core fix non-api compilation 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use std::collections::HashMap;
use std::error::Error;
use std::fs;
use std::fs::File;
use std::path::PathBuf;
use crate::config::{ASSET_DIR, ASSETS_DIST_SUBDIR, ASSETS_FINAL_SUBDIR, ASSETS_SRC_SUBDIR};
use crate::ninja::NinjaWriter;

pub fn configure_assets(writer: &mut NinjaWriter<File>, root: &PathBuf) -> Result<(), Box<dyn Error>> {
    // scan for assets
    let asset_src_dir = root.join(ASSET_DIR).join(ASSETS_SRC_SUBDIR);

    let mut found_assets = vec![];

    let files_in_src_dir = fs::read_dir(asset_src_dir)?;
    for maybe_asset in files_in_src_dir {
        let maybe_asset = maybe_asset?;
        if maybe_asset.file_name().to_str().unwrap().ends_with(".svg") {
            found_assets.push(maybe_asset.path());
        }
    }

    println!("[spacetime] asset scan: found {} assets", found_assets.len());

    let default_asset_size = 512;
    let asset_overrides = HashMap::from([
        ("earth.ink.svg", 2048),
        ("moon.ink.svg", 2048)
    ]);

    // generate an inkscape rule for all required asset sizes
    let mut written_rules_for = vec![];

    gen_inkscape_rule(default_asset_size, writer, &mut written_rules_for)?;

    for size in asset_overrides.values() {
        gen_inkscape_rule(*size, writer, &mut written_rules_for)?;
    }

    println!("[spacetime] generated {} image conversion rules", written_rules_for.len() * 3);

    let mut files_375 = vec![];
    let mut files_125 = vec![];
    let mut files_full = vec![];

    for asset in &found_assets {
        gen_convert_rule(asset, root, writer, &mut files_375, &mut files_full, &mut files_125, asset_size(asset.to_str().unwrap(), &asset_overrides, default_asset_size))?;
    }

    println!("[spacetime] generated {} image conversion steps", files_full.len() + files_125.len() + files_375.len());

    gen_packer_rule(root, writer, &files_375, &files_full, &files_125)?;

    println!("[spacetime] generated asset build commands");

    Ok(())
}

fn gen_packer_rule(root: &PathBuf, writer: &mut NinjaWriter<File>, files_375: &Vec<PathBuf>, files_full: &Vec<PathBuf>, files_125: &Vec<PathBuf>) -> Result<(), Box<dyn Error>> {
    writer.rule("pack", &format!("cd {} && atlasify -m 4096,4096 -o $out $in && touch $out", root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).to_string_lossy()), None, None, None, Some("console"), None, None, None, None)?;

    writer.build(vec![root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).join("spritesheet-full").to_str().unwrap().to_string()], "pack".to_string(), files_full.iter().map(|u| u.to_str().unwrap().to_string()).collect(), vec![], vec![], HashMap::new(), vec![root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).join("spritesheet-full.json").to_str().unwrap().to_string(), root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).join("spritesheet-full.png").to_str().unwrap().to_string()], None, None)?;
    writer.build(vec!["asset-full".to_string()], "phony".to_string(), vec![root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).join("spritesheet-full").to_str().unwrap().to_string()], vec![], vec![], HashMap::new(), vec![], None, None)?;

    writer.build(vec![root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).join("spritesheet-125").to_str().unwrap().to_string()], "pack".to_string(), files_125.iter().map(|u| u.to_str().unwrap().to_string()).collect(), vec![], vec![], HashMap::new(), vec![root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).join("spritesheet-125.json").to_str().unwrap().to_string(), root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).join("spritesheet-125.png").to_str().unwrap().to_string()], None, None)?;
    writer.build(vec!["asset-125".to_string()], "phony".to_string(), vec![root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).join("spritesheet-125").to_str().unwrap().to_string()], vec![], vec![], HashMap::new(), vec![], None, None)?;

    writer.build(vec![root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).join("spritesheet-375").to_str().unwrap().to_string()], "pack".to_string(), files_375.iter().map(|u| u.to_str().unwrap().to_string()).collect(), vec![], vec![], HashMap::new(), vec![root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).join("spritesheet-375.json").to_str().unwrap().to_string(), root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).join("spritesheet-375.png").to_str().unwrap().to_string()], None, None)?;
    writer.build(vec!["asset-375".to_string()], "phony".to_string(), vec![root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).join("spritesheet-375").to_str().unwrap().to_string()], vec![], vec![], HashMap::new(), vec![], None, None)?;

    writer.build(vec!["asset".to_string()], "phony".to_string(), vec![root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).join("spritesheet-375").to_str().unwrap().to_string(), root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).join("spritesheet-full").to_str().unwrap().to_string(), root.join(ASSET_DIR).join(ASSETS_DIST_SUBDIR).join("spritesheet-125").to_str().unwrap().to_string()], vec![], vec![], HashMap::new(), vec![], None, None)?;


    Ok(())
}

fn gen_convert_rule(asset: &PathBuf, root: &PathBuf, writer: &mut NinjaWriter<File>, files_375: &mut Vec<PathBuf>, files_full: &mut Vec<PathBuf>, files_125: &mut Vec<PathBuf>, size: i32) -> Result<(), Box<dyn Error>> {
    let out_full = root.join(ASSET_DIR).join(ASSETS_FINAL_SUBDIR).join("full/").join(asset.file_stem().unwrap().to_str().unwrap().to_string() + ".png");
    files_full.push(out_full.clone());
    let rule_full = format!("inkscape_{}_px_full", size);
    writer.build(vec![out_full.to_str().unwrap().to_string()], rule_full, vec![asset.to_str().unwrap().to_string()], vec![], vec![], HashMap::new(), vec![], None, None)?;

    let out_375 = root.join(ASSET_DIR).join(ASSETS_FINAL_SUBDIR).join("375/").join(asset.file_stem().unwrap().to_str().unwrap().to_string() + ".png");
    files_375.push(out_375.clone());
    let rule_375 = format!("inkscape_{}_px_375", size);
    writer.build(vec![out_375.to_str().unwrap().to_string()], rule_375, vec![asset.to_str().unwrap().to_string()], vec![], vec![], HashMap::new(), vec![], None, None)?;

    let out_125 = root.join(ASSET_DIR).join(ASSETS_FINAL_SUBDIR).join("125/").join(asset.file_stem().unwrap().to_str().unwrap().to_string() + ".png");
    files_125.push(out_125.clone());
    let rule_125 = format!("inkscape_{}_px_125", size);
    writer.build(vec![out_125.to_str().unwrap().to_string()], rule_125, vec![asset.to_str().unwrap().to_string()], vec![], vec![], HashMap::new(), vec![], None, None)?;

    Ok(())
}

fn asset_size(asset: &str, overrides: &HashMap<&str, i32>, default: i32) -> i32 {
    *overrides.get(asset).unwrap_or(&default)
}

fn gen_inkscape_rule(size: i32, writer: &mut NinjaWriter<File>, written: &mut Vec<i32>) -> Result<(), Box<dyn Error>> {
    if written.contains(&size) {
        return Ok(())
    }

    writer.rule(&format!("inkscape_{}_px_full", size), &format!("inkscape -w {} -h {} $in -o $out", size, size), None, None, None, None, None, None, None, None)?;
    writer.rule(&format!("inkscape_{}_px_375", size), &format!("inkscape -w {} -h {} $in -o $out", (size as f64 * 0.375) as i32, (size as f64 * 0.375) as i32), None, None, None, None, None, None, None, None)?;
    writer.rule(&format!("inkscape_{}_px_125", size), &format!("inkscape -w {} -h {} $in -o $out", (size as f64 * 0.125) as i32, (size as f64 * 0.125) as i32), None, None, None, None, None, None, None, None)?;

    written.push(size);

    Ok(())
}