1use std::marker::PhantomData;
8
9#[cfg(feature="dist_mode")]
10use std::mem;
11
12#[cfg(feature="dist_mode")]
13use std::ptr;
14
15#[cfg(feature="dist_mode")]
16use libc::*;
17
18use crate::simulation;
19use crate::simulation::Point;
20use crate::simulation::Run;
21use crate::simulation::simulation::Simulation;
22use crate::simulation::process::is_process_cancelled;
23use crate::simulation::process::revoke_process;
24use crate::simulation::process::revoke_process_boxed;
25use crate::simulation::process::Process;
26use crate::simulation::process::ProcessId;
27use crate::simulation::process::ProcessBoxCont;
28use crate::simulation::observable::disposable::*;
29use crate::simulation::composite::*;
30
31#[cfg(feature="dist_mode")]
32use crate::simulation::error::*;
33
34#[cfg(feature="dist_mode")]
35use crate::simulation::internal::event_queue::*;
36
37use dvcompute_utils::grc::Grc;
38
39pub mod ops;
41
42#[inline]
44pub fn return_event<T>(val: T) -> Return<T> {
45 Return { val: val }
46}
47
48#[inline]
50pub fn delay_event<F, M>(f: F) -> Delay<F, M>
51 where F: FnOnce() -> M,
52 M: Event
53{
54 Delay { f: f, _phantom: PhantomData }
55}
56
57#[inline]
59pub fn cons_event<F, T>(f: F) -> Cons<F, T>
60 where F: FnOnce(&Point) -> simulation::Result<T>
61{
62 Cons { f: f, _phantom: PhantomData }
63}
64
65#[inline]
67pub fn enqueue_event(time: f64, comp: EventBox<()>) -> Enqueue {
68 Enqueue { time: time, comp: comp }
69}
70
71#[inline]
73pub fn enqueue_event_with_priority(time: f64, priority: isize, comp: EventBox<()>) -> EnqueueWithPriority {
74 EnqueueWithPriority { time: time, priority: priority, comp: comp }
75}
76
77#[inline]
79pub fn enqueue_events_with_integ_times<F>(f: F) -> EnqueueWithIntegTimes<F>
80 where F: Fn() -> EventBox<()> + Clone + 'static
81{
82 EnqueueWithIntegTimes { f: f }
83}
84
85#[inline]
87pub fn enqueue_io_event(time: f64, comp: EventBox<()>) -> EnqueueIO {
88 EnqueueIO { time: time, comp: comp }
89}
90
91#[inline]
93pub fn enqueue_io_event_with_priority(time: f64, priority: isize, comp: EventBox<()>) -> EnqueueIOWithPriority {
94 EnqueueIOWithPriority { time: time, priority: priority, comp: comp }
95}
96
97#[inline]
99pub fn enqueue_io_events_with_integ_times<F>(f: F) -> EnqueueIOWithIntegTimes<F>
100 where F: Fn() -> EventBox<()> + Clone + 'static
101{
102 EnqueueIOWithIntegTimes { f: f }
103}
104
105#[inline]
107pub fn yield_event<M>(comp: M) -> Yield<M>
108 where M: Event<Item = ()> + Clone + 'static
109{
110 Yield { comp: comp }
111}
112
113#[inline]
115pub fn time_event() -> Time {
116 Time {}
117}
118
119#[inline]
121pub fn priority_event() -> Priority {
122 Priority {}
123}
124
125#[inline]
127pub fn event_sequence<I, M>(comps: I) -> Sequence<I::IntoIter, M>
128 where I: IntoIterator<Item = M>,
129 M: Event
130{
131 Sequence { comps: comps.into_iter(), _phantom: PhantomData }
132}
133
134#[inline]
136pub fn event_sequence_<I, M>(comps: I) -> Sequence_<I::IntoIter, M>
137 where I: IntoIterator<Item = M>,
138 M: Event
139{
140 Sequence_ { comps: comps.into_iter(), _phantom: PhantomData }
141}
142
143#[inline]
145pub fn trace_event<M>(msg: String, comp: M) -> Trace<M>
146 where M: Event
147{
148 Trace { comp: comp, msg: msg}
149}
150
151#[cfg(feature="dist_mode")]
162#[inline]
163pub fn leave_simulation() -> LeaveSimulation {
164 LeaveSimulation {}
165}
166
167pub trait Event {
169
170 type Item;
172
173 #[doc(hidden)]
175 fn call_event(self, p: &Point) -> simulation::Result<Self::Item>;
176
177 fn into_process(self) -> EventIntoProcess<Self>
179 where Self: Sized
180 {
181 EventIntoProcess { comp: self }
182 }
183
184 fn into_composite(self) -> EventIntoComposite<Self>
186 where Self: Sized
187 {
188 EventIntoComposite { comp: self }
189 }
190
191 #[inline]
193 fn and_then<U, F>(self, f: F) -> AndThen<Self, U, F>
194 where Self: Sized,
195 U: Event,
196 F: FnOnce(Self::Item) -> U,
197 {
198 AndThen { comp: self, f: f, _phantom: PhantomData }
199 }
200
201 #[inline]
203 fn map<B, F>(self, f: F) -> Map<Self, B, F>
204 where Self: Sized,
205 F: FnOnce(Self::Item) -> B,
206 {
207 Map { comp: self, f: f, _phantom: PhantomData }
208 }
209
210 #[inline]
212 fn zip<U>(self, other: U) -> Zip<Self, U>
213 where Self: Sized,
214 U: Event
215 {
216 Zip { comp: self, other: other }
217 }
218
219 #[inline]
221 fn ap<U, B>(self, other: U) -> Ap<Self, U, B>
222 where Self: Sized,
223 Self::Item: FnOnce(U::Item) -> B,
224 U: Event
225 {
226 Ap { comp: self, other: other, _phantom: PhantomData }
227 }
228
229 #[inline]
231 fn run_in_start_time(self) -> RunInStartTime<Self>
232 where Self: Sized
233 {
234 RunInStartTime { comp: self, including_current_events: true }
235 }
236
237 #[inline]
239 fn run_in_start_time_by(self, including_current_events: bool) -> RunInStartTime<Self>
240 where Self: Sized
241 {
242 RunInStartTime { comp: self, including_current_events: including_current_events }
243 }
244
245 #[inline]
247 fn run_in_stop_time(self) -> RunInStopTime<Self>
248 where Self: Sized
249 {
250 RunInStopTime { comp: self, including_current_events: true }
251 }
252
253 #[inline]
255 fn run_in_stop_time_by(self, including_current_events: bool) -> RunInStopTime<Self>
256 where Self: Sized
257 {
258 RunInStopTime { comp: self, including_current_events: including_current_events }
259 }
260
261 #[inline]
263 fn into_boxed(self) -> EventBox<Self::Item>
264 where Self: Sized + Clone + 'static
265 {
266 EventBox::new(move |p: &Point| { self.call_event(p) })
267 }
268}
269
270pub trait IntoEvent {
272
273 type Event: Event<Item = Self::Item>;
275
276 type Item;
278
279 fn into_event(self) -> Self::Event;
281}
282
283impl<M: Event> IntoEvent for M {
284
285 type Event = M;
286
287 type Item = M::Item;
288
289 #[inline]
290 fn into_event(self) -> Self::Event {
291 self
292 }
293}
294
295#[must_use = "computations are lazy and do nothing unless to be run"]
297pub struct EventBox<T> {
298 f: Box<dyn EventFnBoxClone<T>>
299}
300
301impl<T> EventBox<T> {
302
303 #[doc(hidden)]
305 #[inline]
306 fn new<F>(f: F) -> Self
307 where F: FnOnce(&Point) -> simulation::Result<T> + Clone + 'static
308 {
309 EventBox {
310 f: Box::new(f)
311 }
312 }
313
314 #[doc(hidden)]
316 #[inline]
317 pub fn call_box(self, arg: (&Point,)) -> simulation::Result<T> {
318 let EventBox { f } = self;
319 f.call_box(arg)
320 }
321}
322
323impl<T> Clone for EventBox<T> {
324
325 fn clone(&self) -> Self {
326 EventBox {
327 f: self.f.call_clone()
328 }
329 }
330}
331
332impl<T> Event for EventBox<T> {
333
334 type Item = T;
335
336 #[inline]
337 fn call_event(self, p: &Point) -> simulation::Result<Self::Item> {
338 self.call_box((p,))
339 }
340
341 #[inline]
342 fn into_boxed(self) -> EventBox<Self::Item>
343 where Self: Sized + Clone + 'static
344 {
345 self
346 }
347}
348
349trait EventFnBox<T> {
351
352 fn call_box(self: Box<Self>, args: (&Point,)) -> simulation::Result<T>;
354}
355
356impl<T, F> EventFnBox<T> for F
357 where F: for<'a> FnOnce(&'a Point) -> simulation::Result<T>
358{
359 fn call_box(self: Box<Self>, args: (&Point,)) -> simulation::Result<T> {
360 let this: Self = *self;
361 this(args.0)
362 }
363}
364
365trait EventFnBoxClone<T>: EventFnBox<T> {
367
368 fn call_clone(&self) -> Box<dyn EventFnBoxClone<T>>;
370}
371
372impl<T, F> EventFnBoxClone<T> for F
373 where F: for<'a> FnOnce(&'a Point) -> simulation::Result<T> + Clone + 'static
374{
375 fn call_clone(&self) -> Box<dyn EventFnBoxClone<T>> {
376 Box::new(self.clone())
377 }
378}
379
380#[cfg(feature="dist_mode")]
382#[repr(C)]
383#[derive(Copy, Clone)]
384struct EventTraitObject {
385
386 field1: *mut c_void,
387 field2: *mut c_void
388}
389
390#[cfg(feature="dist_mode")]
392#[repr(C)]
393pub struct EventRepr {
394
395 delete: unsafe extern "C" fn(obj: *mut EventTraitObject),
397
398 clone: unsafe extern "C" fn(obj: *const EventTraitObject) -> EventRepr,
400
401 callback: unsafe extern "C" fn(obj: *mut EventTraitObject, p: *const Point) -> *mut ErrorRepr,
403
404 trait_object: EventTraitObject
406}
407
408#[cfg(feature="dist_mode")]
409impl Drop for EventRepr {
410
411 fn drop(&mut self) {
412 unsafe {
413 (self.delete)(&mut self.trait_object);
414 }
415 }
416}
417
418#[cfg(feature="dist_mode")]
419impl Clone for EventRepr {
420
421 fn clone(&self) -> Self {
422 unsafe {
423 (self.clone)(&self.trait_object)
424 }
425 }
426}
427
428#[cfg(feature="dist_mode")]
429impl EventRepr {
430
431 #[inline]
433 pub fn into_repr(comp: EventBox<()>) -> EventRepr {
434 unsafe {
435 EventRepr {
436 delete: delete_event_repr,
437 clone: clone_event_repr,
438 callback: call_event_repr,
439 trait_object: mem::transmute(comp)
440 }
441 }
442 }
443
444 #[inline]
446 fn call_repr(mut self, p: &Point) -> *mut ErrorRepr {
447 unsafe {
448 let x = (self.callback)(&mut self.trait_object, p);
449 mem::forget(self);
450 x
451 }
452 }
453}
454
455#[cfg(feature="dist_mode")]
457unsafe extern "C" fn call_event_repr(comp: *mut EventTraitObject, p: *const Point) -> *mut ErrorRepr {
458 let comp: EventBox<()> = mem::transmute(*comp);
459 match comp.call_box((&*p,)) {
460 Result::Ok(()) => ptr::null_mut(),
461 Result::Err(e) => {
462 let e = ErrorRepr::new(e);
463 Box::into_raw(Box::new(e))
464 }
465 }
466}
467
468#[cfg(feature="dist_mode")]
470unsafe extern "C" fn clone_event_repr(comp: *const EventTraitObject) -> EventRepr {
471 let comp: EventBox<()> = mem::transmute(*comp);
472 let x = EventRepr {
473 delete: delete_event_repr,
474 clone: clone_event_repr,
475 callback: call_event_repr,
476 trait_object: mem::transmute(comp.clone())
477 };
478 mem::forget(comp);
479 x
480}
481
482#[cfg(feature="dist_mode")]
484unsafe extern "C" fn delete_event_repr(comp: *mut EventTraitObject) {
485 let _: EventBox<()> = mem::transmute(*comp);
486}
487
488#[cfg(feature="dist_mode")]
489impl Event for EventRepr {
490
491 type Item = ();
492
493 #[doc(hidden)]
494 #[inline]
495 fn call_event(self, p: &Point) -> simulation::Result<Self::Item> {
496 unsafe {
497 let e = self.call_repr(p);
498 if e == ptr::null_mut() {
499 Result::Ok(())
500 } else {
501 let e = ffi_error_repr_into_error(e);
502 Result::Err(e)
503 }
504 }
505 }
506}
507
508#[cfg(any(feature="branch_mode", feature="branch_wasm_mode"))]
510#[derive(Clone)]
511pub struct EventRepr {
512
513 comp: EventBox<()>
515}
516
517#[cfg(any(feature="branch_mode", feature="branch_wasm_mode"))]
518impl EventRepr {
519
520 #[inline]
522 pub fn into_repr(comp: EventBox<()>) -> EventRepr {
523 EventRepr { comp: comp }
524 }
525
526 #[inline]
528 fn call_repr(self, p: &Point) -> simulation::Result<()> {
529 self.comp.call_event(p)
530 }
531}
532
533#[cfg(any(feature="branch_mode", feature="branch_wasm_mode"))]
534impl Event for EventRepr {
535
536 type Item = ();
537
538 #[doc(hidden)]
539 #[inline]
540 fn call_event(self, p: &Point) -> simulation::Result<Self::Item> {
541 self.call_repr(p)
542 }
543}
544
545#[cfg(feature="dist_mode")]
547#[repr(C)]
548#[derive(Copy, Clone)]
549struct DisposableEventTraitObject {
550
551 field1: *mut c_void,
552 field2: *mut c_void
553}
554
555#[cfg(feature="dist_mode")]
557#[repr(C)]
558pub struct DisposableEventRepr {
559
560 delete: unsafe extern "C" fn(obj: *mut DisposableEventTraitObject),
562
563 clone: unsafe extern "C" fn(obj: *const DisposableEventTraitObject) -> DisposableEventRepr,
565
566 callback: unsafe extern "C" fn(obj: *mut DisposableEventTraitObject, p: *const Point, e: *mut *mut ErrorRepr) -> DisposableRepr,
568
569 trait_object: DisposableEventTraitObject
571}
572
573#[cfg(feature="dist_mode")]
574impl Drop for DisposableEventRepr {
575
576 fn drop(&mut self) {
577 unsafe {
578 (self.delete)(&mut self.trait_object);
579 }
580 }
581}
582
583#[cfg(feature="dist_mode")]
584impl Clone for DisposableEventRepr {
585
586 fn clone(&self) -> Self {
587 unsafe {
588 (self.clone)(&self.trait_object)
589 }
590 }
591}
592
593#[cfg(feature="dist_mode")]
594impl DisposableEventRepr {
595
596 #[inline]
598 pub fn into_repr(comp: EventBox<DisposableRepr>) -> DisposableEventRepr {
599 unsafe {
600 DisposableEventRepr {
601 delete: delete_disposable_event_repr,
602 clone: clone_disposable_event_repr,
603 callback: call_disposable_event_repr,
604 trait_object: mem::transmute(comp)
605 }
606 }
607 }
608
609 #[inline]
611 fn call_repr(mut self, p: &Point, e: *mut *mut ErrorRepr) -> DisposableRepr {
612 unsafe {
613 let x = (self.callback)(&mut self.trait_object, p, e);
614 mem::forget(self);
615 x
616 }
617 }
618}
619
620#[cfg(feature="dist_mode")]
622unsafe extern "C" fn call_disposable_event_repr(comp: *mut DisposableEventTraitObject, p: *const Point, e: *mut *mut ErrorRepr) -> DisposableRepr {
623 let comp: EventBox<DisposableRepr> = mem::transmute(*comp);
624 match comp.call_box((&*p,)) {
625 Result::Ok(x) => {
626 *e = ptr::null_mut();
627 x
628 },
629 Result::Err(e0) => {
630 let e0 = ErrorRepr::new(e0);
631 let e0 = Box::new(e0);
632 let e0 = Box::into_raw(e0);
633 *e = e0;
634
635 let x = empty_disposable();
636 let x = x.into_boxed();
637 let x = DisposableRepr::into_repr(x);
638 x
639 }
640 }
641}
642
643#[cfg(feature="dist_mode")]
645unsafe extern "C" fn clone_disposable_event_repr(comp: *const DisposableEventTraitObject) -> DisposableEventRepr {
646 let comp: EventBox<DisposableRepr> = mem::transmute(*comp);
647 let x = DisposableEventRepr {
648 delete: delete_disposable_event_repr,
649 clone: clone_disposable_event_repr,
650 callback: call_disposable_event_repr,
651 trait_object: mem::transmute(comp.clone())
652 };
653 mem::forget(comp);
654 x
655}
656
657#[cfg(feature="dist_mode")]
659unsafe extern "C" fn delete_disposable_event_repr(comp: *mut DisposableEventTraitObject) {
660 let _: EventBox<DisposableRepr> = mem::transmute(*comp);
661}
662
663#[cfg(feature="dist_mode")]
664impl Event for DisposableEventRepr {
665
666 type Item = DisposableRepr;
667
668 #[doc(hidden)]
669 #[inline]
670 fn call_event(self, p: &Point) -> simulation::Result<Self::Item> {
671 unsafe {
672 let mut e: *mut ErrorRepr = ptr::null_mut();
673 let x = self.call_repr(p, &mut e);
674 if e == ptr::null_mut() {
675 Result::Ok(x)
676 } else {
677 let e = ffi_error_repr_into_error(e);
678 Result::Err(e)
679 }
680 }
681 }
682}
683
684#[must_use = "computations are lazy and do nothing unless to be run"]
686#[derive(Clone)]
687pub struct Return<T> {
688
689 val: T
691}
692
693impl<T> Event for Return<T> {
694
695 type Item = T;
696
697 #[doc(hidden)]
698 #[inline]
699 fn call_event(self, _: &Point) -> simulation::Result<T> {
700 let Return { val } = self;
701 Result::Ok(val)
702 }
703}
704
705#[must_use = "computations are lazy and do nothing unless to be run"]
707#[derive(Clone)]
708pub struct Delay<F, M> {
709
710 f: F,
712
713 _phantom: PhantomData<M>
715}
716
717impl<F, M> Event for Delay<F, M>
718 where F: FnOnce() -> M,
719 M: Event
720{
721 type Item = M::Item;
722
723 #[doc(hidden)]
724 #[inline]
725 fn call_event(self, p: &Point) -> simulation::Result<M::Item> {
726 let Delay { f, _phantom } = self;
727 f().call_event(p)
728 }
729}
730
731#[must_use = "computations are lazy and do nothing unless to be run"]
733#[derive(Clone)]
734pub struct Cons<F, T> {
735
736 f: F,
738
739 _phantom: PhantomData<T>
741}
742
743impl<F, T> Event for Cons<F, T>
744 where F: FnOnce(&Point) -> simulation::Result<T>
745{
746 type Item = T;
747
748 #[doc(hidden)]
749 #[inline]
750 fn call_event(self, p: &Point) -> simulation::Result<T> {
751 let Cons { f, _phantom } = self;
752 f(p)
753 }
754}
755
756#[must_use = "computations are lazy and do nothing unless to be run"]
758#[derive(Clone)]
759pub struct Enqueue {
760
761 time: f64,
763
764 comp: EventBox<()>
766}
767
768impl Event for Enqueue {
769
770 type Item = ();
771
772 #[cfg(any(feature="branch_mode", feature="branch_wasm_mode"))]
773 #[doc(hidden)]
774 #[inline]
775 fn call_event(self, p: &Point) -> simulation::Result<()> {
776 let Enqueue { time, comp } = self;
777 let run = p.run;
778 let queue = &run.event_queue;
779 let comp = EventRepr::into_repr(comp);
780 queue.enqueue_event(time, p.priority, comp, p);
781 Result::Ok(())
782 }
783
784 #[cfg(feature="dist_mode")]
785 #[doc(hidden)]
786 #[inline]
787 fn call_event(self, p: &Point) -> simulation::Result<()> {
788 let Enqueue { time, comp } = self;
789 let run = p.run;
790 let queue = run.event_queue;
791 let comp = EventRepr::into_repr(comp);
792 unsafe {
793 enqueue_extern_event(queue, time, p.priority, comp, p);
794 }
795 Result::Ok(())
796 }
797}
798
799#[must_use = "computations are lazy and do nothing unless to be run"]
801pub struct EnqueueWithPriority {
802
803 time: f64,
805
806 priority: isize,
808
809 comp: EventBox<()>
811}
812
813impl Event for EnqueueWithPriority {
814
815 type Item = ();
816
817 #[cfg(any(feature="branch_mode", feature="branch_wasm_mode"))]
818 #[doc(hidden)]
819 #[inline]
820 fn call_event(self, p: &Point) -> simulation::Result<()> {
821 let EnqueueWithPriority { time, priority, comp } = self;
822 let run = p.run;
823 let queue = &run.event_queue;
824 let comp = EventRepr::into_repr(comp);
825 queue.enqueue_event(time, priority, comp, p);
826 Result::Ok(())
827 }
828
829 #[cfg(feature="dist_mode")]
830 #[doc(hidden)]
831 #[inline]
832 fn call_event(self, p: &Point) -> simulation::Result<()> {
833 let EnqueueWithPriority { time, priority, comp } = self;
834 let run = p.run;
835 let queue = run.event_queue;
836 let comp = EventRepr::into_repr(comp);
837 unsafe {
838 enqueue_extern_event(queue, time, priority, comp, p);
839 }
840 Result::Ok(())
841 }
842}
843
844#[must_use = "computations are lazy and do nothing unless to be run"]
846#[derive(Clone)]
847pub struct EnqueueWithIntegTimes<F> {
848
849 f: F
851}
852
853impl<F> Event for EnqueueWithIntegTimes<F>
854 where F: Fn() -> EventBox<()> + Clone + 'static
855{
856 type Item = ();
857
858 #[doc(hidden)]
859 #[inline]
860 fn call_event(self, p: &Point) -> simulation::Result<()> {
861 let EnqueueWithIntegTimes { f } = self;
862 let comp = EnqueueWithIntegTimesLoop { f, iteration: p.iteration };
863 enqueue_event(p.time, comp.into_boxed())
864 .call_event(p)
865 }
866}
867
868#[must_use = "computations are lazy and do nothing unless to be run"]
870#[derive(Clone)]
871struct EnqueueWithIntegTimesLoop<F> {
872
873 f: F,
875
876 iteration: usize
878}
879
880impl<F> Event for EnqueueWithIntegTimesLoop<F>
881 where F: Fn() -> EventBox<()> + Clone + 'static
882{
883 type Item = ();
884
885 #[doc(hidden)]
886 #[inline]
887 fn call_event(self, p: &Point) -> simulation::Result<()> {
888 let EnqueueWithIntegTimesLoop { f, iteration } = self;
889 let comp = f();
890 let p = p.with_iteration(iteration); comp.call_event(&p)?;
892 let p2 = p.with_iteration(1 + iteration);
893 let comp = EnqueueWithIntegTimesLoop { f, iteration: p2.iteration };
894 enqueue_event(p2.time, comp.into_boxed())
895 .call_event(&p)
896 }
897}
898
899#[must_use = "computations are lazy and do nothing unless to be run"]
901pub struct EnqueueIO {
902
903 time: f64,
905
906 comp: EventBox<()>
908}
909
910impl Event for EnqueueIO {
911
912 type Item = ();
913
914 #[cfg(any(feature="branch_mode", feature="branch_wasm_mode"))]
915 #[doc(hidden)]
916 #[inline]
917 fn call_event(self, p: &Point) -> simulation::Result<()> {
918 let EnqueueIO { time, comp } = self;
919 let run = p.run;
920 let queue = &run.event_queue;
921 let comp = EventRepr::into_repr(comp);
922 queue.enqueue_io_event(time, p.priority, comp, p);
923 Result::Ok(())
924 }
925
926 #[cfg(feature="dist_mode")]
927 #[doc(hidden)]
928 #[inline]
929 fn call_event(self, p: &Point) -> simulation::Result<()> {
930 let EnqueueIO { time, comp } = self;
931 let run = p.run;
932 let queue = run.event_queue;
933 let comp = EventRepr::into_repr(comp);
934 unsafe {
935 enqueue_extern_io_event(queue, time, p.priority, comp, p);
936 }
937 Result::Ok(())
938 }
939}
940
941#[must_use = "computations are lazy and do nothing unless to be run"]
943pub struct EnqueueIOWithPriority {
944
945 time: f64,
947
948 priority: isize,
950
951 comp: EventBox<()>
953}
954
955impl Event for EnqueueIOWithPriority {
956
957 type Item = ();
958
959 #[cfg(any(feature="branch_mode", feature="branch_wasm_mode"))]
960 #[doc(hidden)]
961 #[inline]
962 fn call_event(self, p: &Point) -> simulation::Result<()> {
963 let EnqueueIOWithPriority { time, priority, comp } = self;
964 let run = p.run;
965 let queue = &run.event_queue;
966 let comp = EventRepr::into_repr(comp);
967 queue.enqueue_io_event(time, priority, comp, p);
968 Result::Ok(())
969 }
970
971 #[cfg(feature="dist_mode")]
972 #[doc(hidden)]
973 #[inline]
974 fn call_event(self, p: &Point) -> simulation::Result<()> {
975 let EnqueueIOWithPriority { time, priority, comp } = self;
976 let run = p.run;
977 let queue = run.event_queue;
978 let comp = EventRepr::into_repr(comp);
979 unsafe {
980 enqueue_extern_io_event(queue, time, priority, comp, p);
981 }
982 Result::Ok(())
983 }
984}
985
986#[must_use = "computations are lazy and do nothing unless to be run"]
988#[derive(Clone)]
989pub struct EnqueueIOWithIntegTimes<F> {
990
991 f: F
993}
994
995impl<F> Event for EnqueueIOWithIntegTimes<F>
996 where F: Fn() -> EventBox<()> + Clone + 'static
997{
998 type Item = ();
999
1000 #[doc(hidden)]
1001 #[inline]
1002 fn call_event(self, p: &Point) -> simulation::Result<()> {
1003 let EnqueueIOWithIntegTimes { f } = self;
1004 let comp = EnqueueIOWithIntegTimesLoop { f, iteration: p.iteration };
1005 enqueue_io_event(p.time, comp.into_boxed())
1006 .call_event(p)
1007 }
1008}
1009
1010#[must_use = "computations are lazy and do nothing unless to be run"]
1012#[derive(Clone)]
1013struct EnqueueIOWithIntegTimesLoop<F> {
1014
1015 f: F,
1017
1018 iteration: usize
1020}
1021
1022impl<F> Event for EnqueueIOWithIntegTimesLoop<F>
1023 where F: Fn() -> EventBox<()> + Clone + 'static
1024{
1025 type Item = ();
1026
1027 #[doc(hidden)]
1028 #[inline]
1029 fn call_event(self, p: &Point) -> simulation::Result<()> {
1030 let EnqueueIOWithIntegTimesLoop { f, iteration } = self;
1031 let comp = f();
1032 let p = p.with_iteration(iteration); comp.call_event(&p)?;
1034 let p2 = p.with_iteration(1 + iteration);
1035 let comp = EnqueueIOWithIntegTimesLoop { f, iteration: p2.iteration };
1036 enqueue_io_event(p2.time, comp.into_boxed())
1037 .call_event(&p)
1038 }
1039}
1040
1041#[must_use = "computations are lazy and do nothing unless to be run"]
1043#[derive(Clone)]
1044pub struct AndThen<M, U, F> {
1045
1046 comp: M,
1048
1049 f: F,
1051
1052 _phantom: PhantomData<U>
1054}
1055
1056impl<M, U, F> Event for AndThen<M, U, F>
1057 where M: Event,
1058 U: Event,
1059 F: FnOnce(M::Item) -> U,
1060{
1061 type Item = U::Item;
1062
1063 #[doc(hidden)]
1064 #[inline]
1065 fn call_event(self, p: &Point) -> simulation::Result<U::Item> {
1066 let AndThen { comp, f, _phantom } = self;
1067 match comp.call_event(p) {
1068 Result::Ok(a) => {
1069 let m = f(a);
1070 m.call_event(p)
1071 },
1072 Result::Err(e) => {
1073 Result::Err(e)
1074 }
1075 }
1076 }
1077}
1078
1079#[must_use = "computations are lazy and do nothing unless to be run"]
1081#[derive(Clone)]
1082pub struct Map<M, B, F> {
1083
1084 comp: M,
1086
1087 f: F,
1089
1090 _phantom: PhantomData<B>
1092}
1093
1094impl<M, B, F> Event for Map<M, B, F>
1095 where M: Event,
1096 F: FnOnce(M::Item) -> B,
1097{
1098 type Item = B;
1099
1100 #[doc(hidden)]
1101 #[inline]
1102 fn call_event(self, p: &Point) -> simulation::Result<B> {
1103 let Map { comp, f, _phantom } = self;
1104 match comp.call_event(p) {
1105 Result::Ok(a) => Result::Ok(f(a)),
1106 Result::Err(e) => Result::Err(e)
1107 }
1108 }
1109}
1110
1111#[must_use = "computations are lazy and do nothing unless to be run"]
1113#[derive(Clone)]
1114pub struct Zip<M, U> {
1115
1116 comp: M,
1118
1119 other: U,
1121}
1122
1123impl<M, U> Event for Zip<M, U>
1124 where M: Event,
1125 U: Event
1126{
1127 type Item = (M::Item, U::Item);
1128
1129 #[doc(hidden)]
1130 #[inline]
1131 fn call_event(self, p: &Point) -> simulation::Result<(M::Item, U::Item)> {
1132 let Zip { comp, other } = self;
1133 comp.and_then(move |a| {
1134 other.map(move |b| (a, b))
1135 }).call_event(p)
1136 }
1137}
1138
1139#[must_use = "computations are lazy and do nothing unless to be run"]
1141#[derive(Clone)]
1142pub struct Ap<M, U, B> {
1143
1144 comp: M,
1146
1147 other: U,
1149
1150 _phantom: PhantomData<B>
1152}
1153
1154impl<M, U, B> Event for Ap<M, U, B>
1155 where M: Event,
1156 U: Event,
1157 M::Item: FnOnce(U::Item) -> B,
1158{
1159 type Item = B;
1160
1161 #[doc(hidden)]
1162 #[inline]
1163 fn call_event(self, p: &Point) -> simulation::Result<B> {
1164 let Ap { comp, other, _phantom } = self;
1165 comp.and_then(move |f| {
1166 other.map(move |a| { f(a) })
1167 }).call_event(p)
1168 }
1169}
1170
1171#[must_use = "computations are lazy and do nothing unless to be run"]
1173#[derive(Clone)]
1174pub struct RunInStartTime<M> {
1175
1176 comp: M,
1178
1179 including_current_events: bool
1181}
1182
1183impl<M> Simulation for RunInStartTime<M>
1184 where M: Event
1185{
1186 type Item = M::Item;
1187
1188 #[cfg(any(feature="branch_mode", feature="branch_wasm_mode"))]
1189 #[doc(hidden)]
1190 #[inline]
1191 fn call_simulation(self, r: &Run) -> simulation::Result<M::Item> {
1192 let RunInStartTime { comp, including_current_events } = self;
1193 let p = r.point_in_start_time();
1194 let queue = &r.event_queue;
1195 queue.run_events(including_current_events, &p)?;
1196 comp.call_event(&p)
1197 }
1198
1199 #[cfg(feature="dist_mode")]
1200 #[doc(hidden)]
1201 #[inline]
1202 fn call_simulation(self, r: &Run) -> simulation::Result<M::Item> {
1203 let RunInStartTime { comp, including_current_events } = self;
1204 let p = r.point_in_start_time();
1205 let including_current_events = if including_current_events { 1 } else { 0 };
1206 unsafe {
1207 sync_extern_events(including_current_events, &p);
1208 }
1209 comp.call_event(&p)
1210 }
1211}
1212
1213#[must_use = "computations are lazy and do nothing unless to be run"]
1215#[derive(Clone)]
1216pub struct RunInStopTime<M> {
1217
1218 comp: M,
1220
1221 including_current_events: bool
1223}
1224
1225impl<M> Simulation for RunInStopTime<M>
1226 where M: Event
1227{
1228 type Item = M::Item;
1229
1230 #[cfg(any(feature="branch_mode", feature="branch_wasm_mode"))]
1231 #[doc(hidden)]
1232 #[inline]
1233 fn call_simulation(self, r: &Run) -> simulation::Result<M::Item> {
1234 let RunInStopTime { comp, including_current_events } = self;
1235 let p = r.point_in_stop_time();
1236 let queue = &r.event_queue;
1237 queue.run_events(including_current_events, &p)?;
1238 comp.call_event(&p)
1239 }
1240
1241 #[cfg(feature="dist_mode")]
1242 #[doc(hidden)]
1243 #[inline]
1244 fn call_simulation(self, r: &Run) -> simulation::Result<M::Item> {
1245 let RunInStopTime { comp, including_current_events } = self;
1246 let p = r.point_in_stop_time();
1247 let including_current_events = if including_current_events { 1 } else { 0 };
1248 unsafe {
1249 sync_extern_events(including_current_events, &p);
1250 }
1251 comp.call_event(&p)
1252 }
1253}
1254
1255#[must_use = "computations are lazy and do nothing unless to be run"]
1257#[derive(Clone)]
1258pub struct Time {}
1259
1260impl Event for Time {
1261
1262 type Item = f64;
1263
1264 #[doc(hidden)]
1265 #[inline]
1266 fn call_event(self, p: &Point) -> simulation::Result<f64> {
1267 Result::Ok(p.time)
1268 }
1269}
1270
1271#[must_use = "computations are lazy and do nothing unless to be run"]
1273#[derive(Clone)]
1274pub struct Priority {}
1275
1276impl Event for Priority {
1277
1278 type Item = isize;
1279
1280 #[doc(hidden)]
1281 #[inline]
1282 fn call_event(self, p: &Point) -> simulation::Result<isize> {
1283 Result::Ok(p.priority)
1284 }
1285}
1286
1287#[must_use = "computations are lazy and do nothing unless to be run"]
1289#[derive(Clone)]
1290pub struct EventIntoProcess<M> {
1291
1292 comp: M
1294}
1295
1296impl<M> Process for EventIntoProcess<M>
1297 where M: Event
1298{
1299 type Item = M::Item;
1300
1301 #[doc(hidden)]
1302 #[inline]
1303 fn call_process<C>(self, cont: C, pid: Grc<ProcessId>, p: &Point) -> simulation::Result<()>
1304 where C: FnOnce(simulation::Result<Self::Item>, Grc<ProcessId>, &Point) -> simulation::Result<()> + Clone + 'static
1305 {
1306 if is_process_cancelled(&pid, p) {
1307 revoke_process(cont, pid, p)
1308 } else {
1309 let EventIntoProcess { comp } = self;
1310 let t = comp.call_event(p);
1311 cont(t, pid, p)
1312 }
1313 }
1314
1315 #[doc(hidden)]
1316 #[inline]
1317 fn call_process_boxed(self, cont: ProcessBoxCont<Self::Item>, pid: Grc<ProcessId>, p: &Point) -> simulation::Result<()> {
1318 if is_process_cancelled(&pid, p) {
1319 revoke_process_boxed(cont, pid, p)
1320 } else {
1321 let EventIntoProcess { comp } = self;
1322 let t = comp.call_event(p);
1323 cont.call_box((t, pid, p))
1324 }
1325 }
1326}
1327
1328#[must_use = "computations are lazy and do nothing unless to be run"]
1330#[derive(Clone)]
1331pub struct EventIntoComposite<M> {
1332
1333 comp: M
1335}
1336
1337impl<M> Composite for EventIntoComposite<M>
1338 where M: Event
1339{
1340 type Item = M::Item;
1341
1342 #[doc(hidden)]
1343 #[inline]
1344 fn call_composite(self, disposable: DisposableBox, p: &Point) -> simulation::Result<(M::Item, DisposableBox)> {
1345 let EventIntoComposite { comp } = self;
1346 let a = comp.call_event(p)?;
1347 Result::Ok((a, disposable))
1348 }
1349}
1350
1351#[must_use = "computations are lazy and do nothing unless to be run"]
1353#[derive(Clone)]
1354pub struct Sequence<I, M> {
1355
1356 comps: I,
1358
1359 _phantom: PhantomData<M>
1361}
1362
1363impl<I, M> Event for Sequence<I, M>
1364 where I: Iterator<Item = M>,
1365 M: Event
1366{
1367 type Item = Vec<M::Item>;
1368
1369 #[doc(hidden)]
1370 fn call_event(self, p: &Point) -> simulation::Result<Self::Item> {
1371 let Sequence { comps, _phantom } = self;
1372 let mut v = {
1373 match comps.size_hint() {
1374 (_, Some(n)) => Vec::with_capacity(n),
1375 (_, None) => Vec::new()
1376 }
1377 };
1378 for m in comps {
1379 match m.call_event(p) {
1380 Result::Ok(a) => {
1381 v.push(a)
1382 },
1383 Result::Err(e) => {
1384 return Result::Err(e)
1385 }
1386 }
1387 }
1388 Result::Ok(v)
1389 }
1390}
1391
1392#[must_use = "computations are lazy and do nothing unless to be run"]
1394#[derive(Clone)]
1395pub struct Sequence_<I, M> {
1396
1397 comps: I,
1399
1400 _phantom: PhantomData<M>
1402}
1403
1404impl<I, M> Event for Sequence_<I, M>
1405 where I: Iterator<Item = M>,
1406 M: Event
1407{
1408 type Item = ();
1409
1410 #[doc(hidden)]
1411 fn call_event(self, p: &Point) -> simulation::Result<Self::Item> {
1412 let Sequence_ { comps, _phantom } = self;
1413 for m in comps {
1414 match m.call_event(p) {
1415 Result::Ok(_) => (),
1416 Result::Err(e) => return Result::Err(e)
1417 }
1418 }
1419 Result::Ok(())
1420 }
1421}
1422
1423#[must_use = "computations are lazy and do nothing unless to be run"]
1425#[derive(Clone)]
1426pub struct Yield<M> {
1427
1428 comp: M
1430}
1431
1432impl<M> Event for Yield<M>
1433 where M: Event<Item = ()> + Clone + 'static
1434{
1435 type Item = ();
1436
1437 #[doc(hidden)]
1438 #[inline]
1439 fn call_event(self, p: &Point) -> simulation::Result<Self::Item> {
1440 let Yield { comp } = self;
1441 enqueue_event(p.time, comp.into_boxed()).call_event(p)
1442 }
1443}
1444
1445#[cfg(feature="dist_mode")]
1447#[must_use = "computations are lazy and do nothing unless to be run"]
1448#[derive(Clone)]
1449pub struct LeaveSimulation {}
1450
1451#[cfg(feature="dist_mode")]
1452impl Event for LeaveSimulation {
1453
1454 type Item = ();
1455
1456 #[doc(hidden)]
1457 #[inline]
1458 fn call_event(self, p: &Point) -> simulation::Result<Self::Item> {
1459 let LeaveSimulation {} = self;
1460 let r = p.run;
1461 let q = r.event_queue;
1462 unsafe {
1463 leave_extern_simulation(q, p);
1464 }
1465 Result::Ok(())
1466 }
1467}
1468
1469#[must_use = "computations are lazy and do nothing unless to be run"]
1471#[derive(Clone)]
1472pub struct Trace<M> {
1473
1474 comp: M,
1476
1477 msg: String
1479}
1480
1481impl<M> Event for Trace<M>
1482 where M: Event
1483{
1484 type Item = M::Item;
1485
1486 #[doc(hidden)]
1487 #[inline]
1488 fn call_event(self, p: &Point) -> simulation::Result<Self::Item> {
1489 let Trace { comp, msg } = self;
1490 p.trace(&msg);
1491 comp.call_event(p)
1492 }
1493}