emergent/decision_makers/
selector.rs1use crate::{condition::*, decision_makers::*, task::*};
4
5pub struct SelectorState<M = ()> {
7 condition: Box<dyn Condition<M>>,
8 task: Box<dyn Task<M>>,
9}
10
11impl<M> SelectorState<M> {
12 pub fn new<C, T>(condition: C, task: T) -> Self
14 where
15 C: Condition<M> + 'static,
16 T: Task<M> + 'static,
17 {
18 Self {
19 condition: Box::new(condition),
20 task: Box::new(task),
21 }
22 }
23
24 pub fn new_raw(condition: Box<dyn Condition<M>>, task: Box<dyn Task<M>>) -> Self {
26 Self { condition, task }
27 }
28}
29
30impl<M> std::fmt::Debug for SelectorState<M> {
31 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32 f.debug_struct("SelectorState").finish()
33 }
34}
35
36pub struct Selector<M = ()> {
71 states: Vec<SelectorState<M>>,
72 active_index: Option<usize>,
73}
74
75impl<M> Selector<M> {
76 pub fn new(states: Vec<SelectorState<M>>) -> Self {
78 Self {
79 states,
80 active_index: None,
81 }
82 }
83
84 pub fn new_raw(states: Vec<SelectorState<M>>) -> Self {
86 Self {
87 states,
88 active_index: None,
89 }
90 }
91
92 pub fn active_index(&self) -> Option<usize> {
94 self.active_index
95 }
96
97 pub fn reset(&mut self, memory: &mut M, forced: bool) -> bool {
101 if let Some(index) = self.active_index {
102 let state = self.states.get_mut(index).unwrap();
103 if !forced && state.task.is_locked(memory) {
104 return false;
105 }
106 state.task.on_exit(memory);
107 self.active_index = None;
108 }
109 true
110 }
111
112 fn change_active_index(&mut self, index: Option<usize>, memory: &mut M) -> bool {
113 if index == self.active_index {
114 return false;
115 }
116 if let Some(index) = self.active_index {
117 let state = self.states.get_mut(index).unwrap();
118 if state.task.is_locked(memory) {
119 return false;
120 }
121 state.task.on_exit(memory);
122 }
123 if let Some(index) = index {
124 self.states.get_mut(index).unwrap().task.on_enter(memory);
125 }
126 self.active_index = index;
127 true
128 }
129
130 pub fn process(&mut self, memory: &mut M) -> bool {
132 if self.states.is_empty() {
133 return false;
134 }
135 let index = self
136 .states
137 .iter()
138 .position(|state| state.condition.validate(memory));
139 if self.change_active_index(index, memory) {
140 return true;
141 }
142 if let Some(index) = self.active_index {
143 return self.states.get_mut(index).unwrap().task.on_process(memory);
144 }
145 false
146 }
147
148 pub fn update(&mut self, memory: &mut M) {
150 if let Some(index) = self.active_index {
151 self.states.get_mut(index).unwrap().task.on_update(memory);
152 }
153 }
154}
155
156impl<M, K> DecisionMaker<M, K> for Selector<M>
157where
158 K: Default,
159{
160 fn decide(&mut self, memory: &mut M) -> Option<K> {
161 self.process(memory);
162 Some(K::default())
163 }
164
165 fn change_mind(&mut self, _: Option<K>, memory: &mut M) -> bool {
166 self.reset(memory, true)
167 }
168}
169
170impl<M> Task<M> for Selector<M> {
171 fn is_locked(&self, memory: &M) -> bool {
172 if let Some(index) = self.active_index {
173 if let Some(state) = self.states.get(index) {
174 return state.task.is_locked(memory);
175 }
176 }
177 false
178 }
179
180 fn on_enter(&mut self, memory: &mut M) {
181 self.reset(memory, true);
182 self.process(memory);
183 }
184
185 fn on_exit(&mut self, memory: &mut M) {
186 self.reset(memory, true);
187 }
188
189 fn on_update(&mut self, memory: &mut M) {
190 self.update(memory);
191 }
192
193 fn on_process(&mut self, memory: &mut M) -> bool {
194 self.process(memory)
195 }
196}
197
198impl<M> std::fmt::Debug for Selector<M> {
199 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
200 f.debug_struct("Selector")
201 .field("states", &self.states)
202 .field("active_index", &self.active_index)
203 .finish()
204 }
205}