oxihuman_core/
action_map.rs1#![allow(dead_code)]
4
5#[allow(dead_code)]
10#[derive(Debug, Clone)]
11pub struct ActionMap {
12 entries: Vec<ActionEntry>,
13 enabled: bool,
14}
15
16#[allow(dead_code)]
17#[derive(Debug, Clone)]
18pub struct ActionEntry {
19 pub name: String,
20 pub category: String,
21 pub priority: u32,
22 pub enabled: bool,
23}
24
25impl Default for ActionMap {
26 fn default() -> Self {
27 Self::new()
28 }
29}
30
31#[allow(dead_code)]
32impl ActionMap {
33 pub fn new() -> Self {
34 Self {
35 entries: Vec::new(),
36 enabled: true,
37 }
38 }
39
40 pub fn register(&mut self, name: &str, category: &str, priority: u32) -> bool {
41 if self.entries.iter().any(|e| e.name == name) {
42 return false;
43 }
44 self.entries.push(ActionEntry {
45 name: name.to_string(),
46 category: category.to_string(),
47 priority,
48 enabled: true,
49 });
50 true
51 }
52
53 pub fn unregister(&mut self, name: &str) -> bool {
54 let before = self.entries.len();
55 self.entries.retain(|e| e.name != name);
56 self.entries.len() < before
57 }
58
59 pub fn get(&self, name: &str) -> Option<&ActionEntry> {
60 self.entries.iter().find(|e| e.name == name)
61 }
62
63 pub fn contains(&self, name: &str) -> bool {
64 self.entries.iter().any(|e| e.name == name)
65 }
66
67 pub fn set_enabled(&mut self, name: &str, enabled: bool) -> bool {
68 if let Some(entry) = self.entries.iter_mut().find(|e| e.name == name) {
69 entry.enabled = enabled;
70 true
71 } else {
72 false
73 }
74 }
75
76 pub fn is_enabled(&self, name: &str) -> bool {
77 self.entries
78 .iter()
79 .find(|e| e.name == name)
80 .is_some_and(|e| e.enabled)
81 }
82
83 pub fn count(&self) -> usize {
84 self.entries.len()
85 }
86
87 pub fn by_category(&self, category: &str) -> Vec<&ActionEntry> {
88 self.entries
89 .iter()
90 .filter(|e| e.category == category)
91 .collect()
92 }
93
94 pub fn by_priority(&self) -> Vec<&ActionEntry> {
95 let mut sorted: Vec<&ActionEntry> = self.entries.iter().collect();
96 sorted.sort_by(|a, b| b.priority.cmp(&a.priority));
97 sorted
98 }
99
100 pub fn categories(&self) -> Vec<String> {
101 let mut cats: Vec<String> = self.entries.iter().map(|e| e.category.clone()).collect();
102 cats.sort();
103 cats.dedup();
104 cats
105 }
106
107 pub fn enabled_count(&self) -> usize {
108 self.entries.iter().filter(|e| e.enabled).count()
109 }
110
111 pub fn clear(&mut self) {
112 self.entries.clear();
113 }
114
115 pub fn names(&self) -> Vec<&str> {
116 self.entries.iter().map(|e| e.name.as_str()).collect()
117 }
118
119 pub fn set_global_enabled(&mut self, enabled: bool) {
120 self.enabled = enabled;
121 }
122
123 pub fn is_global_enabled(&self) -> bool {
124 self.enabled
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131
132 #[test]
133 fn test_new_empty() {
134 let map = ActionMap::new();
135 assert_eq!(map.count(), 0);
136 assert!(map.is_global_enabled());
137 }
138
139 #[test]
140 fn test_register_and_get() {
141 let mut map = ActionMap::new();
142 assert!(map.register("jump", "movement", 10));
143 assert!(map.contains("jump"));
144 let entry = map.get("jump").expect("should succeed");
145 assert_eq!(entry.category, "movement");
146 assert_eq!(entry.priority, 10);
147 }
148
149 #[test]
150 fn test_duplicate_register() {
151 let mut map = ActionMap::new();
152 assert!(map.register("fire", "combat", 5));
153 assert!(!map.register("fire", "combat", 5));
154 }
155
156 #[test]
157 fn test_unregister() {
158 let mut map = ActionMap::new();
159 map.register("run", "movement", 1);
160 assert!(map.unregister("run"));
161 assert!(!map.contains("run"));
162 assert!(!map.unregister("run"));
163 }
164
165 #[test]
166 fn test_enable_disable() {
167 let mut map = ActionMap::new();
168 map.register("crouch", "movement", 2);
169 assert!(map.is_enabled("crouch"));
170 map.set_enabled("crouch", false);
171 assert!(!map.is_enabled("crouch"));
172 }
173
174 #[test]
175 fn test_by_category() {
176 let mut map = ActionMap::new();
177 map.register("jump", "movement", 10);
178 map.register("fire", "combat", 5);
179 map.register("run", "movement", 8);
180 assert_eq!(map.by_category("movement").len(), 2);
181 assert_eq!(map.by_category("combat").len(), 1);
182 }
183
184 #[test]
185 fn test_by_priority() {
186 let mut map = ActionMap::new();
187 map.register("a", "cat", 1);
188 map.register("b", "cat", 10);
189 map.register("c", "cat", 5);
190 let sorted = map.by_priority();
191 assert_eq!(sorted[0].name, "b");
192 assert_eq!(sorted[2].name, "a");
193 }
194
195 #[test]
196 fn test_categories() {
197 let mut map = ActionMap::new();
198 map.register("a", "x", 1);
199 map.register("b", "y", 2);
200 map.register("c", "x", 3);
201 let cats = map.categories();
202 assert_eq!(cats.len(), 2);
203 }
204
205 #[test]
206 fn test_clear() {
207 let mut map = ActionMap::new();
208 map.register("a", "b", 1);
209 map.clear();
210 assert_eq!(map.count(), 0);
211 }
212
213 #[test]
214 fn test_enabled_count() {
215 let mut map = ActionMap::new();
216 map.register("a", "c", 1);
217 map.register("b", "c", 2);
218 map.set_enabled("b", false);
219 assert_eq!(map.enabled_count(), 1);
220 }
221}