fastanvil/java/
section_tower.rs1use serde::Deserialize;
2
3use crate::SectionLike;
4
5#[derive(Debug)]
9pub struct SectionTower<S> {
10 sections: Vec<S>,
11 map: Vec<Option<usize>>,
12 y_min: isize,
13 y_max: isize,
14}
15
16impl<S> SectionTower<S> {
17 pub fn sections(&self) -> &[S] {
18 &self.sections
19 }
20
21 pub(crate) fn take_sections(self) -> Vec<S> {
22 self.sections
23 }
24
25 pub fn get_section_for_y(&self, y: isize) -> Option<&S> {
26 if y >= self.y_max || y < self.y_min {
27 return None;
30 }
31
32 let lookup_index = y_to_index(y, self.y_min);
33
34 let section_index = *self.map.get(lookup_index as usize)?;
35 self.sections.get(section_index?)
36 }
37
38 pub fn y_min(&self) -> isize {
39 self.y_min
40 }
41
42 pub fn y_max(&self) -> isize {
43 self.y_max
44 }
45}
46
47impl<'de, S: SectionLike + Deserialize<'de>> Deserialize<'de> for SectionTower<S> {
48 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
49 where
50 D: serde::Deserializer<'de>,
51 {
52 let sections: Vec<S> = Deserialize::deserialize(deserializer)?;
53 if sections.is_empty() {
54 return Ok(Self {
55 sections,
56 map: vec![],
57 y_min: 0,
58 y_max: 0,
59 });
60 }
61
62 let lowest_section = sections
67 .iter()
68 .min_by_key(|s| s.y())
69 .expect("checked no empty above");
70
71 let null_term = lowest_section.is_terminator();
76
77 let min = if null_term {
78 lowest_section.y() as isize + 1
79 } else {
80 lowest_section.y() as isize
81 };
82 let max = sections
83 .iter()
84 .max_by_key(|s| s.y())
85 .map(|s| s.y())
86 .unwrap() as isize;
87
88 let mut sparse_sections = vec![None; (1 + max - min) as usize];
89
90 for (i, sec) in sections.iter().enumerate() {
91 if sec.y() == lowest_section.y() && null_term {
93 continue;
94 }
95
96 let sec_index = (sec.y() as isize - min) as usize;
97
98 sparse_sections[sec_index] = Some(i);
99 }
100
101 Ok(Self {
102 sections,
103 map: sparse_sections,
104 y_min: 16 * min,
105 y_max: 16 * (max + 1),
106 })
107 }
108}
109
110const fn y_to_index(y: isize, y_min: isize) -> u8 {
111 ((y - y_min) >> 4) as u8
112}