Skip to content
This repository was archived by the owner on May 10, 2023. It is now read-only.

Commit 8a7ab29

Browse files
authored
Merge pull request #40 from yellowcake-org/feature/core-58-performance-improvements
CORE-58: Performance improvements.
2 parents 6ac5de3 + 0113933 commit 8a7ab29

File tree

4 files changed

+105
-84
lines changed

4 files changed

+105
-84
lines changed

examples/mapview/main.rs

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::collections::HashMap;
12
use std::fs::File;
23
use std::io::BufWriter;
34

@@ -9,9 +10,13 @@ use cli::export::elevation;
910
use cli::export::filter::{Filter, Layers};
1011
use libycresources::common::types::geometry::Scaled;
1112
use libycresources::common::types::space;
12-
use libycresources::formats::map;
13+
use libycresources::formats::{map, pal};
14+
use libycresources::formats::map::blueprint::prototype::Instance;
15+
use libycresources::formats::map::tiles::Group;
1316
use provider::CommonProvider;
1417

18+
use crate::cli::export::darkness::Darkness;
19+
1520
mod print;
1621
mod render;
1722
mod provider;
@@ -69,17 +74,75 @@ fn main() {
6974
if export.darkness.as_ref().is_some() { println!("Darkness customization has been applied."); }
7075
if export.elevation.as_ref().is_some() { println!("Provided elevation will be rendered only."); }
7176

72-
for level in levels {
73-
let level_readable = level + 1;
74-
let elevation = space::Elevation { level: Scaled { value: level, scale: 0..MAX_ELEVATION + 1 } };
77+
let default = match u8::try_from(map.darkness) {
78+
Ok(value) => value,
79+
Err(error) => {
80+
return eprintln!("Map darkness value is out of range. Error: {:?}", error);
81+
}
82+
};
83+
84+
let darkness = export.darkness.map_or(
85+
default,
86+
|d| {
87+
match d {
88+
Darkness::None => 1,
89+
Darkness::Night => 2,
90+
Darkness::Dusk => 3,
91+
Darkness::Day => 4,
92+
}
93+
},
94+
);
95+
96+
println!("Loading common palette...");
97+
98+
let file = match File::open(&options.resources.join("COLOR.PAL")) {
99+
Err(error) => { return eprintln!("Failed to open main palette's file. Error: {:?}.", error); }
100+
Ok(value) => value
101+
};
102+
103+
let mut reader = std::io::BufReader::with_capacity(1 * 1024 * 1024, file);
104+
let palette = match pal::parse::palette(&mut reader) {
105+
Err(error) => { return eprintln!("Failed to parse main palette. Error: {:?}.", error); }
106+
Ok(value) => value
107+
};
108+
109+
println!("Success.");
110+
111+
let mut tiles = HashMap::new();
112+
for group in &map.tiles { tiles.insert(&group.elevation, group); }
113+
114+
let mut protos: HashMap<&space::Elevation, Vec<&Instance>> = HashMap::new();
115+
for proto in &map.prototypes {
116+
if let Some(grid) = &proto.location.grid {
117+
if let Some(protos) = protos.get_mut(&grid.elevation) {
118+
protos.push(&proto);
119+
} else {
120+
let mut list = Vec::new();
121+
list.push(proto);
122+
123+
protos.insert(&grid.elevation, list);
124+
}
125+
}
126+
}
127+
128+
let drawables: Vec<(space::Elevation, &&Group, Option<&Vec<&Instance>>)> = levels.map(
129+
|l| space::Elevation { level: Scaled { value: l, scale: 0..MAX_ELEVATION + 1 } }
130+
).map(|e| {
131+
let protos = protos.get(&e);
132+
tiles.get(&e).map(|t| (e, t, protos))
133+
}).flatten().collect();
134+
135+
for (elevation, tiles, protos) in drawables {
136+
let level_readable = elevation.level.value + 1;
75137

76138
println!("Started rendering level {:?}...", level_readable);
77139
let result = render::map(
78-
&map, &filter,
79-
export.darkness.as_ref(),
80-
&elevation,
140+
&tiles,
141+
protos,
142+
&filter,
143+
darkness,
81144
&provider,
82-
&options.resources,
145+
&palette,
83146
);
84147

85148
let image = match result {

examples/mapview/provider/suffix.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub(crate) fn detect(weapon: &Option<weapon::Animation>, animation: &critter::An
1515
Some(weapon::Animation::BigGun) => 8,
1616
Some(weapon::Animation::Minigun) => 9,
1717
Some(weapon::Animation::RocketLauncher) => 10,
18-
}) as char
18+
}) as char;
1919
}
2020

2121
fn a_char(a: &critter::Animation) -> char {

examples/mapview/render.rs

Lines changed: 33 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
use std::fs::File;
2-
use std::path::PathBuf;
3-
41
use item::Instance;
5-
use libycresources::common::types::space::Elevation;
6-
use libycresources::formats::{map, pal};
7-
use libycresources::formats::map::blueprint;
2+
use libycresources::formats::map;
3+
use libycresources::formats::map::tiles::Group;
4+
use libycresources::formats::pal::Palette;
85
use libycresources::formats::pro::meta::info::flags::Root::Flat;
96

10-
use crate::cli::export::darkness::Darkness;
117
use crate::cli::export::filter::Layers;
128
use crate::error::Error;
139
use crate::traits::render::Provider;
@@ -21,37 +17,13 @@ mod sprite;
2117
mod grid;
2218

2319
pub(crate) fn map<'a, P: Provider>(
24-
map: &'a map::Map,
20+
tiles: &'a Group,
21+
protos: Option<&Vec<&map::blueprint::prototype::Instance>>,
2522
layers: &Layers,
26-
darkness: Option<&Darkness>,
27-
elevation: &Elevation,
23+
darkness: u8,
2824
provider: &P,
29-
resources: &PathBuf,
25+
palette: &Palette,
3026
) -> Result<Option<(Vec<(u8, u8, u8)>, (usize, usize))>, Error<'a>> {
31-
let default = u8::try_from(map.darkness)
32-
.map_err(|_| Error::Corrupted("Map darkness value is out of range."))?;
33-
34-
let darkness = darkness.map_or(
35-
default,
36-
|d| {
37-
match d {
38-
Darkness::None => 1,
39-
Darkness::Night => 2,
40-
Darkness::Dusk => 3,
41-
Darkness::Day => 4,
42-
}
43-
},
44-
);
45-
46-
let tiles = map.tiles
47-
.iter()
48-
.find(|e| { &e.elevation == elevation });
49-
50-
let tiles = match tiles {
51-
None => return Ok(None),
52-
Some(value) => value
53-
};
54-
5527
let floors: Vec<Instance> = tiles::convert(&tiles.floor, provider)?;
5628
let ceilings: Vec<Instance> = tiles::convert(&tiles.ceiling, provider)?;
5729

@@ -66,51 +38,41 @@ pub(crate) fn map<'a, P: Provider>(
6638
let mut pixels = vec![(u8::MIN, u8::MIN, u8::MIN); w * h];
6739
let mut image = (&mut pixels, (w, h));
6840

69-
let file = File::open(&resources.join("COLOR.PAL"))
70-
.map_err(|io| Error::IO(io, "Failed to load main palette."))?;
71-
72-
let mut reader = std::io::BufReader::with_capacity(1 * 1024 * 1024, file);
73-
let palette = pal::parse::palette(&mut reader)
74-
.map_err(|i| Error::Internal(i, "Failed to parse main palette."))?;
75-
7641
if layers.floor || layers.all() {
7742
println!("Rendering floor...");
78-
tiles::imprint(&floors, false, &palette, darkness, &mut image)?;
43+
tiles::imprint(&floors, false, palette, darkness, &mut image)?;
7944
}
8045

8146
if layers.overlay || layers.all() {
8247
println!("Rendering hexagonal tiles' overlay...");
8348
hexes::overlay(&mut image)?;
8449
}
8550

86-
println!("Rendering prototypes...");
87-
let flat: Vec<&blueprint::prototype::Instance> = map.prototypes.iter()
88-
.filter(|p| p.patch.meta.flags.contains(&Flat)).collect();
89-
90-
let other: Vec<&blueprint::prototype::Instance> = map.prototypes.iter()
91-
.filter(|p| !p.patch.meta.flags.contains(&Flat)).collect();
92-
93-
protos::imprint(
94-
&flat,
95-
provider,
96-
&elevation,
97-
&palette,
98-
darkness,
99-
&layers,
100-
(tw, th),
101-
&mut image,
102-
)?;
103-
104-
protos::imprint(
105-
&other,
106-
provider,
107-
&elevation,
108-
&palette,
109-
darkness,
110-
&layers,
111-
(tw, th),
112-
&mut image,
113-
)?;
51+
if let Some(protos) = protos {
52+
println!("Rendering prototypes...");
53+
let (flat, normal) = protos.iter()
54+
.partition(|p| p.patch.meta.flags.contains(&Flat));
55+
56+
protos::imprint(
57+
&flat,
58+
provider,
59+
&palette,
60+
darkness,
61+
&layers,
62+
(tw, th),
63+
&mut image,
64+
)?;
65+
66+
protos::imprint(
67+
&normal,
68+
provider,
69+
&palette,
70+
darkness,
71+
&layers,
72+
(tw, th),
73+
&mut image,
74+
)?;
75+
}
11476

11577
if layers.roof || layers.all() {
11678
println!("Rendering roofs...");

examples/mapview/render/protos.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::collections::HashMap;
22

3-
use libycresources::common::types::space::Elevation;
43
use libycresources::formats::{pal, pro};
54
use libycresources::formats::map::blueprint;
65
use libycresources::formats::pro::Type::{Critter, Item, Misc, Scenery, Tile, Wall};
@@ -13,7 +12,6 @@ use crate::traits::render::Provider;
1312
pub(crate) fn imprint<'a, P: Provider>(
1413
protos: &Vec<&blueprint::prototype::Instance>,
1514
provider: &P,
16-
elevation: &Elevation,
1715
palette: &pal::Palette,
1816
darkness: u8,
1917
layers: &Layers,
@@ -69,8 +67,6 @@ pub(crate) fn imprint<'a, P: Provider>(
6967
&proto.location.grid,
7068
&proto.location.screen.correction
7169
) {
72-
if &location.elevation != elevation { continue; }
73-
7470
let identifier = &proto.appearance.sprite;
7571
let item = provider.provide(&identifier)?;
7672

0 commit comments

Comments
 (0)