steel_core/worldgen/feature/
vanilla_collections.rs1use smallvec::SmallVec;
2
3use super::prelude::*;
4
5const INLINE_CAPACITY: usize = 32;
6
7#[derive(Default)]
13pub(super) struct JavaBlockPosSet {
14 entries: SmallVec<[BlockPos; INLINE_CAPACITY]>,
15}
16
17impl JavaBlockPosSet {
18 pub(super) fn insert(&mut self, pos: BlockPos) -> bool {
19 if self.entries.contains(&pos) {
20 return false;
21 }
22
23 self.entries.push(pos);
24 true
25 }
26
27 pub(super) fn contains(&self, pos: BlockPos) -> bool {
28 self.entries.contains(&pos)
29 }
30
31 pub(super) fn is_empty(&self) -> bool {
32 self.entries.is_empty()
33 }
34
35 pub(super) fn insertion_order(&self) -> impl Iterator<Item = &BlockPos> {
36 self.entries.iter()
37 }
38
39 pub(super) fn java_ordered_positions(&self) -> Vec<BlockPos> {
40 self.entries.to_vec()
41 }
42
43 pub(super) fn pop_java_ordered_position(&mut self) -> Option<BlockPos> {
44 if self.entries.is_empty() {
45 return None;
46 }
47
48 Some(self.entries.remove(0))
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn duplicate_positions_keep_first_insertion() {
58 let mut set = JavaBlockPosSet::default();
59 assert!(set.insert(BlockPos::new(1, 2, 3)));
60 assert!(!set.insert(BlockPos::new(1, 2, 3)));
61 assert_eq!(set.java_ordered_positions(), [BlockPos::new(1, 2, 3)]);
62 }
63
64 #[test]
65 fn popped_positions_do_not_iterate() {
66 let mut set = JavaBlockPosSet::default();
67 for x in 0..4 {
68 assert!(set.insert(BlockPos::new(x, 0, 0)));
69 }
70
71 assert_eq!(
72 set.pop_java_ordered_position(),
73 Some(BlockPos::new(0, 0, 0))
74 );
75
76 assert_eq!(
77 set.java_ordered_positions(),
78 [
79 BlockPos::new(1, 0, 0),
80 BlockPos::new(2, 0, 0),
81 BlockPos::new(3, 0, 0)
82 ]
83 );
84 }
85
86 #[test]
87 fn reinserted_position_uses_new_insertion_position() {
88 let mut set = JavaBlockPosSet::default();
89 let first = BlockPos::new(1, 0, 0);
90 let second = BlockPos::new(17, 0, 0);
91
92 assert!(set.insert(first));
93 assert!(set.insert(second));
94 assert_eq!(set.pop_java_ordered_position(), Some(first));
95 assert!(set.insert(first));
96
97 assert_eq!(set.java_ordered_positions(), [second, first]);
98 }
99
100 #[test]
101 fn pop_uses_insertion_order() {
102 let mut set = JavaBlockPosSet::default();
103 let first = BlockPos::new(1, 0, 0);
104 let second = BlockPos::new(2, 0, 0);
105 assert!(set.insert(first));
106 assert!(set.insert(second));
107
108 assert_eq!(set.pop_java_ordered_position(), Some(first));
109 assert_eq!(set.pop_java_ordered_position(), Some(second));
110 assert_eq!(set.pop_java_ordered_position(), None);
111 }
112}