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.hooks
69 .run_before(Phase::AdvanceTransient, &mut self.world);
70 for group in &self.groups {
71 self.hooks
72 .run_before_group(Phase::AdvanceTransient, group.id(), &mut self.world);
73 }
74 let ctx = self.phase_context();
75 crate::systems::advance_transient::run(
76 &mut self.world,
77 &mut self.events,
78 &ctx,
79 &mut self.rider_index,
80 );
81 for group in &self.groups {
82 self.hooks
83 .run_after_group(Phase::AdvanceTransient, group.id(), &mut self.world);
84 }
85 self.hooks
86 .run_after(Phase::AdvanceTransient, &mut self.world);
87 }
88
89 pub fn run_dispatch(&mut self) {
91 self.hooks.run_before(Phase::Dispatch, &mut self.world);
92 for group in &self.groups {
93 self.hooks
94 .run_before_group(Phase::Dispatch, group.id(), &mut self.world);
95 }
96 let ctx = self.phase_context();
97 crate::systems::dispatch::run(
98 &mut self.world,
99 &mut self.events,
100 &ctx,
101 &self.groups,
102 &mut self.dispatchers,
103 &self.rider_index,
104 );
105 for group in &self.groups {
106 self.hooks
107 .run_after_group(Phase::Dispatch, group.id(), &mut self.world);
108 }
109 self.hooks.run_after(Phase::Dispatch, &mut self.world);
110 }
111
112 pub fn run_movement(&mut self) {
114 self.hooks.run_before(Phase::Movement, &mut self.world);
115 for group in &self.groups {
116 self.hooks
117 .run_before_group(Phase::Movement, group.id(), &mut self.world);
118 }
119 let ctx = self.phase_context();
120 self.world.elevator_ids_into(&mut self.elevator_ids_buf);
121 crate::systems::movement::run(
122 &mut self.world,
123 &mut self.events,
124 &ctx,
125 &self.elevator_ids_buf,
126 &mut self.metrics,
127 );
128 for group in &self.groups {
129 self.hooks
130 .run_after_group(Phase::Movement, group.id(), &mut self.world);
131 }
132 self.hooks.run_after(Phase::Movement, &mut self.world);
133 }
134
135 pub fn run_doors(&mut self) {
137 self.hooks.run_before(Phase::Doors, &mut self.world);
138 for group in &self.groups {
139 self.hooks
140 .run_before_group(Phase::Doors, group.id(), &mut self.world);
141 }
142 let ctx = self.phase_context();
143 self.world.elevator_ids_into(&mut self.elevator_ids_buf);
144 crate::systems::doors::run(
145 &mut self.world,
146 &mut self.events,
147 &ctx,
148 &self.elevator_ids_buf,
149 );
150 for group in &self.groups {
151 self.hooks
152 .run_after_group(Phase::Doors, group.id(), &mut self.world);
153 }
154 self.hooks.run_after(Phase::Doors, &mut self.world);
155 }
156
157 pub fn run_loading(&mut self) {
159 self.hooks.run_before(Phase::Loading, &mut self.world);
160 for group in &self.groups {
161 self.hooks
162 .run_before_group(Phase::Loading, group.id(), &mut self.world);
163 }
164 let ctx = self.phase_context();
165 self.world.elevator_ids_into(&mut self.elevator_ids_buf);
166 crate::systems::loading::run(
167 &mut self.world,
168 &mut self.events,
169 &ctx,
170 &self.elevator_ids_buf,
171 &mut self.rider_index,
172 );
173 for group in &self.groups {
174 self.hooks
175 .run_after_group(Phase::Loading, group.id(), &mut self.world);
176 }
177 self.hooks.run_after(Phase::Loading, &mut self.world);
178 }
179
180 pub fn run_advance_queue(&mut self) {
186 self.hooks.run_before(Phase::AdvanceQueue, &mut self.world);
187 for group in &self.groups {
188 self.hooks
189 .run_before_group(Phase::AdvanceQueue, group.id(), &mut self.world);
190 }
191 let ctx = self.phase_context();
192 self.world.elevator_ids_into(&mut self.elevator_ids_buf);
193 crate::systems::advance_queue::run(
194 &mut self.world,
195 &mut self.events,
196 &ctx,
197 &self.elevator_ids_buf,
198 );
199 for group in &self.groups {
200 self.hooks
201 .run_after_group(Phase::AdvanceQueue, group.id(), &mut self.world);
202 }
203 self.hooks.run_after(Phase::AdvanceQueue, &mut self.world);
204 }
205
206 pub fn run_reposition(&mut self) {
214 self.hooks.run_before(Phase::Reposition, &mut self.world);
215 if !self.repositioners.is_empty() {
216 for group in &self.groups {
218 if self.repositioners.contains_key(&group.id()) {
219 self.hooks
220 .run_before_group(Phase::Reposition, group.id(), &mut self.world);
221 }
222 }
223 let ctx = self.phase_context();
224 crate::systems::reposition::run(
225 &mut self.world,
226 &mut self.events,
227 &ctx,
228 &self.groups,
229 &mut self.repositioners,
230 &mut self.reposition_buf,
231 );
232 for group in &self.groups {
233 if self.repositioners.contains_key(&group.id()) {
234 self.hooks
235 .run_after_group(Phase::Reposition, group.id(), &mut self.world);
236 }
237 }
238 }
239 self.hooks.run_after(Phase::Reposition, &mut self.world);
240 }
241
242 #[cfg(feature = "energy")]
244 fn run_energy(&mut self) {
245 let ctx = self.phase_context();
246 self.world.elevator_ids_into(&mut self.elevator_ids_buf);
247 crate::systems::energy::run(
248 &mut self.world,
249 &mut self.events,
250 &ctx,
251 &self.elevator_ids_buf,
252 );
253 }
254
255 pub fn run_metrics(&mut self) {
257 self.hooks.run_before(Phase::Metrics, &mut self.world);
258 for group in &self.groups {
259 self.hooks
260 .run_before_group(Phase::Metrics, group.id(), &mut self.world);
261 }
262 let ctx = self.phase_context();
263 crate::systems::metrics::run(
264 &mut self.world,
265 &self.events,
266 &mut self.metrics,
267 &ctx,
268 &self.groups,
269 );
270 for group in &self.groups {
271 self.hooks
272 .run_after_group(Phase::Metrics, group.id(), &mut self.world);
273 }
274 self.hooks.run_after(Phase::Metrics, &mut self.world);
275 }
276
277 pub fn advance_tick(&mut self) {
284 self.pending_output.extend(self.events.drain());
285 self.tick += 1;
286 }
287
288 pub fn step(&mut self) {
302 self.world.snapshot_prev_positions();
303 self.run_advance_transient();
304 self.run_dispatch();
305 self.run_reposition();
306 self.run_advance_queue();
307 self.run_movement();
308 self.run_doors();
309 self.run_loading();
310 #[cfg(feature = "energy")]
311 self.run_energy();
312 self.run_metrics();
313 self.advance_tick();
314 }
315}