1use std::time::{Duration, Instant};
4
5use maybenot::event::TriggerEvent;
6
7use crate::{
8 SimEvent, event_to_usize,
9 queue_event::{EventQueue, Queue},
10};
11
12#[derive(Debug, Clone)]
18pub struct SimQueue {
19 pub(crate) client: EventQueue,
20 pub(crate) server: EventQueue,
21 pub(crate) max_pps: Option<usize>,
24}
25
26impl Default for SimQueue {
27 fn default() -> Self {
28 Self::new()
29 }
30}
31
32impl SimQueue {
33 pub fn new() -> SimQueue {
34 SimQueue {
35 client: EventQueue::new(),
36 server: EventQueue::new(),
37 max_pps: None,
38 }
39 }
40
41 pub fn len(&self) -> usize {
42 self.client.len() + self.server.len()
43 }
44
45 pub fn is_empty(&self) -> bool {
46 self.len() == 0
47 }
48
49 pub fn no_normal_packets(&self) -> bool {
50 self.client.no_normal_packets() && self.server.no_normal_packets()
51 }
52
53 pub fn get_max_pps(&self) -> Option<usize> {
54 self.max_pps
55 }
56
57 pub fn push(
58 &mut self,
59 event: TriggerEvent,
60 is_client: bool,
61 contains_padding: bool,
62 time: Instant,
63 delay: Duration,
64 ) {
65 self.push_sim(SimEvent {
66 event,
67 time,
68 integration_delay: delay,
69 client: is_client,
70 contains_padding,
71 bypass: false,
72 replace: false,
73 debug_note: None,
74 });
75 }
76
77 pub fn push_sim(&mut self, item: SimEvent) {
78 match item.client {
79 true => self.client.push(item),
80 false => self.server.push(item),
81 }
82 }
83
84 pub fn peek(
85 &self,
86 client_network_delay_sum: Duration,
87 server_network_delay_sum: Duration,
88 current_time: Instant,
89 ) -> (Option<&SimEvent>, Queue, Duration) {
90 match self.len() {
91 0 => (None, Queue::Blocking, Duration::default()),
92 _ => {
93 let (client, client_queue, client_duration) =
95 self.client.peek(client_network_delay_sum, current_time);
96 let (server, server_queue, server_duration) =
97 self.server.peek(server_network_delay_sum, current_time);
98
99 match (client, server) {
104 (Some(_), None) => (client, client_queue, client_duration),
105 (None, Some(_)) => (server, server_queue, server_duration),
106 (None, None) => (None, Queue::Blocking, Duration::default()),
107 (Some(client_event), Some(server_event)) => {
108 let ordering = client_duration.cmp(&server_duration).then_with(|| {
109 event_to_usize(&client_event.event)
110 .cmp(&event_to_usize(&server_event.event))
111 });
112 if ordering == std::cmp::Ordering::Less
113 || ordering == std::cmp::Ordering::Equal
114 {
115 (client, client_queue, client_duration)
116 } else {
117 (server, server_queue, server_duration)
118 }
119 }
120 }
121 }
122 }
123 }
124
125 pub fn pop(
126 &mut self,
127 q: Queue,
128 is_client: bool,
129 network_delay_sum: Duration,
130 ) -> Option<SimEvent> {
131 match is_client {
132 true => self.client.pop(q, network_delay_sum),
133 false => self.server.pop(q, network_delay_sum),
134 }
135 }
136
137 pub fn peek_blocking(
138 &self,
139 active_blocking_bypassable: bool,
140 is_client: bool,
141 ) -> (Option<&SimEvent>, Queue) {
142 match is_client {
143 true => peek_blocking(&self.client, active_blocking_bypassable),
144 false => peek_blocking(&self.server, active_blocking_bypassable),
145 }
146 }
147
148 pub fn pop_blocking(
149 &mut self,
150 q: Queue,
151 bypassable: bool,
152 is_client: bool,
153 network_delay_sum: Duration,
154 ) -> Option<SimEvent> {
155 if bypassable {
156 match is_client {
157 true => self.client.blocking.pop(),
158 false => self.server.blocking.pop(),
159 }
160 } else {
161 self.pop(q, is_client, network_delay_sum)
162 }
163 }
164
165 pub fn peek_non_blocking(
166 &self,
167 bypassable: bool,
168 is_client: bool,
169 network_delay_sum: Duration,
170 ) -> (Option<&SimEvent>, Queue) {
171 match is_client {
172 true => peek_non_blocking(&self.client, bypassable, network_delay_sum),
173 false => peek_non_blocking(&self.server, bypassable, network_delay_sum),
174 }
175 }
176
177 pub fn get_first_time(&self) -> Option<Instant> {
178 let c = self.client.get_first_base_time();
179 let s = self.server.get_first_base_time();
180
181 match (c, s) {
182 (Some(ct), Some(st)) => Some(ct.min(st)),
183 (Some(ct), None) => Some(ct),
184 (None, Some(st)) => Some(st),
185 (None, None) => None,
186 }
187 }
188}
189
190fn peek_blocking(
191 queue: &EventQueue,
192 active_blocking_bypassable: bool,
193) -> (Option<&SimEvent>, Queue) {
194 if active_blocking_bypassable {
195 (queue.peek_blocking(), Queue::Blocking)
197 } else {
198 let b = queue.peek_blocking();
201 let bb = queue.peek_bypassable();
202
203 if b > bb {
204 (b, Queue::Blocking)
205 } else {
206 (bb, Queue::Bypassable)
207 }
208 }
209}
210
211fn peek_non_blocking(
212 queue: &EventQueue,
213 bypassable: bool,
214 network_delay_sum: Duration,
215) -> (Option<&SimEvent>, Queue) {
216 if bypassable {
217 let bb = queue.peek_bypassable();
220 let (n, nq) = queue.peek_non_blocking(network_delay_sum);
221
222 if bb > n {
223 (bb, Queue::Bypassable)
224 } else {
225 (n, nq)
226 }
227 } else {
228 queue.peek_non_blocking(network_delay_sum)
229 }
230}