dotzuki_engine/overworld/
event_flags.rs1use std::collections::HashMap;
2
3#[derive(Debug, Clone)]
25#[non_exhaustive]
26pub struct EventFlags {
27 flags: HashMap<String, bool>,
28}
29
30impl Default for EventFlags {
31 fn default() -> Self {
32 Self::new()
33 }
34}
35
36impl EventFlags {
37 #[inline]
39 pub fn new() -> Self {
40 Self {
41 flags: HashMap::new(),
42 }
43 }
44
45 pub fn count_set(&self) -> u32 {
47 self.flags.values().filter(|&&v| v).count() as u32
48 }
49
50 pub fn clear_all(&mut self) {
52 self.flags.clear();
53 }
54
55 #[inline]
57 pub fn get_flag(&self, name: &str) -> bool {
58 self.flags.get(name).copied().unwrap_or(false)
59 }
60
61 #[inline]
63 pub fn set_flag(&mut self, name: &str, value: bool) {
64 self.flags.insert(name.to_owned(), value);
65 }
66
67 #[inline]
69 pub fn remove_flag(&mut self, name: &str) {
70 self.flags.remove(name);
71 }
72
73 pub fn iter(&self) -> impl Iterator<Item = (&String, &bool)> {
75 self.flags.iter()
76 }
77
78 pub fn as_hashmap(&self) -> &HashMap<String, bool> {
80 &self.flags
81 }
82
83 pub fn as_hashmap_mut(&mut self) -> &mut HashMap<String, bool> {
85 &mut self.flags
86 }
87
88 pub fn merge_from(&mut self, other: &HashMap<String, bool>) {
91 for (k, &v) in other {
92 self.flags.insert(k.clone(), v);
93 }
94 }
95
96 pub fn to_hashmap(&self) -> HashMap<String, bool> {
98 self.flags.clone()
99 }
100
101 pub fn from_hashmap(map: &HashMap<String, bool>) -> Self {
103 let mut ef = Self::new();
104 ef.merge_from(map);
105 ef
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112
113 #[test]
114 fn new_all_cleared() {
115 let flags = EventFlags::new();
116 assert_eq!(flags.count_set(), 0);
117 }
118
119 #[test]
120 fn default_same_as_new() {
121 let a = EventFlags::new();
122 let b = EventFlags::default();
123 assert_eq!(a.count_set(), b.count_set());
124 }
125
126 #[test]
127 fn set_and_get_flag() {
128 let mut flags = EventFlags::new();
129 assert!(!flags.get_flag("my_flag"));
130 flags.set_flag("my_flag", true);
131 assert!(flags.get_flag("my_flag"));
132 }
133
134 #[test]
135 fn remove_flag() {
136 let mut flags = EventFlags::new();
137 flags.set_flag("temp", true);
138 assert!(flags.get_flag("temp"));
139 flags.remove_flag("temp");
140 assert!(!flags.get_flag("temp"));
141 }
142
143 #[test]
144 fn clear_all() {
145 let mut flags = EventFlags::new();
146 flags.set_flag("a", true);
147 flags.set_flag("b", true);
148 flags.set_flag("c", true);
149 assert_eq!(flags.count_set(), 3);
150 flags.clear_all();
151 assert_eq!(flags.count_set(), 0);
152 }
153
154 #[test]
155 fn merge_from() {
156 let mut flags = EventFlags::new();
157 let mut other = HashMap::new();
158 other.insert("x".to_owned(), true);
159 other.insert("y".to_owned(), false);
160 flags.merge_from(&other);
161 assert!(flags.get_flag("x"));
162 assert!(!flags.get_flag("y"));
163 }
164
165 #[test]
166 fn from_hashmap_roundtrip() {
167 let mut map = HashMap::new();
168 map.insert("a".to_owned(), true);
169 map.insert("b".to_owned(), false);
170 let flags = EventFlags::from_hashmap(&map);
171 assert!(flags.get_flag("a"));
172 assert!(!flags.get_flag("b"));
173 assert_eq!(flags.to_hashmap(), map);
174 }
175
176 #[test]
177 fn iter_works() {
178 let mut flags = EventFlags::new();
179 flags.set_flag("a", true);
180 flags.set_flag("b", false);
181 let pairs: Vec<_> = flags.iter().collect();
182 assert_eq!(pairs.len(), 2);
183 }
184
185 #[test]
186 fn as_hashmap_mut_allows_modification() {
187 let mut flags = EventFlags::new();
188 flags.as_hashmap_mut().insert("direct".to_owned(), true);
189 assert!(flags.get_flag("direct"));
190 }
191
192 #[test]
193 fn non_exhaustive_allows_downstream_extension() {
194 let flags = EventFlags::new();
196 assert_eq!(flags.count_set(), 0);
197 }
198}