1use crate::dispatch::DispatchStrategy;
8use crate::events::EventBus;
9use crate::hooks::Phase;
10use crate::ids::GroupId;
11use crate::metrics::Metrics;
12use crate::systems::PhaseContext;
13use std::collections::BTreeMap;
14
15impl super::Simulation {
16 #[must_use]
20 pub fn dispatchers(&self) -> &BTreeMap<GroupId, Box<dyn DispatchStrategy>> {
21 &self.dispatchers
22 }
23
24 pub fn dispatchers_mut(&mut self) -> &mut BTreeMap<GroupId, Box<dyn DispatchStrategy>> {
26 &mut self.dispatchers
27 }
28
29 pub const fn events_mut(&mut self) -> &mut EventBus {
31 &mut self.events
32 }
33
34 pub const fn metrics_mut(&mut self) -> &mut Metrics {
36 &mut self.metrics
37 }
38
39 #[must_use]
41 pub const fn phase_context(&self) -> PhaseContext {
42 PhaseContext {
43 tick: self.tick,
44 dt: self.dt,
45 }
46 }
47
48 pub fn run_advance_transient(&mut self) {
68 self.tick_in_progress = true;
69 self.hooks
70 .run_before(Phase::AdvanceTransient, &mut self.world);
71 for group in &self.groups {
72 self.hooks
73 .run_before_group(Phase::AdvanceTransient, group.id(), &mut self.world);
74 }
75 let ctx = self.phase_context();
76 crate::systems::advance_transient::run(
77 &mut self.world,
78 &mut self.events,
79 &ctx,
80 &mut self.rider_index,
81 );
82 for group in &self.groups {
83 self.hooks
84 .run_after_group(Phase::AdvanceTransient, group.id(), &mut self.world);
85 }
86 self.hooks
87 .run_after(Phase::AdvanceTransient, &mut self.world);
88 }
89
90 pub fn run_dispatch(&mut self) {
92 self.hooks.run_before(Phase::Dispatch, &mut self.world);
93 for group in &self.groups {
94 self.hooks
95 .run_before_group(Phase::Dispatch, group.id(), &mut self.world);
96 }
97 let ctx = self.phase_context();
98 crate::systems::dispatch::run(
99 &mut self.world,
100 &mut self.events,
101 &ctx,
102 &self.groups,
103 &mut self.dispatchers,
104 &self.rider_index,
105 );
106 for group in &self.groups {
107 self.hooks
108 .run_after_group(Phase::Dispatch, group.id(), &mut self.world);
109 }
110 self.hooks.run_after(Phase::Dispatch, &mut self.world);
111 }
112
113 pub fn run_movement(&mut self) {
115 self.hooks.run_before(Phase::Movement, &mut self.world);
116 for group in &self.groups {
117 self.hooks
118 .run_before_group(Phase::Movement, group.id(), &mut self.world);
119 }
120 let ctx = self.phase_context();
121 self.world.elevator_ids_into(&mut self.elevator_ids_buf);
122 crate::systems::movement::run(
123 &mut self.world,
124 &mut self.events,
125 &ctx,
126 &self.elevator_ids_buf,
127 &mut self.metrics,
128 );
129 for group in &self.groups {
130 self.hooks
131 .run_after_group(Phase::Movement, group.id(), &mut self.world);
132 }
133 self.hooks.run_after(Phase::Movement, &mut self.world);
134 }
135
136 pub fn run_doors(&mut self) {
138 self.hooks.run_before(Phase::Doors, &mut self.world);
139 for group in &self.groups {
140 self.hooks
141 .run_before_group(Phase::Doors, group.id(), &mut self.world);
142 }
143 let ctx = self.phase_context();
144 self.world.elevator_ids_into(&mut self.elevator_ids_buf);
145 crate::systems::doors::run(
146 &mut self.world,
147 &mut self.events,
148 &ctx,
149 &self.elevator_ids_buf,
150 );
151 for group in &self.groups {
152 self.hooks
153 .run_after_group(Phase::Doors, group.id(), &mut self.world);
154 }
155 self.hooks.run_after(Phase::Doors, &mut self.world);
156 }
157
158 pub fn run_loading(&mut self) {
160 self.hooks.run_before(Phase::Loading, &mut self.world);
161 for group in &self.groups {
162 self.hooks
163 .run_before_group(Phase::Loading, group.id(), &mut self.world);
164 }
165 let ctx = self.phase_context();
166 self.world.elevator_ids_into(&mut self.elevator_ids_buf);
167 crate::systems::loading::run(
168 &mut self.world,
169 &mut self.events,
170 &ctx,
171 &self.elevator_ids_buf,
172 &mut self.rider_index,
173 );
174 for group in &self.groups {
175 self.hooks
176 .run_after_group(Phase::Loading, group.id(), &mut self.world);
177 }
178 self.hooks.run_after(Phase::Loading, &mut self.world);
179 }
180
181 pub fn run_advance_queue(&mut self) {
187 self.hooks.run_before(Phase::AdvanceQueue, &mut self.world);
188 for group in &self.groups {
189 self.hooks
190 .run_before_group(Phase::AdvanceQueue, group.id(), &mut self.world);
191 }
192 let ctx = self.phase_context();
193 self.world.elevator_ids_into(&mut self.elevator_ids_buf);
194 crate::systems::advance_queue::run(
195 &mut self.world,
196 &mut self.events,
197 &ctx,
198 &self.elevator_ids_buf,
199 );
200 for group in &self.groups {
201 self.hooks
202 .run_after_group(Phase::AdvanceQueue, group.id(), &mut self.world);
203 }
204 self.hooks.run_after(Phase::AdvanceQueue, &mut self.world);
205 }
206
207 pub fn run_reposition(&mut self) {
215 self.hooks.run_before(Phase::Reposition, &mut self.world);
216 if !self.repositioners.is_empty() {
217 for group in &self.groups {
219 if self.repositioners.contains_key(&group.id()) {
220 self.hooks
221 .run_before_group(Phase::Reposition, group.id(), &mut self.world);
222 }
223 }
224 let ctx = self.phase_context();
225 crate::systems::reposition::run(
226 &mut self.world,
227 &mut self.events,
228 &ctx,
229 &self.groups,
230 &mut self.repositioners,
231 &mut self.reposition_buf,
232 );
233 for group in &self.groups {
234 if self.repositioners.contains_key(&group.id()) {
235 self.hooks
236 .run_after_group(Phase::Reposition, group.id(), &mut self.world);
237 }
238 }
239 }
240 self.hooks.run_after(Phase::Reposition, &mut self.world);
241 }
242
243 #[cfg(feature = "energy")]
245 fn run_energy(&mut self) {
246 let ctx = self.phase_context();
247 self.world.elevator_ids_into(&mut self.elevator_ids_buf);
248 crate::systems::energy::run(
249 &mut self.world,
250 &mut self.events,
251 &ctx,
252 &self.elevator_ids_buf,
253 );
254 }
255
256 pub fn run_metrics(&mut self) {
258 self.hooks.run_before(Phase::Metrics, &mut self.world);
259 for group in &self.groups {
260 self.hooks
261 .run_before_group(Phase::Metrics, group.id(), &mut self.world);
262 }
263 let ctx = self.phase_context();
264 crate::systems::metrics::run(
265 &mut self.world,
266 &self.events,
267 &mut self.metrics,
268 &ctx,
269 &self.groups,
270 );
271 for group in &self.groups {
272 self.hooks
273 .run_after_group(Phase::Metrics, group.id(), &mut self.world);
274 }
275 self.hooks.run_after(Phase::Metrics, &mut self.world);
276 }
277
278 pub fn advance_tick(&mut self) {
285 self.pending_output.extend(self.events.drain());
286 self.tick += 1;
287 self.tick_in_progress = false;
288 }
289
290 pub fn step(&mut self) {
304 self.world.snapshot_prev_positions();
305 self.run_advance_transient();
306 self.run_dispatch();
307 self.run_reposition();
308 self.run_advance_queue();
309 self.run_movement();
310 self.run_doors();
311 self.run_loading();
312 #[cfg(feature = "energy")]
313 self.run_energy();
314 self.run_metrics();
315 self.advance_tick();
316 }
317}