des_sim/context/
source.rs1use crate::context::UserContext;
7use crate::event_scheduler::EventScheduler;
8use crate::modeling::event::EventPriority;
9use crate::modeling::hook::Hook;
10use crate::modeling::hook::instance::HookDelegate;
11use crate::modeling::model::Model;
12use crate::primitive::time::{Duration, MicroStep, SimTime};
13use crate::primitive::time::{MicroStepStatus, TickStatus};
14use crate::source_handler::SourceHandler;
15
16pub struct SourceContext<E, M: Model<E>> {
21 pub(crate) current_tick_status: TickStatus,
22 pub(crate) current_micro_step_status: MicroStepStatus,
23 pub(crate) hook_delegate: HookDelegate<E, M>,
24 pub(crate) source_handler: Option<SourceHandler<E, M>>,
30 pub(crate) event_scheduler: EventScheduler<E>,
31}
32
33impl<E, M: Model<E>> UserContext<E, M> for SourceContext<E, M> {
34 fn current_tick(&self) -> SimTime {
35 self.current_tick_status.current()
36 }
37
38 fn current_micro_step(&self) -> MicroStep {
39 self.current_micro_step_status.current()
40 }
41
42 fn schedule_event(&mut self, delay: Duration, priority: EventPriority, event_payload: E) {
43 self.event_scheduler
44 .schedule(self.current_tick(), delay, priority, event_payload);
45 }
46}
47
48impl<E, M: Model<E>> SourceContext<E, M> {
49 pub(crate) fn hook(&self) -> &impl Hook<E, M> {
51 &self.hook_delegate
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use crate::context::EventContext;
59 use crate::event_scheduler::EventScheduler;
60 use crate::modeling::event::{Event, EventPriority};
61 use crate::modeling::hook::instance::HookDelegate;
62 use crate::modeling::model::Model;
63 use crate::primitive::time::{Duration, MicroStep, SimTime};
64 use crate::primitive::time::{MicroStepStatus, TickStatus};
65
66 #[derive(Debug, PartialEq)]
67 enum TestEvent {
68 EventA,
69 }
70
71 struct TestModel;
72
73 impl Model<TestEvent> for TestModel {
74 fn handle_event(
75 &mut self,
76 _context: &mut EventContext<TestEvent, Self>,
77 _event: &Event<TestEvent>,
78 ) {
79 }
81 }
82
83 fn create_test_source_context() -> SourceContext<TestEvent, TestModel> {
85 SourceContext {
86 current_tick_status: TickStatus::new(SimTime::from_ticks(0), Duration::zero()),
87 current_micro_step_status: MicroStepStatus::new(MicroStep::zero()),
88 hook_delegate: HookDelegate::new(),
89 source_handler: None,
90 event_scheduler: EventScheduler::new(),
91 }
92 }
93
94 #[test]
95 fn test_current_tick() {
96 let context = create_test_source_context();
97 assert_eq!(context.current_tick(), SimTime::from_ticks(0));
98 }
99
100 #[test]
101 fn test_current_micro_step() {
102 let context = create_test_source_context();
103 assert_eq!(context.current_micro_step(), MicroStep::zero());
104 }
105
106 #[test]
107 fn test_schedule_event() {
108 let mut context = create_test_source_context();
109
110 context.event_scheduler.schedule(
112 SimTime::from_ticks(0),
113 Duration::one(),
114 EventPriority::minimum(),
115 TestEvent::EventA,
116 );
117 context.event_scheduler.schedule(
118 SimTime::from_ticks(0),
119 Duration::one(),
120 EventPriority::minimum(),
121 TestEvent::EventA,
122 );
123 context.event_scheduler.schedule(
124 SimTime::from_ticks(0),
125 Duration::one(),
126 EventPriority::minimum(),
127 TestEvent::EventA,
128 );
129
130 context.event_scheduler.flush_pending();
132 let initial_event_count = context.event_scheduler.ready_queue_len();
133
134 context.schedule_event(Duration::one(), EventPriority::minimum(), TestEvent::EventA);
136 context.event_scheduler.flush_pending();
137
138 assert_eq!(
139 context.event_scheduler.ready_queue_len(),
140 initial_event_count + 1
141 );
142 }
143}