1use crate::modeling::event::Event;
9use crate::modeling::hook::Hook;
10use crate::modeling::model::Model;
11use crate::primitive::time::{Duration, MicroStep, SimTime};
12use crate::source_handler::{SourceReadyEntry, SourceView};
13use std::marker::PhantomData;
14use std::sync::Arc;
15
16pub struct SharedHook<E, M: Model<E>, H: Hook<E, M>> {
18 inner: Arc<H>,
19 _event: PhantomData<E>,
20 _model: PhantomData<M>,
21}
22
23impl<E, M: Model<E>, H: Hook<E, M>> Clone for SharedHook<E, M, H> {
24 fn clone(&self) -> Self {
25 SharedHook {
26 inner: Arc::clone(&self.inner),
27 _event: PhantomData,
28 _model: PhantomData,
29 }
30 }
31}
32
33impl<E, M: Model<E>, H> Hook<E, M> for SharedHook<E, M, H>
34where
35 H: Hook<E, M>,
36{
37 fn before_simulation(&self, model: &M) {
40 self.inner.as_ref().before_simulation(model)
41 }
42
43 fn after_simulation(&self, model: &M, end_tick: SimTime) {
44 self.inner.as_ref().after_simulation(model, end_tick)
45 }
46
47 fn before_tick(&self, model: &M, current_tick: SimTime, skipped_duration: Duration) {
50 self.inner
51 .as_ref()
52 .before_tick(model, current_tick, skipped_duration)
53 }
54
55 fn after_tick(&self, model: &M, current_tick: SimTime, last_micro_step: MicroStep) {
56 self.inner
57 .as_ref()
58 .after_tick(model, current_tick, last_micro_step)
59 }
60
61 fn before_micro_step(&self, model: &M, current_tick: SimTime, current_micro_step: MicroStep) {
62 self.inner
63 .as_ref()
64 .before_micro_step(model, current_tick, current_micro_step)
65 }
66
67 fn after_micro_step(&self, model: &M, current_tick: SimTime, current_micro_step: MicroStep) {
68 self.inner
69 .as_ref()
70 .after_micro_step(model, current_tick, current_micro_step)
71 }
72
73 fn on_discard_remain_micro_step(
74 &self,
75 model: &M,
76 current_tick: SimTime,
77 first_discarded_micro_step: MicroStep,
78 discarded_sources: &[SourceReadyEntry],
79 discarded_events: &[Event<E>],
80 ) {
81 self.inner.as_ref().on_discard_remain_micro_step(
82 model,
83 current_tick,
84 first_discarded_micro_step,
85 discarded_sources,
86 discarded_events,
87 )
88 }
89
90 fn before_register_source(&self, model: &M, name: &str) {
93 self.inner.as_ref().before_register_source(model, name)
94 }
95
96 fn after_register_source(&self, model: &M, name: &str) {
97 self.inner.as_ref().after_register_source(model, name)
98 }
99
100 fn before_source_phase(&self, model: &M, current_tick: SimTime, current_micro_step: MicroStep) {
101 self.inner
102 .as_ref()
103 .before_source_phase(model, current_tick, current_micro_step)
104 }
105
106 fn before_source(
107 &self,
108 model: &M,
109 current_tick: SimTime,
110 current_micro_step: MicroStep,
111 source_view: &SourceView,
112 ) {
113 self.inner
114 .as_ref()
115 .before_source(model, current_tick, current_micro_step, source_view)
116 }
117
118 fn after_source(
119 &self,
120 model: &M,
121 current_tick: SimTime,
122 current_micro_step: MicroStep,
123 source_view: &SourceView,
124 computed_next_fire: Option<SimTime>,
125 ) {
126 self.inner.as_ref().after_source(
127 model,
128 current_tick,
129 current_micro_step,
130 source_view,
131 computed_next_fire,
132 )
133 }
134
135 fn cancel_source(
136 &self,
137 model: &M,
138 current_tick: SimTime,
139 current_micro_step: MicroStep,
140 scheduled_at: SimTime,
141 source_view: &SourceView,
142 ) {
143 self.inner.as_ref().cancel_source(
144 model,
145 current_tick,
146 current_micro_step,
147 scheduled_at,
148 source_view,
149 )
150 }
151
152 fn discard_source(
153 &self,
154 model: &M,
155 current_tick: SimTime,
156 current_micro_step: MicroStep,
157 source_view: &SourceView,
158 ) {
159 self.inner
160 .as_ref()
161 .discard_source(model, current_tick, current_micro_step, source_view)
162 }
163
164 fn after_source_phase(&self, model: &M, current_tick: SimTime, current_micro_step: MicroStep) {
165 self.inner
166 .as_ref()
167 .after_source_phase(model, current_tick, current_micro_step)
168 }
169
170 fn before_event_phase(&self, model: &M, current_tick: SimTime, current_micro_step: MicroStep) {
173 self.inner
174 .as_ref()
175 .before_event_phase(model, current_tick, current_micro_step)
176 }
177
178 fn before_event(
179 &self,
180 model: &M,
181 current_tick: SimTime,
182 current_micro_step: MicroStep,
183 event: &Event<E>,
184 ) {
185 self.inner
186 .as_ref()
187 .before_event(model, current_tick, current_micro_step, event)
188 }
189
190 fn after_event(
191 &self,
192 model: &M,
193 current_tick: SimTime,
194 current_micro_step: MicroStep,
195 event: &Event<E>,
196 ) {
197 self.inner
198 .as_ref()
199 .after_event(model, current_tick, current_micro_step, event)
200 }
201
202 fn cancel_event(
203 &self,
204 model: &M,
205 current_tick: SimTime,
206 current_micro_step: MicroStep,
207 scheduled_at: SimTime,
208 event: &Event<E>,
209 ) {
210 self.inner.as_ref().cancel_event(
211 model,
212 current_tick,
213 current_micro_step,
214 scheduled_at,
215 event,
216 )
217 }
218
219 fn discard_event(
220 &self,
221 model: &M,
222 current_tick: SimTime,
223 current_micro_step: MicroStep,
224 event: &Event<E>,
225 ) {
226 self.inner
227 .as_ref()
228 .discard_event(model, current_tick, current_micro_step, event)
229 }
230
231 fn after_event_phase(&self, model: &M, current_tick: SimTime, current_micro_step: MicroStep) {
232 self.inner
233 .as_ref()
234 .after_event_phase(model, current_tick, current_micro_step)
235 }
236}
237
238impl<E, M: Model<E>, H: Hook<E, M>> SharedHook<E, M, H> {
239 pub fn new(hook: H) -> Self {
241 Self {
242 inner: Arc::new(hook),
243 _event: PhantomData,
244 _model: PhantomData,
245 }
246 }
247
248 pub fn get_ref(&self) -> &H {
250 &self.inner
251 }
252}