simcore/context.rs
1//! Accessing simulation from components.
2
3use std::cell::RefCell;
4use std::rc::Rc;
5
6use rand::distributions::uniform::{SampleRange, SampleUniform};
7use rand::prelude::Distribution;
8
9use crate::async_mode_enabled;
10use crate::component::Id;
11use crate::event::{Event, EventData, EventId};
12use crate::state::SimulationState;
13
14async_mode_enabled!(
15 use std::any::TypeId;
16 use std::any::type_name;
17
18 use futures::Future;
19
20 use crate::async_mode::event_future::EventFuture;
21 use crate::async_mode::EventKey;
22 use crate::async_mode::timer_future::TimerFuture;
23);
24
25/// A facade for accessing the simulation state and producing events from simulation components.
26pub struct SimulationContext {
27 id: Id,
28 name: String,
29 sim_state: Rc<RefCell<SimulationState>>,
30}
31
32impl SimulationContext {
33 pub(crate) fn new(id: Id, name: &str, sim_state: Rc<RefCell<SimulationState>>) -> Self {
34 Self {
35 id,
36 name: name.to_owned(),
37 sim_state,
38 }
39 }
40
41 /// Returns the identifier of component associated with this context.
42 ///
43 /// # Examples
44 ///
45 /// ```rust
46 /// use simcore::{Simulation, SimulationContext};
47 ///
48 /// let mut sim = Simulation::new(123);
49 /// let comp_ctx = sim.create_context("comp");
50 /// let comp_id = comp_ctx.id();
51 /// assert_eq!(comp_id, 0); // component ids are assigned sequentially starting from 0
52 /// ```
53 pub fn id(&self) -> Id {
54 self.id
55 }
56
57 /// Returns the name of component associated with this context.
58 ///
59 /// # Examples
60 ///
61 /// ```rust
62 /// use simcore::{Simulation, SimulationContext};
63 ///
64 /// let mut sim = Simulation::new(123);
65 /// let comp_ctx = sim.create_context("comp");
66 /// let comp_name = comp_ctx.name();
67 /// assert_eq!(comp_name, "comp");
68 /// ```
69 pub fn name(&self) -> &str {
70 &self.name
71 }
72
73 /// Returns the current simulation time.
74 ///
75 /// # Examples
76 ///
77 /// ```rust
78 /// use simcore::{Simulation, SimulationContext};
79 ///
80 /// let mut sim = Simulation::new(123);
81 /// let comp_ctx = sim.create_context("comp");
82 /// let time = comp_ctx.time();
83 /// assert_eq!(time, 0.0);
84 /// ```
85 pub fn time(&self) -> f64 {
86 self.sim_state.borrow().time()
87 }
88
89 /// Returns a random float in the range _[0, 1)_
90 /// using the simulation-wide random number generator.
91 ///
92 /// # Examples
93 ///
94 /// ```rust
95 /// use simcore::{Simulation, SimulationContext};
96 ///
97 /// let mut sim = Simulation::new(123);
98 /// let mut comp_ctx = sim.create_context("comp");
99 /// let f: f64 = comp_ctx.rand();
100 /// assert!(f >= 0.0 && f < 1.0);
101 /// ```
102 pub fn rand(&self) -> f64 {
103 self.sim_state.borrow_mut().rand()
104 }
105
106 /// Returns a random number in the specified range
107 /// using the simulation-wide random number generator.
108 ///
109 /// # Examples
110 ///
111 /// ```rust
112 /// use simcore::{Simulation, SimulationContext};
113 ///
114 /// let mut sim = Simulation::new(123);
115 /// let mut comp_ctx = sim.create_context("comp");
116 /// let n: u32 = comp_ctx.gen_range(1..=10);
117 /// assert!(n >= 1 && n <= 10);
118 /// let f: f64 = comp_ctx.gen_range(0.1..0.5);
119 /// assert!(f >= 0.1 && f < 0.5);
120 /// ```
121 pub fn gen_range<T, R>(&self, range: R) -> T
122 where
123 T: SampleUniform,
124 R: SampleRange<T>,
125 {
126 self.sim_state.borrow_mut().gen_range(range)
127 }
128
129 /// Returns a random value from the specified distribution
130 /// using the simulation-wide random number generator.
131 pub fn sample_from_distribution<T, Dist: Distribution<T>>(&self, dist: &Dist) -> T {
132 self.sim_state.borrow_mut().sample_from_distribution(dist)
133 }
134
135 /// Returns a random alphanumeric string of specified length
136 /// using the simulation-wide random number generator.
137 pub fn random_string(&self, len: usize) -> String {
138 self.sim_state.borrow_mut().random_string(len)
139 }
140
141 /// Creates new event with specified payload, destination and delay, returns event id.
142 ///
143 /// The event time will be `current_time + delay`.
144 /// It is not allowed to create events before the current simulation time, so `delay` should be non-negative.
145 ///
146 /// The event source will be equal to [`id`](Self::id).
147 /// See [`emit_as`](Self::emit_as) if you want to emit event on behalf of some other component.
148 ///
149 /// # Examples
150 ///
151 /// ```rust
152 /// use std::cell::RefCell;
153 /// use std::rc::Rc;
154 /// use serde::Serialize;
155 /// use simcore::{cast, Event, EventHandler, Simulation, SimulationContext};
156 ///
157 /// #[derive(Clone, Serialize)]
158 /// struct SomeEvent {
159 /// some_field: u32,
160 /// }
161 ///
162 /// struct Component {
163 /// ctx: SimulationContext,
164 /// }
165 ///
166 /// impl EventHandler for Component {
167 /// fn on(&mut self, event: Event) {
168 /// cast!(match event.data {
169 /// SomeEvent { some_field } => {
170 /// assert_eq!(self.ctx.time(), 1.2);
171 /// assert_eq!(event.time, 1.2);
172 /// assert_eq!(event.id, 0);
173 /// assert_eq!(some_field, 16);
174 /// }
175 /// })
176 ///
177 /// }
178 /// }
179 ///
180 /// let mut sim = Simulation::new(123);
181 /// let mut comp1_ctx = sim.create_context("comp1");
182 /// let mut comp2_ctx = sim.create_context("comp2");
183 /// let comp2_id = sim.add_handler("comp2", Rc::new(RefCell::new(Component { ctx: comp2_ctx })));
184 /// let event_id = comp1_ctx.emit(SomeEvent{ some_field: 16 }, comp2_id, 1.2);
185 /// assert_eq!(event_id, 0); // events ids are assigned sequentially starting from 0
186 /// sim.step();
187 /// assert_eq!(sim.time(), 1.2);
188 /// ```
189 ///
190 /// ```should_panic
191 /// use serde::Serialize;
192 /// use simcore::{Simulation, SimulationContext};
193 ///
194 /// #[derive(Clone, Serialize)]
195 /// struct SomeEvent {
196 /// }
197 ///
198 /// let mut sim = Simulation::new(123);
199 /// let mut comp1_ctx = sim.create_context("comp1");
200 /// let mut comp2_ctx = sim.create_context("comp2");
201 /// comp1_ctx.emit(SomeEvent{}, comp2_ctx.id(), -1.0); // will panic because of negative delay
202 /// ```
203 pub fn emit<T>(&self, data: T, dst: Id, delay: f64) -> EventId
204 where
205 T: EventData,
206 {
207 self.sim_state.borrow_mut().add_event(data, self.id, dst, delay)
208 }
209
210 /// This and all other `emit_ordered...` functions are special variants of normal `emit_...` functions
211 /// that allow adding events to ordered event deque instead of heap, which may improve simulation performance.
212 ///
213 /// Ordered events should be emitted in non-decreasing order of their time, otherwise the simulation will panic.
214 ///
215 /// # Examples
216 ///
217 /// ```rust
218 /// use serde::Serialize;
219 /// use simcore::{Simulation, SimulationContext};
220 ///
221 /// #[derive(Clone, Serialize)]
222 /// struct SomeEvent {
223 /// }
224 ///
225 /// let mut sim = Simulation::new(123);
226 /// let mut comp1_ctx = sim.create_context("comp1");
227 /// let mut comp2_ctx = sim.create_context("comp2");
228 /// comp1_ctx.emit_ordered(SomeEvent{}, comp2_ctx.id(), 1.0);
229 /// comp1_ctx.emit_ordered(SomeEvent{}, comp2_ctx.id(), 1.0);
230 /// comp1_ctx.emit_ordered(SomeEvent{}, comp2_ctx.id(), 2.0);
231 /// sim.step();
232 /// assert_eq!(sim.time(), 1.0);
233 /// sim.step();
234 /// assert_eq!(sim.time(), 1.0);
235 /// sim.step();
236 /// assert_eq!(sim.time(), 2.0);
237 /// ```
238 ///
239 /// ```should_panic
240 /// use serde::Serialize;
241 /// use simcore::{Simulation, SimulationContext};
242 ///
243 /// #[derive(Clone, Serialize)]
244 /// struct SomeEvent {
245 /// }
246 ///
247 /// let mut sim = Simulation::new(123);
248 /// let mut comp1_ctx = sim.create_context("comp1");
249 /// let mut comp2_ctx = sim.create_context("comp2");
250 /// comp1_ctx.emit_ordered(SomeEvent{}, comp2_ctx.id(), 2.0);
251 /// comp1_ctx.emit_ordered(SomeEvent{}, comp2_ctx.id(), 1.0); // will panic because of broken time order
252 /// ```
253 pub fn emit_ordered<T>(&self, data: T, dst: Id, delay: f64) -> EventId
254 where
255 T: EventData,
256 {
257 self.sim_state.borrow_mut().add_ordered_event(data, self.id, dst, delay)
258 }
259
260 /// Checks whether it is safe to emit an ordered event with the specified delay.
261 ///
262 /// The time of new event must be not less than the time of the previously emitted ordered event.
263 ///
264 /// Returns true if this condition holds and false otherwise.
265 ///
266 /// # Examples
267 ///
268 /// ```rust
269 /// use serde::Serialize;
270 /// use simcore::{Simulation, SimulationContext};
271 ///
272 /// #[derive(Clone, Serialize)]
273 /// struct SomeEvent {
274 /// }
275 ///
276 /// let mut sim = Simulation::new(123);
277 /// let mut comp1_ctx = sim.create_context("comp1");
278 /// let mut comp2_ctx = sim.create_context("comp2");
279 /// comp1_ctx.emit_ordered(SomeEvent{}, comp2_ctx.id(), 1.0);
280 /// assert!(comp1_ctx.can_emit_ordered(1.0)); // 1.0 == 1.0
281 /// assert!(comp1_ctx.can_emit_ordered(1.1)); // 1.1 > 1.0
282 /// assert!(!comp1_ctx.can_emit_ordered(0.9)); // 0.9 < 1.0
283 /// comp1_ctx.emit_ordered(SomeEvent{}, comp2_ctx.id(), 1.5);
284 /// assert!(!comp1_ctx.can_emit_ordered(1.0)); // 1.0 < 1.5
285 /// sim.step();
286 /// assert_eq!(sim.time(), 1.0);
287 /// assert!(comp1_ctx.can_emit_ordered(1.0)); // 2.0 > 1.5
288 /// assert!(!comp1_ctx.can_emit_ordered(0.3)); // 1.3 < 1.5
289 /// ```
290 pub fn can_emit_ordered(&self, delay: f64) -> bool {
291 self.sim_state.borrow().can_add_ordered_event(delay)
292 }
293
294 /// Creates new immediate (zero-delay) event with specified payload and destination, returns event id.
295 ///
296 /// This is a shorthand for [`emit`](Self::emit) with zero delay.
297 ///
298 /// # Examples
299 ///
300 /// ```rust
301 /// use std::cell::RefCell;
302 /// use std::rc::Rc;
303 /// use serde::Serialize;
304 /// use simcore::{cast, Event, EventHandler, Simulation, SimulationContext};
305 ///
306 /// #[derive(Clone, Serialize)]
307 /// struct SomeEvent {
308 /// some_field: u32,
309 /// }
310 ///
311 /// struct Component {
312 /// ctx: SimulationContext,
313 /// }
314 ///
315 /// impl EventHandler for Component {
316 /// fn on(&mut self, event: Event) {
317 /// cast!(match event.data {
318 /// SomeEvent { some_field } => {
319 /// assert_eq!(self.ctx.time(), 0.0);
320 /// assert_eq!(event.time, 0.0);
321 /// assert_eq!(event.id, 0);
322 /// assert_eq!(some_field, 16);
323 /// }
324 /// })
325 ///
326 /// }
327 /// }
328 ///
329 /// let mut sim = Simulation::new(123);
330 /// let mut comp1_ctx = sim.create_context("comp1");
331 /// let mut comp2_ctx = sim.create_context("comp2");
332 /// let comp2_id = sim.add_handler("comp2", Rc::new(RefCell::new(Component { ctx: comp2_ctx })));
333 /// let event_id = comp1_ctx.emit_now(SomeEvent{ some_field: 16 }, comp2_id);
334 /// assert_eq!(event_id, 0); // events ids are assigned sequentially starting from 0
335 /// sim.step();
336 /// assert_eq!(sim.time(), 0.0);
337 /// ```
338 pub fn emit_now<T>(&self, data: T, dst: Id) -> EventId
339 where
340 T: EventData,
341 {
342 self.sim_state.borrow_mut().add_event(data, self.id, dst, 0.)
343 }
344
345 /// See [`emit_ordered`](Self::emit_ordered).
346 pub fn emit_ordered_now<T>(&self, data: T, dst: Id) -> EventId
347 where
348 T: EventData,
349 {
350 self.sim_state.borrow_mut().add_ordered_event(data, self.id, dst, 0.)
351 }
352
353 /// Creates new event for itself with specified payload and delay, returns event id.
354 ///
355 /// This is a shorthand for [`emit`](Self::emit) with event destination equals [`id`](Self::id).
356 ///
357 /// # Examples
358 ///
359 /// ```rust
360 /// use std::cell::RefCell;
361 /// use std::rc::Rc;
362 /// use serde::Serialize;
363 /// use simcore::{cast, Event, EventHandler, Simulation, SimulationContext};
364 ///
365 /// #[derive(Clone, Serialize)]
366 /// struct SomeEvent {
367 /// some_field: u32,
368 /// }
369 ///
370 /// struct Component {
371 /// ctx: SimulationContext,
372 /// }
373 ///
374 /// impl Component {
375 /// fn start(&mut self) {
376 /// self.ctx.emit_self(SomeEvent{ some_field: 16 }, 6.4);
377 /// }
378 /// }
379 ///
380 /// impl EventHandler for Component {
381 /// fn on(&mut self, event: Event) {
382 /// cast!(match event.data {
383 /// SomeEvent { some_field } => {
384 /// assert_eq!(self.ctx.time(), 6.4);
385 /// assert_eq!(event.time, 6.4);
386 /// assert_eq!(event.id, 0);
387 /// assert_eq!(event.src, self.ctx.id());
388 /// assert_eq!(some_field, 16);
389 /// }
390 /// })
391 ///
392 /// }
393 /// }
394 ///
395 /// let mut sim = Simulation::new(123);
396 /// let comp1 = Rc::new(RefCell::new(Component { ctx: sim.create_context("comp1") }));
397 /// let comp1_id = sim.add_handler("comp1", comp1.clone());
398 /// comp1.borrow_mut().start();
399 /// sim.step();
400 /// assert_eq!(sim.time(), 6.4);
401 /// ```
402 pub fn emit_self<T>(&self, data: T, delay: f64) -> EventId
403 where
404 T: EventData,
405 {
406 self.sim_state.borrow_mut().add_event(data, self.id, self.id, delay)
407 }
408
409 /// See [`Self::emit_ordered`].
410 pub fn emit_ordered_self<T>(&self, data: T, delay: f64) -> EventId
411 where
412 T: EventData,
413 {
414 self.sim_state
415 .borrow_mut()
416 .add_ordered_event(data, self.id, self.id, delay)
417 }
418
419 /// Creates new immediate event for itself with specified payload, returns event id.
420 ///
421 /// This is a shorthand for [`emit`](Self::emit) with event destination equals [`id`](Self::id)
422 /// and zero delay.
423 ///
424 /// # Examples
425 ///
426 /// ```rust
427 /// use std::cell::RefCell;
428 /// use std::rc::Rc;
429 /// use serde::Serialize;
430 /// use simcore::{cast, Event, EventHandler, Simulation, SimulationContext};
431 ///
432 /// #[derive(Clone, Serialize)]
433 /// struct SomeEvent {
434 /// some_field: u32,
435 /// }
436 ///
437 /// struct Component {
438 /// ctx: SimulationContext,
439 /// }
440 ///
441 /// impl Component {
442 /// fn start(&mut self) {
443 /// self.ctx.emit_self_now(SomeEvent{ some_field: 16 });
444 /// }
445 /// }
446 ///
447 /// impl EventHandler for Component {
448 /// fn on(&mut self, event: Event) {
449 /// cast!(match event.data {
450 /// SomeEvent { some_field } => {
451 /// assert_eq!(self.ctx.time(), 0.0);
452 /// assert_eq!(event.time, 0.0);
453 /// assert_eq!(event.id, 0);
454 /// assert_eq!(event.src, self.ctx.id());
455 /// assert_eq!(some_field, 16);
456 /// }
457 /// })
458 ///
459 /// }
460 /// }
461 ///
462 /// let mut sim = Simulation::new(123);
463 /// let comp1 = Rc::new(RefCell::new(Component { ctx: sim.create_context("comp1") }));
464 /// let comp1_id = sim.add_handler("comp1", comp1.clone());
465 /// comp1.borrow_mut().start();
466 /// sim.step();
467 /// assert_eq!(sim.time(), 0.0);
468 /// ```
469 pub fn emit_self_now<T>(&self, data: T) -> EventId
470 where
471 T: EventData,
472 {
473 self.sim_state.borrow_mut().add_event(data, self.id, self.id, 0.)
474 }
475
476 /// See [`emit_ordered`](Self::emit_ordered).
477 pub fn emit_ordered_self_now<T>(&self, data: T) -> EventId
478 where
479 T: EventData,
480 {
481 self.sim_state
482 .borrow_mut()
483 .add_ordered_event(data, self.id, self.id, 0.)
484 }
485
486 /// Creates new event with specified payload, source, destination and delay, returns event id.
487 ///
488 /// This is an extended version of [`emit`](Self::emit) for special cases when the event should be emitted
489 /// on behalf of another component.
490 ///
491 /// ```rust
492 /// use std::cell::RefCell;
493 /// use std::rc::Rc;
494 /// use serde::Serialize;
495 /// use simcore::{cast, Event, EventHandler, Simulation, SimulationContext};
496 ///
497 /// #[derive(Clone, Serialize)]
498 /// struct SomeEvent {
499 /// some_field: u32,
500 /// }
501 ///
502 /// struct Component {
503 /// ctx: SimulationContext,
504 /// }
505 ///
506 /// impl EventHandler for Component {
507 /// fn on(&mut self, event: Event) {
508 /// cast!(match event.data {
509 /// SomeEvent { some_field } => {
510 /// assert_eq!(self.ctx.time(), 2.4);
511 /// assert_eq!(event.time, 2.4);
512 /// assert_eq!(event.id, 0);
513 /// assert_eq!(event.src, 0);
514 /// assert_eq!(self.ctx.id(), 1);
515 /// assert_eq!(some_field, 8);
516 /// }
517 /// })
518 ///
519 /// }
520 /// }
521 ///
522 /// let mut sim = Simulation::new(123);
523 /// let comp1 = Rc::new(RefCell::new(Component { ctx: sim.create_context("comp1") }));
524 /// let comp1_id = sim.add_handler("comp1", comp1);
525 /// let comp2 = Rc::new(RefCell::new(Component { ctx: sim.create_context("comp2") }));
526 /// let comp2_id = sim.add_handler("comp2", comp2);
527 /// let mut other_ctx = sim.create_context("other");
528 /// other_ctx.emit_as(SomeEvent{ some_field: 8 }, comp1_id, comp2_id, 2.4);
529 /// sim.step();
530 /// assert_eq!(sim.time(), 2.4);
531 /// ```
532 pub fn emit_as<T>(&self, data: T, src: Id, dst: Id, delay: f64) -> EventId
533 where
534 T: EventData,
535 {
536 self.sim_state.borrow_mut().add_event(data, src, dst, delay)
537 }
538
539 /// See [`emit_ordered`](Self::emit_ordered).
540 pub fn emit_ordered_as<T>(&self, data: T, src: Id, dst: Id, delay: f64) -> EventId
541 where
542 T: EventData,
543 {
544 self.sim_state.borrow_mut().add_ordered_event(data, src, dst, delay)
545 }
546
547 /// Cancels the specified event.
548 ///
549 /// Use [`EventId`] obtained when creating the event to cancel it.
550 /// Note that already processed events cannot be cancelled.
551 ///
552 /// # Examples
553 ///
554 /// ```rust
555 /// use serde::Serialize;
556 /// use simcore::{Simulation, SimulationContext};
557 ///
558 /// #[derive(Clone, Serialize)]
559 /// struct SomeEvent {
560 /// }
561 ///
562 /// let mut sim = Simulation::new(123);
563 /// let mut comp1_ctx = sim.create_context("comp1");
564 /// let mut comp2_ctx = sim.create_context("comp2");
565 /// let event1 = comp1_ctx.emit(SomeEvent{}, comp2_ctx.id(), 1.0);
566 /// let event2 = comp1_ctx.emit(SomeEvent{}, comp2_ctx.id(), 2.0);
567 /// sim.step();
568 /// comp1_ctx.cancel_event(event2);
569 /// sim.step_until_no_events();
570 /// assert_eq!(sim.time(), 1.0);
571 /// ```
572 pub fn cancel_event(&self, id: EventId) {
573 self.sim_state.borrow_mut().cancel_event(id);
574 }
575
576 /// Cancels events that satisfy the given predicate function.
577 ///
578 /// Note that already processed events cannot be cancelled.
579 ///
580 /// # Examples
581 ///
582 /// ```rust
583 /// use serde::Serialize;
584 /// use simcore::{Event, Simulation, SimulationContext};
585 ///
586 /// #[derive(Clone, Serialize)]
587 /// struct SomeEvent {
588 /// }
589 ///
590 /// let mut sim = Simulation::new(123);
591 /// let mut comp1_ctx = sim.create_context("comp1");
592 /// let mut comp2_ctx = sim.create_context("comp2");
593 /// let event1 = comp1_ctx.emit(SomeEvent{}, comp2_ctx.id(), 1.0);
594 /// let event2 = comp1_ctx.emit(SomeEvent{}, comp2_ctx.id(), 2.0);
595 /// let event2 = comp1_ctx.emit(SomeEvent{}, comp2_ctx.id(), 3.0);
596 /// comp1_ctx.cancel_events(|e| e.id < 2);
597 /// sim.step();
598 /// assert_eq!(sim.time(), 3.0);
599 /// ```
600 pub fn cancel_events<F>(&self, pred: F)
601 where
602 F: Fn(&Event) -> bool,
603 {
604 self.sim_state.borrow_mut().cancel_events(pred);
605 }
606
607 /// Same as [`cancel_events`](Self::cancel_events), but ignores events added through `emit_ordered_...` methods.
608 pub fn cancel_heap_events<F>(&self, pred: F)
609 where
610 F: Fn(&Event) -> bool,
611 {
612 self.sim_state.borrow_mut().cancel_heap_events(pred);
613 }
614
615 /// Returns component name by its identifier.
616 ///
617 /// # Examples
618 ///
619 /// ```rust
620 /// use std::cell::RefCell;
621 /// use std::rc::Rc;
622 /// use serde::Serialize;
623 /// use simcore::{cast, Event, EventHandler, Simulation, SimulationContext};
624 ///
625 /// #[derive(Clone, Serialize)]
626 /// struct SomeEvent {
627 /// }
628 ///
629 /// struct Component {
630 /// ctx: SimulationContext,
631 /// }
632 ///
633 /// impl EventHandler for Component {
634 /// fn on(&mut self, event: Event) {
635 /// cast!(match event.data {
636 /// SomeEvent { } => {
637 /// // look up the name of event source
638 /// let src_name = self.ctx.lookup_name(event.src);
639 /// assert_eq!(src_name, "comp1");
640 /// }
641 /// })
642 ///
643 /// }
644 /// }
645 ///
646 /// let mut sim = Simulation::new(123);
647 /// let mut comp1_ctx = sim.create_context("comp1");
648 /// let mut comp2_ctx = sim.create_context("comp2");
649 /// let comp2_id = sim.add_handler("comp2", Rc::new(RefCell::new(Component { ctx: comp2_ctx })));
650 /// comp1_ctx.emit(SomeEvent{}, comp2_id, 1.0);
651 /// sim.step();
652 /// ```
653 pub fn lookup_name(&self, id: Id) -> String {
654 self.sim_state.borrow().lookup_name(id)
655 }
656
657 async_mode_enabled!(
658 /// Spawns a new asynchronous task for component associated with this context.
659 ///
660 /// Passing component's state to asynchronous tasks can be achieved by using `Rc<Self>` instead of `&self` reference.
661 /// Mutating the component's state by asynchronous tasks can be achieved by wrapping this state into `RefCell<_>`.
662 /// In order to spawn asynchronous tasks, component is required to be [registered](crate::Simulation::add_static_handler)
663 /// as [`StaticEventHandler`](crate::StaticEventHandler). See the examples below.
664 ///
665 /// # Examples
666 ///
667 /// ```rust
668 /// use std::rc::Rc;
669 /// use serde::Serialize;
670 /// use simcore::{cast, Simulation, SimulationContext, Event, StaticEventHandler};
671 ///
672 /// #[derive(Clone, Serialize)]
673 /// struct Start {
674 /// tasks: u32,
675 /// }
676 ///
677 /// struct Component {
678 /// ctx: SimulationContext,
679 /// }
680 ///
681 /// impl Component {
682 /// fn on_start(self: Rc<Self>, tasks: u32) {
683 /// for i in 1..=tasks {
684 /// self.ctx.spawn(self.clone().step_waiting(i));
685 /// }
686 /// }
687 ///
688 /// async fn step_waiting(self: Rc<Self>, num_steps: u32) {
689 /// for _ in 0..num_steps {
690 /// self.ctx.sleep(1.).await;
691 /// }
692 /// }
693 /// }
694 ///
695 /// impl StaticEventHandler for Component {
696 /// fn on(self: Rc<Self>, event: Event) {
697 /// cast!(match event.data {
698 /// Start { tasks } => {
699 /// self.on_start(tasks);
700 /// }
701 /// })
702 /// }
703 /// }
704 ///
705 /// let mut sim = Simulation::new(123);
706 ///
707 /// let comp_ctx = sim.create_context("comp");
708 /// let comp_id = sim.add_static_handler("comp", Rc::new(Component {ctx: comp_ctx }));
709 ///
710 /// let root_ctx = sim.create_context("root");
711 /// root_ctx.emit(Start { tasks: 10 }, comp_id, 10.);
712 ///
713 /// sim.step_until_no_events();
714 ///
715 /// assert_eq!(sim.time(), 20.);
716 /// ```
717 ///
718 /// ```should_panic
719 /// use std::rc::Rc;
720 /// use simcore::{Simulation, SimulationContext};
721 ///
722 /// struct Component {
723 /// ctx: SimulationContext,
724 /// }
725 ///
726 /// impl Component {
727 /// fn start(self: Rc<Self>, tasks: u32) {
728 /// for i in 1..=tasks {
729 /// self.ctx.spawn(self.clone().step_waiting(i));
730 /// }
731 /// }
732 ///
733 /// async fn step_waiting(self: Rc<Self>, num_steps: u32) {
734 /// for _i in 0..num_steps {
735 /// self.ctx.sleep(1.).await;
736 /// }
737 /// }
738 /// }
739 ///
740 /// let mut sim = Simulation::new(123);
741 /// let mut comp = Rc::new(Component { ctx: sim.create_context("comp") });
742 ///
743 /// // Panics because spawning async tasks for component without event handler is prohibited
744 /// // due to safety reasons.
745 /// // Register Component via Simulation::add_static_handler as in the previous example.
746 /// comp.start(10);
747 /// ```
748 ///
749 /// ```compile_fail
750 /// use std::rc::Rc;
751 /// use std::cell::RefCell;
752 /// use simcore::{Simulation, SimulationContext, Event, EventHandler};
753 ///
754 /// struct Component {
755 /// ctx: SimulationContext,
756 /// counter: u32,
757 /// }
758 ///
759 /// impl Component {
760 /// fn on_start(&mut self, tasks: u32) {
761 /// for i in 1..=tasks {
762 /// // Compile fails because reference to self is used in the async task,
763 /// // which is not allowed because of 'static requirements on the spawned future.
764 /// // 1. To spawn 'static futures register this component as StaticEventHandler.
765 /// // 2. Use RefCell to wrap the mutable state and access it in the async task via RefCell::borrow_mut.
766 /// // See the next example for details.
767 /// self.ctx.spawn(self.increase_counter(i));
768 /// }
769 /// }
770 ///
771 /// async fn increase_counter(&mut self, num_steps: u32) {
772 /// for _ in 0..num_steps {
773 /// self.ctx.sleep(1.).await;
774 /// self.counter += 1;
775 /// }
776 /// }
777 /// }
778 ///
779 /// impl EventHandler for Component {
780 /// fn on(&mut self, event: Event) {}
781 /// }
782 ///
783 /// let mut sim = Simulation::new(123);
784 ///
785 /// let comp_ctx = sim.create_context("comp");
786 /// let comp = Rc::new(RefCell::new(Component {ctx: comp_ctx, counter: 0 }));
787 /// sim.add_handler("comp", comp.clone());
788 ///
789 /// comp.borrow_mut().on_start(10);
790 ///
791 /// sim.step_until_no_events();
792 /// ```
793 ///
794 /// ```rust
795 /// use std::rc::Rc;
796 /// use std::cell::RefCell;
797 /// use simcore::{Simulation, SimulationContext, Event, StaticEventHandler};
798 ///
799 /// struct Component {
800 /// ctx: SimulationContext,
801 /// counter: RefCell<u32>,
802 /// }
803 ///
804 /// impl Component {
805 /// fn on_start(self: Rc<Self>, tasks: u32) {
806 /// for i in 1..=tasks {
807 /// self.ctx.spawn(self.clone().increase_counter(i));
808 /// }
809 /// }
810 ///
811 /// async fn increase_counter(self: Rc<Self>, num_steps: u32) {
812 /// for _ in 0..num_steps {
813 /// self.ctx.sleep(1.).await;
814 /// *self.counter.borrow_mut() += 1;
815 /// }
816 /// }
817 /// }
818 ///
819 /// impl StaticEventHandler for Component {
820 /// fn on(self: Rc<Self>, event: Event) {}
821 /// }
822 ///
823 /// let mut sim = Simulation::new(123);
824 ///
825 /// let comp_ctx = sim.create_context("comp");
826 /// let comp = Rc::new(Component {ctx: comp_ctx, counter: RefCell::new(0) });
827 /// sim.add_static_handler("comp", comp.clone());
828 ///
829 /// comp.clone().on_start(10);
830 ///
831 /// sim.step_until_no_events();
832 ///
833 /// assert_eq!(sim.time(), 10.);
834 /// // 1 + 2 + 3 + ... + 10 = 55
835 /// assert_eq!(*comp.counter.borrow(), 55);
836 /// ```
837 pub fn spawn(&self, future: impl Future<Output = ()> + 'static) {
838 self.sim_state.borrow_mut().spawn_component(self.id(), future);
839 }
840
841 /// Waits (asynchronously) until `duration` seconds have elapsed.
842 ///
843 /// # Examples
844 ///
845 /// ```rust
846 /// use futures::{stream::FuturesUnordered, StreamExt};
847 /// use simcore::Simulation;
848 ///
849 /// let mut sim = Simulation::new(123);
850 ///
851 /// let ctx = sim.create_context("comp");
852 ///
853 /// sim.spawn(async move {
854 /// let initial_time = ctx.time();
855 /// ctx.sleep(5.).await;
856 ///
857 /// let mut expected_time = initial_time + 5.;
858 /// assert_eq!(expected_time, ctx.time());
859 ///
860 /// let mut futures = FuturesUnordered::new();
861 /// for i in 1..=10 {
862 /// futures.push(ctx.sleep(i as f64));
863 /// }
864 ///
865 /// while let Some(_) = futures.next().await {
866 /// expected_time += 1.;
867 /// assert_eq!(expected_time, ctx.time());
868 /// }
869 /// });
870 ///
871 /// sim.step_until_no_events();
872 /// assert_eq!(15., sim.time());
873 /// ```
874 pub fn sleep(&self, duration: f64) -> TimerFuture {
875 assert!(duration >= 0., "Duration must be a positive value");
876 self.sim_state
877 .borrow_mut()
878 .create_timer(self.id, duration, self.sim_state.clone())
879 }
880
881 /// Waits (asynchronously) until all events scheduled at the current time are processed.
882 ///
883 /// May be useful to execute some logic without a time delay but after all events have been processed.
884 /// If there are several `yield_now` calls at the same simulation time, the order of their completion
885 /// is the same as the order of the calls.
886 ///
887 /// # Examples
888 ///
889 /// ```rust
890 /// use std::cell::RefCell;
891 /// use serde::Serialize;
892 /// use simcore::Simulation;
893 ///
894 /// #[derive(Clone, Serialize)]
895 /// struct Request {}
896 ///
897 /// #[derive(Clone, Serialize)]
898 /// struct Response {}
899 ///
900 /// let mut sim = Simulation::new(123);
901 ///
902 /// let master = sim.create_context("master");
903 /// let worker_1 = sim.create_context("worker_1");
904 /// let worker_2 = sim.create_context("worker_2");
905 ///
906 /// sim.spawn(async move {
907 /// let mut counter = RefCell::new(0);
908 /// futures::join!(
909 /// async {
910 /// master.emit(Request {}, worker_1.id(), 5.);
911 /// master.recv_event::<Response>().await;
912 ///
913 /// // Wait until workers exchange 3 messages.
914 /// master.yield_now().await;
915 ///
916 /// assert_eq!(*counter.borrow(), 3);
917 /// assert_eq!(master.time(), 5.);
918 /// master.sleep(5.).await;
919 /// },
920 /// async {
921 /// worker_1.recv_event::<Request>().await;
922 /// worker_1.emit_now(Response {}, master.id());
923 /// for _ in 0..3 {
924 /// worker_1.emit_now(Request {}, worker_2.id());
925 /// }
926 /// for _ in 0..3 {
927 /// worker_1.recv_event::<Response>().await;
928 /// *counter.borrow_mut() += 1;
929 /// }
930 /// },
931 /// async {
932 /// loop {
933 /// let request = worker_2.recv_event::<Request>().await;
934 /// worker_2.emit_now(Response {}, request.src);
935 /// }
936 /// }
937 /// );
938 /// });
939 ///
940 /// sim.step_until_no_events();
941 /// assert_eq!(sim.time(), 10.);
942 /// ```
943 pub async fn yield_now(&self) {
944 let current_time = self.time();
945 let need_yield = if let Some(next_event) = self.sim_state.borrow_mut().peek_event() {
946 next_event.time == current_time
947 } else {
948 false
949 };
950 if need_yield {
951 self.sleep(0.).await;
952 }
953 }
954
955 /// Waits (asynchronously) for event of type `T` from any component.
956 ///
957 /// The returned future outputs the received event and event data.
958 ///
959 /// The timeout for waiting can be set by calling [`EventFuture::with_timeout`] on the returned future.
960 ///
961 /// # Examples
962 ///
963 /// ```rust
964 /// use serde::Serialize;
965 /// use simcore::Simulation;
966 ///
967 /// #[derive(Clone, Serialize)]
968 /// struct Message {
969 /// payload: u32,
970 /// }
971 ///
972 /// let mut sim = Simulation::new(123);
973 /// let sender_ctx = sim.create_context("sender");
974 /// let sender_id = sender_ctx.id();
975 /// let receiver_ctx = sim.create_context("receiver");
976 /// let receiver_id = receiver_ctx.id();
977 ///
978 /// sim.spawn(async move {
979 /// sender_ctx.emit(Message { payload: 321 }, receiver_id, 50.);
980 /// });
981 ///
982 /// sim.spawn(async move {
983 /// let e = receiver_ctx.recv_event::<Message>().await;
984 /// assert_eq!(e.src, sender_id);
985 /// assert_eq!(e.data.payload, 321);
986 /// });
987 ///
988 /// sim.step_until_no_events();
989 /// assert_eq!(sim.time(), 50.);
990 /// ```
991 ///
992 /// ```rust
993 /// use serde::Serialize;
994 /// use simcore::Simulation;
995 ///
996 /// #[derive(Clone, Serialize)]
997 /// struct Message {
998 /// payload: u32,
999 /// }
1000 ///
1001 /// let mut sim = Simulation::new(123);
1002 /// let sender1_ctx = sim.create_context("sender1");
1003 /// let sender1_id = sender1_ctx.id();
1004 /// let sender2_ctx = sim.create_context("sender2");
1005 /// let sender2_id = sender2_ctx.id();
1006 /// let receiver_ctx = sim.create_context("receiver");
1007 /// let receiver_id = receiver_ctx.id();
1008 ///
1009 /// sim.spawn(async move {
1010 /// sender1_ctx.emit(Message { payload: 321 }, receiver_id, 50.);
1011 /// });
1012 ///
1013 /// sim.spawn(async move {
1014 /// sender2_ctx.emit(Message { payload: 322 }, receiver_id, 100.);
1015 /// });
1016 ///
1017 /// sim.spawn(async move {
1018 /// let e = receiver_ctx.recv_event::<Message>().await;
1019 /// assert_eq!(receiver_ctx.time(), 50.);
1020 /// assert_eq!(e.src, sender1_id);
1021 /// assert_eq!(e.data.payload, 321);
1022 /// let e = receiver_ctx.recv_event::<Message>().await;
1023 /// assert_eq!(receiver_ctx.time(), 100.);
1024 /// assert_eq!(e.src, sender2_id);
1025 /// assert_eq!(e.data.payload, 322);
1026 /// });
1027 ///
1028 /// sim.step_until_no_events();
1029 /// assert_eq!(sim.time(), 100.);
1030 /// ```
1031 pub fn recv_event<T>(&self) -> EventFuture<T>
1032 where
1033 T: EventData,
1034 {
1035 self.recv_event_inner::<T>(self.id, None, None)
1036 }
1037
1038 /// Waits (asynchronously) for event of type `T` from component `src`.
1039 ///
1040 /// The returned future outputs the received event and event data.
1041 ///
1042 /// The timeout for waiting can be set by calling [`EventFuture::with_timeout`] on the returned future.
1043 ///
1044 /// # Examples
1045 ///
1046 /// ```rust
1047 /// use serde::Serialize;
1048 /// use simcore::Simulation;
1049 ///
1050 /// #[derive(Clone, Serialize)]
1051 /// struct Message {
1052 /// payload: u32,
1053 /// }
1054 ///
1055 /// let mut sim = Simulation::new(123);
1056 /// let sender_ctx = sim.create_context("sender");
1057 /// let sender_id = sender_ctx.id();
1058 /// let receiver_ctx = sim.create_context("receiver");
1059 /// let receiver_id = receiver_ctx.id();
1060 ///
1061 /// sim.spawn(async move {
1062 /// sender_ctx.emit(Message { payload: 321 }, receiver_id, 50.);
1063 /// });
1064 ///
1065 /// sim.spawn(async move {
1066 /// let e = receiver_ctx.recv_event_from::<Message>(sender_id).await;
1067 /// assert_eq!(e.src, sender_id);
1068 /// assert_eq!(e.data.payload, 321);
1069 /// });
1070 ///
1071 /// sim.step_until_no_events();
1072 /// assert_eq!(sim.time(), 50.);
1073 /// ```
1074 pub fn recv_event_from<T>(&self, src: Id) -> EventFuture<T>
1075 where
1076 T: EventData,
1077 {
1078 self.recv_event_inner::<T>(self.id, Some(src), None)
1079 }
1080
1081 /// Waits (asynchronously) for event of type `T` from self.
1082 ///
1083 /// The returned future outputs the received event and event data.
1084 ///
1085 /// The timeout for waiting can be set by calling [`EventFuture::with_timeout`] on the returned future.
1086 ///
1087 /// # Examples
1088 ///
1089 /// ```rust
1090 /// use serde::Serialize;
1091 /// use simcore::Simulation;
1092 ///
1093 /// #[derive(Clone, Serialize)]
1094 /// struct SomeEvent {
1095 /// payload: u32,
1096 /// }
1097 ///
1098 /// let mut sim = Simulation::new(123);
1099 /// let ctx = sim.create_context("comp");
1100 ///
1101 /// sim.spawn(async move {
1102 /// ctx.emit_self(SomeEvent { payload: 321 }, 10.);
1103 ///
1104 /// let e = ctx.recv_event_from_self::<SomeEvent>().await;
1105 /// assert_eq!(e.data.payload, 321);
1106 /// assert_eq!(ctx.time(), 10.)
1107 /// });
1108 ///
1109 /// sim.step_until_no_events();
1110 /// assert_eq!(sim.time(), 10.);
1111 /// ```
1112 pub fn recv_event_from_self<T>(&self) -> EventFuture<T>
1113 where
1114 T: EventData,
1115 {
1116 self.recv_event_inner::<T>(self.id, Some(self.id), None)
1117 }
1118
1119 /// Registers a key getter function for event type `T` to be used with
1120 /// [`recv_event_by_key`](Self::recv_event_by_key) and [`recv_event_by_key_from`](Self::recv_event_by_key_from).
1121 pub fn register_key_getter_for<T: EventData>(&self, key_getter: impl Fn(&T) -> EventKey + 'static) {
1122 self.sim_state.borrow_mut().register_key_getter_for::<T>(key_getter);
1123 }
1124
1125 /// Waits (asynchronously) for event of type `T` with key `key` from any component.
1126 ///
1127 /// The returned future outputs the received event and event data.
1128 ///
1129 /// The timeout for waiting can be set by calling [`EventFuture::with_timeout`] on the returned future.
1130 ///
1131 /// See [`recv_event_by_key_from`](Self::recv_event_by_key_from) and [`recv_event`](Self::recv_event) for examples.
1132 pub fn recv_event_by_key<T>(&self, key: EventKey) -> EventFuture<T>
1133 where
1134 T: EventData,
1135 {
1136 self.recv_event_inner::<T>(self.id, None, Some(key))
1137 }
1138
1139 /// Waits (asynchronously) for event of type `T` with key `key` from component `src`.
1140 ///
1141 /// The returned future outputs the received event and event data.
1142 ///
1143 /// The timeout for waiting can be set by calling [`EventFuture::with_timeout`] on the returned future.
1144 ///
1145 /// # Examples
1146 ///
1147 /// ```rust
1148 /// use std::{cell::RefCell, rc::Rc};
1149 /// use serde::Serialize;
1150 /// use simcore::{cast, Id, Event, StaticEventHandler, Simulation, SimulationContext};
1151 /// use simcore::async_mode::EventKey;
1152 ///
1153 /// #[derive(Clone, Serialize)]
1154 /// struct SomeEvent {
1155 /// key: u64,
1156 /// payload: u32,
1157 /// }
1158 ///
1159 /// #[derive(Clone, Serialize)]
1160 /// struct Start {
1161 /// }
1162 ///
1163 /// struct Component {
1164 /// ctx: SimulationContext,
1165 /// root_id: Id,
1166 /// }
1167 ///
1168 /// impl Component {
1169 /// async fn recv_event_for_key(self: Rc<Self>, key: EventKey) {
1170 /// let e = self.ctx.recv_event_by_key_from::<SomeEvent>(self.root_id, key).await;
1171 /// assert_eq!(e.data.key, key);
1172 /// }
1173 /// }
1174 ///
1175 /// impl StaticEventHandler for Component {
1176 /// fn on(self: Rc<Self>, event: Event) {
1177 /// cast!(match event.data {
1178 /// Start {} => {
1179 /// self.ctx.spawn(self.clone().recv_event_for_key(1));
1180 /// self.ctx.spawn(self.clone().recv_event_for_key(2));
1181 /// }
1182 /// })
1183 /// }
1184 /// }
1185 ///
1186 /// let mut sim = Simulation::new(124);
1187 /// let root_ctx = sim.create_context("sender");
1188 /// let comp_ctx = sim.create_context("comp");
1189 /// let comp_id = sim.add_static_handler("comp", Rc::new(Component { ctx: comp_ctx, root_id: root_ctx.id() }));
1190 ///
1191 /// sim.register_key_getter_for::<SomeEvent>(|message| message.key);
1192 ///
1193 /// root_ctx.emit_now(Start {}, comp_id);
1194 /// root_ctx.emit(SomeEvent { key: 1, payload: 321 }, comp_id, 50.);
1195 /// root_ctx.emit(SomeEvent { key: 2, payload: 322 }, comp_id, 100.);
1196 ///
1197 /// sim.step_until_no_events();
1198 /// assert_eq!(sim.time(), 100.);
1199 /// ```
1200 pub fn recv_event_by_key_from<T>(&self, src: Id, key: EventKey) -> EventFuture<T>
1201 where
1202 T: EventData,
1203 {
1204 self.recv_event_inner::<T>(self.id, Some(src), Some(key))
1205 }
1206
1207 /// Waits (asynchronously) for event of type `T` with key `key` from self.
1208 ///
1209 /// The returned future outputs the received event and event data.
1210 ///
1211 /// The timeout for waiting can be set by calling [`EventFuture::with_timeout`] on the returned future.
1212 ///
1213 /// See [`recv_event_by_key_from`](Self::recv_event_by_key_from) and [`recv_event_from_self`](Self::recv_event_from_self) for examples.
1214 pub fn recv_event_by_key_from_self<T>(&self, key: EventKey) -> EventFuture<T>
1215 where
1216 T: EventData,
1217 {
1218 self.recv_event_inner::<T>(self.id, Some(self.id), Some(key))
1219 }
1220
1221 fn recv_event_inner<T>(&self, dst: Id, src: Option<Id>, key: Option<EventKey>) -> EventFuture<T>
1222 where
1223 T: EventData,
1224 {
1225 if key.is_none() {
1226 assert!(
1227 self.sim_state.borrow().get_key_getter(TypeId::of::<T>()).is_none(),
1228 "Trying to receive event of type with registered key getter, use receive by key for such events"
1229 );
1230 } else {
1231 assert!(
1232 self.sim_state.borrow().get_key_getter(TypeId::of::<T>()).is_some(),
1233 "Trying to receive event by key for type {} without key getter, register it before using this feature",
1234 type_name::<T>()
1235 );
1236 }
1237 let future_result =
1238 self.sim_state
1239 .borrow_mut()
1240 .create_event_future::<T>(dst, src, key, self.sim_state.clone());
1241
1242 match future_result {
1243 Ok(future) => future,
1244 Err((_, e)) => panic!("Failed to create EventFuture: {}", e),
1245 }
1246 }
1247 );
1248}