1use std::{any::Any, collections::HashMap, marker::PhantomData, mem, vec::IntoIter};
2
3use log::warn;
4
5use naia_shared::{
6 Channel, ChannelKind, ComponentKind, EntityEvent, EntityResponseEvent, GlobalResponseId,
7 Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick,
8};
9
10use super::user::{User, UserKey};
11use crate::NaiaServerError;
12
13pub struct Events<E: Copy> {
14 connections: Vec<UserKey>,
15 disconnections: Vec<(UserKey, User)>,
16 ticks: Vec<Tick>,
17 errors: Vec<NaiaServerError>,
18 auths: HashMap<MessageKind, Vec<(UserKey, MessageContainer)>>,
19 messages: HashMap<ChannelKind, HashMap<MessageKind, Vec<(UserKey, MessageContainer)>>>,
20 requests: HashMap<
21 ChannelKind,
22 HashMap<MessageKind, Vec<(UserKey, GlobalResponseId, MessageContainer)>>,
23 >,
24 spawns: Vec<(UserKey, E)>,
25 despawns: Vec<(UserKey, E)>,
26 publishes: Vec<(UserKey, E)>,
27 unpublishes: Vec<(UserKey, E)>,
28 delegates: Vec<(UserKey, E)>,
29 auth_grants: Vec<(UserKey, E)>,
30 auth_resets: Vec<E>,
31 inserts: HashMap<ComponentKind, Vec<(UserKey, E)>>,
32 removes: HashMap<ComponentKind, Vec<(UserKey, E, Box<dyn Replicate>)>>,
33 updates: HashMap<ComponentKind, Vec<(UserKey, E)>>,
34 empty: bool,
35}
36
37impl<E: Copy> Events<E> {
38 pub(crate) fn new() -> Self {
39 Self {
40 connections: Vec::new(),
41 disconnections: Vec::new(),
42 ticks: Vec::new(),
43 errors: Vec::new(),
44 auths: HashMap::new(),
45 messages: HashMap::new(),
46 requests: HashMap::new(),
47 spawns: Vec::new(),
48 despawns: Vec::new(),
49 publishes: Vec::new(),
50 unpublishes: Vec::new(),
51 delegates: Vec::new(),
52 auth_grants: Vec::new(),
53 auth_resets: Vec::new(),
54 inserts: HashMap::new(),
55 removes: HashMap::new(),
56 updates: HashMap::new(),
57 empty: true,
58 }
59 }
60
61 pub fn is_empty(&self) -> bool {
64 self.empty
65 }
66
67 pub fn read<V: Event<E>>(&mut self) -> V::Iter {
68 return V::iter(self);
69 }
70
71 pub fn has<V: Event<E>>(&self) -> bool {
72 return V::has(self);
73 }
74
75 pub fn has_messages(&self) -> bool {
77 !self.messages.is_empty()
78 }
79 pub fn take_messages(
80 &mut self,
81 ) -> HashMap<ChannelKind, HashMap<MessageKind, Vec<(UserKey, MessageContainer)>>> {
82 mem::take(&mut self.messages)
83 }
84
85 pub fn has_requests(&self) -> bool {
87 !self.requests.is_empty()
88 }
89 pub fn take_requests(
90 &mut self,
91 ) -> HashMap<
92 ChannelKind,
93 HashMap<MessageKind, Vec<(UserKey, GlobalResponseId, MessageContainer)>>,
94 > {
95 mem::take(&mut self.requests)
96 }
97
98 pub fn has_auths(&self) -> bool {
100 !self.auths.is_empty()
101 }
102 pub fn take_auths(&mut self) -> HashMap<MessageKind, Vec<(UserKey, MessageContainer)>> {
103 mem::take(&mut self.auths)
104 }
105
106 pub fn has_inserts(&self) -> bool {
108 !self.inserts.is_empty()
109 }
110 pub fn take_inserts(&mut self) -> Option<HashMap<ComponentKind, Vec<(UserKey, E)>>> {
111 if self.inserts.is_empty() {
112 return None;
113 } else {
114 return Some(mem::take(&mut self.inserts));
115 }
116 }
117
118 pub fn has_updates(&self) -> bool {
120 !self.updates.is_empty()
121 }
122 pub fn take_updates(&mut self) -> Option<HashMap<ComponentKind, Vec<(UserKey, E)>>> {
123 if self.updates.is_empty() {
124 return None;
125 } else {
126 return Some(mem::take(&mut self.updates));
127 }
128 }
129
130 pub fn has_removes(&self) -> bool {
132 !self.removes.is_empty()
133 }
134 pub fn take_removes(
135 &mut self,
136 ) -> Option<HashMap<ComponentKind, Vec<(UserKey, E, Box<dyn Replicate>)>>> {
137 if self.removes.is_empty() {
138 return None;
139 } else {
140 return Some(mem::take(&mut self.removes));
141 }
142 }
143
144 pub(crate) fn push_connection(&mut self, user_key: &UserKey) {
147 self.connections.push(*user_key);
148 self.empty = false;
149 }
150
151 pub(crate) fn push_disconnection(&mut self, user_key: &UserKey, user: User) {
152 self.disconnections.push((*user_key, user));
153 self.empty = false;
154 }
155
156 pub(crate) fn push_auth(&mut self, user_key: &UserKey, auth_message: MessageContainer) {
157 let message_type_id = auth_message.kind();
158 if !self.auths.contains_key(&message_type_id) {
159 self.auths.insert(message_type_id, Vec::new());
160 }
161 let list = self.auths.get_mut(&message_type_id).unwrap();
162 list.push((*user_key, auth_message));
163 self.empty = false;
164 }
165
166 pub(crate) fn push_message(
167 &mut self,
168 user_key: &UserKey,
169 channel_kind: &ChannelKind,
170 message: MessageContainer,
171 ) {
172 push_message_impl(&mut self.messages, user_key, channel_kind, message);
173 self.empty = false;
174 }
175
176 pub(crate) fn push_request(
177 &mut self,
178 user_key: &UserKey,
179 channel_kind: &ChannelKind,
180 global_response_id: GlobalResponseId,
181 request: MessageContainer,
182 ) {
183 if !self.requests.contains_key(&channel_kind) {
184 self.requests.insert(*channel_kind, HashMap::new());
185 }
186 let channel_map = self.requests.get_mut(&channel_kind).unwrap();
187 let request_type_id = request.kind();
188 if !channel_map.contains_key(&request_type_id) {
189 channel_map.insert(request_type_id, Vec::new());
190 }
191 let list = channel_map.get_mut(&request_type_id).unwrap();
192 list.push((*user_key, global_response_id, request));
193
194 self.empty = false;
195 }
196
197 pub(crate) fn push_tick(&mut self, tick: Tick) {
198 self.ticks.push(tick);
199 self.empty = false;
200 }
201
202 pub(crate) fn push_error(&mut self, error: NaiaServerError) {
203 self.errors.push(error);
204 self.empty = false;
205 }
206
207 pub(crate) fn push_spawn(&mut self, user_key: &UserKey, entity: &E) {
208 self.spawns.push((*user_key, *entity));
209 self.empty = false;
210 }
211
212 pub(crate) fn push_despawn(&mut self, user_key: &UserKey, entity: &E) {
213 self.despawns.push((*user_key, *entity));
214 self.empty = false;
215 }
216
217 pub(crate) fn push_publish(&mut self, user_key: &UserKey, entity: &E) {
218 self.publishes.push((*user_key, *entity));
219 self.empty = false;
220 }
221
222 pub(crate) fn push_unpublish(&mut self, user_key: &UserKey, entity: &E) {
223 self.unpublishes.push((*user_key, *entity));
224 self.empty = false;
225 }
226
227 pub(crate) fn push_delegate(&mut self, user_key: &UserKey, entity: &E) {
228 self.delegates.push((*user_key, *entity));
229 self.empty = false;
230 }
231
232 pub(crate) fn push_auth_grant(&mut self, user_key: &UserKey, entity: &E) {
233 self.auth_grants.push((*user_key, *entity));
234 self.empty = false;
235 }
236
237 pub(crate) fn push_auth_reset(&mut self, entity: &E) {
238 self.auth_resets.push(*entity);
239 self.empty = false;
240 }
241
242 pub(crate) fn push_insert(
243 &mut self,
244 user_key: &UserKey,
245 entity: &E,
246 component_kind: &ComponentKind,
247 ) {
248 if !self.inserts.contains_key(component_kind) {
249 self.inserts.insert(*component_kind, Vec::new());
250 }
251 let list = self.inserts.get_mut(&component_kind).unwrap();
252 list.push((*user_key, *entity));
253 self.empty = false;
254 }
255
256 pub(crate) fn push_remove(
257 &mut self,
258 user_key: &UserKey,
259 entity: &E,
260 component: Box<dyn Replicate>,
261 ) {
262 let component_kind = component.kind();
263
264 if !self.removes.contains_key(&component_kind) {
265 self.removes.insert(component_kind, Vec::new());
266 }
267 let list = self.removes.get_mut(&component_kind).unwrap();
268 list.push((*user_key, *entity, component));
269 self.empty = false;
270 }
271
272 pub(crate) fn push_update(
273 &mut self,
274 user_key: &UserKey,
275 entity: &E,
276 component_kind: &ComponentKind,
277 ) {
278 if !self.updates.contains_key(component_kind) {
279 self.updates.insert(*component_kind, Vec::new());
280 }
281 let list = self.updates.get_mut(component_kind).unwrap();
282 list.push((*user_key, *entity));
283 self.empty = false;
284 }
285
286 pub(crate) fn receive_entity_events(
287 &mut self,
288 user_key: &UserKey,
289 entity_events: Vec<EntityEvent<E>>,
290 ) -> Vec<EntityResponseEvent<E>> {
291 let mut response_events = Vec::new();
292 for event in entity_events {
293 match event {
294 EntityEvent::SpawnEntity(entity) => {
295 self.push_spawn(user_key, &entity);
296 response_events.push(EntityResponseEvent::SpawnEntity(entity));
297 }
298 EntityEvent::DespawnEntity(entity) => {
299 self.push_despawn(user_key, &entity);
300 response_events.push(EntityResponseEvent::DespawnEntity(entity));
301 }
302 EntityEvent::InsertComponent(entity, component_kind) => {
303 self.push_insert(user_key, &entity, &component_kind);
304 response_events
305 .push(EntityResponseEvent::InsertComponent(entity, component_kind));
306 }
307 EntityEvent::RemoveComponent(entity, component_box) => {
308 let kind = component_box.kind();
309 self.push_remove(user_key, &entity, component_box);
310 response_events.push(EntityResponseEvent::RemoveComponent(entity, kind));
311 }
312 EntityEvent::UpdateComponent(_tick, entity, component_kind) => {
313 self.push_update(user_key, &entity, &component_kind);
314 }
315 }
316 }
317 response_events
318 }
319}
320
321impl<E: Copy> Drop for Events<E> {
322 fn drop(&mut self) {
323 if !self.spawns.is_empty() {
324 warn!("Dropped Server Spawn Event(s)! Make sure to handle these through `events.read::<SpawnEntityEvent>()`, and note that this may be an attack vector.");
325 }
326 if !self.publishes.is_empty() {
327 warn!("Dropped Server Publish Entity Event(s)! Make sure to handle these through `events.read::<PublishEntityEvent>()`, and note that this may be an attack vector.");
328 }
329 if !self.unpublishes.is_empty() {
330 warn!("Dropped Server Unpublish Entity Event(s)! Make sure to handle these through `events.read::<UnpublishEntityEvent>()`, and note that this may be an attack vector.");
331 }
332 if !self.inserts.is_empty() {
333 warn!("Dropped Server Insert Event(s)! Make sure to handle these through `events.read::<InsertComponentEvent<Component>>()`, and note that this may be an attack vector.");
334 }
335 if !self.updates.is_empty() {
336 warn!("Dropped Server Update Event(s)! Make sure to handle these through `events.read::<UpdateComponentEvent<Component>>()`, and note that this may be an attack vector.");
337 }
338 }
339}
340
341pub trait Event<E: Copy> {
343 type Iter;
344
345 fn iter(events: &mut Events<E>) -> Self::Iter;
346
347 fn has(events: &Events<E>) -> bool;
348}
349
350pub struct ConnectEvent;
352impl<E: Copy> Event<E> for ConnectEvent {
353 type Iter = IntoIter<UserKey>;
354
355 fn iter(events: &mut Events<E>) -> Self::Iter {
356 let list = std::mem::take(&mut events.connections);
357 return IntoIterator::into_iter(list);
358 }
359
360 fn has(events: &Events<E>) -> bool {
361 !events.connections.is_empty()
362 }
363}
364
365pub struct DisconnectEvent;
367impl<E: Copy> Event<E> for DisconnectEvent {
368 type Iter = IntoIter<(UserKey, User)>;
369
370 fn iter(events: &mut Events<E>) -> Self::Iter {
371 let list = std::mem::take(&mut events.disconnections);
372 return IntoIterator::into_iter(list);
373 }
374
375 fn has(events: &Events<E>) -> bool {
376 !events.disconnections.is_empty()
377 }
378}
379
380pub struct TickEvent;
382impl<E: Copy> Event<E> for TickEvent {
383 type Iter = IntoIter<Tick>;
384
385 fn iter(events: &mut Events<E>) -> Self::Iter {
386 let list = std::mem::take(&mut events.ticks);
387 return IntoIterator::into_iter(list);
388 }
389
390 fn has(events: &Events<E>) -> bool {
391 !events.ticks.is_empty()
392 }
393}
394
395pub struct ErrorEvent;
397impl<E: Copy> Event<E> for ErrorEvent {
398 type Iter = IntoIter<NaiaServerError>;
399
400 fn iter(events: &mut Events<E>) -> Self::Iter {
401 let list = std::mem::take(&mut events.errors);
402 return IntoIterator::into_iter(list);
403 }
404
405 fn has(events: &Events<E>) -> bool {
406 !events.errors.is_empty()
407 }
408}
409
410pub struct AuthEvent<M: Message> {
412 phantom_m: PhantomData<M>,
413}
414impl<E: Copy, M: Message> Event<E> for AuthEvent<M> {
415 type Iter = IntoIter<(UserKey, M)>;
416
417 fn iter(events: &mut Events<E>) -> Self::Iter {
418 let message_kind: MessageKind = MessageKind::of::<M>();
419 return if let Some(messages) = events.auths.remove(&message_kind) {
420 IntoIterator::into_iter(read_messages(messages))
421 } else {
422 IntoIterator::into_iter(Vec::new())
423 };
424 }
425
426 fn has(events: &Events<E>) -> bool {
427 let message_kind: MessageKind = MessageKind::of::<M>();
428 return events.auths.contains_key(&message_kind);
429 }
430}
431
432pub struct MessageEvent<C: Channel, M: Message> {
434 phantom_c: PhantomData<C>,
435 phantom_m: PhantomData<M>,
436}
437impl<E: Copy, C: Channel, M: Message> Event<E> for MessageEvent<C, M> {
438 type Iter = IntoIter<(UserKey, M)>;
439
440 fn iter(events: &mut Events<E>) -> Self::Iter {
441 let output = read_channel_messages::<C, M>(&mut events.messages);
442 return IntoIterator::into_iter(output);
443 }
444
445 fn has(events: &Events<E>) -> bool {
446 let channel_kind: ChannelKind = ChannelKind::of::<C>();
447 if let Some(channel_map) = events.messages.get(&channel_kind) {
448 let message_kind: MessageKind = MessageKind::of::<M>();
449 return channel_map.contains_key(&message_kind);
450 }
451 return false;
452 }
453}
454
455pub(crate) fn read_channel_messages<C: Channel, M: Message>(
456 messages: &mut HashMap<ChannelKind, HashMap<MessageKind, Vec<(UserKey, MessageContainer)>>>,
457) -> Vec<(UserKey, M)> {
458 let channel_kind: ChannelKind = ChannelKind::of::<C>();
459 if let Some(channel_map) = messages.get_mut(&channel_kind) {
460 let message_kind: MessageKind = MessageKind::of::<M>();
461 if let Some(messages) = channel_map.remove(&message_kind) {
462 return read_messages(messages);
463 }
464 }
465
466 return Vec::new();
467}
468
469pub(crate) fn read_messages<M: Message>(
470 messages: Vec<(UserKey, MessageContainer)>,
471) -> Vec<(UserKey, M)> {
472 let mut output_list: Vec<(UserKey, M)> = Vec::new();
473
474 for (user_key, message) in messages {
475 let message: M = Box::<dyn Any + 'static>::downcast::<M>(message.to_boxed_any())
476 .ok()
477 .map(|boxed_m| *boxed_m)
478 .unwrap();
479 output_list.push((user_key, message));
480 }
481
482 output_list
483}
484
485pub(crate) fn push_message_impl(
486 messages: &mut HashMap<ChannelKind, HashMap<MessageKind, Vec<(UserKey, MessageContainer)>>>,
487 user_key: &UserKey,
488 channel_kind: &ChannelKind,
489 message: MessageContainer,
490) {
491 if !messages.contains_key(&channel_kind) {
492 messages.insert(*channel_kind, HashMap::new());
493 }
494 let channel_map = messages.get_mut(&channel_kind).unwrap();
495 let message_type_id = message.kind();
496 if !channel_map.contains_key(&message_type_id) {
497 channel_map.insert(message_type_id, Vec::new());
498 }
499 let list = channel_map.get_mut(&message_type_id).unwrap();
500 list.push((*user_key, message));
501}
502
503pub struct RequestEvent<C: Channel, Q: Request> {
505 phantom_c: PhantomData<C>,
506 phantom_m: PhantomData<Q>,
507}
508impl<E: Copy, C: Channel, Q: Request> Event<E> for RequestEvent<C, Q> {
509 type Iter = IntoIter<(UserKey, ResponseSendKey<Q::Response>, Q)>;
510
511 fn iter(events: &mut Events<E>) -> Self::Iter {
512 let channel_kind: ChannelKind = ChannelKind::of::<C>();
513 let Some(channel_map) = events.requests.get_mut(&channel_kind) else {
514 return IntoIterator::into_iter(Vec::new());
515 };
516 let message_kind: MessageKind = MessageKind::of::<Q>();
517 let Some(requests) = channel_map.remove(&message_kind) else {
518 return IntoIterator::into_iter(Vec::new());
519 };
520
521 let mut output_list = Vec::new();
522
523 for (user_key, global_response_id, request) in requests {
524 let request: Q = Box::<dyn Any + 'static>::downcast::<Q>(request.to_boxed_any())
525 .ok()
526 .map(|boxed_q| *boxed_q)
527 .unwrap();
528 let response_send_key = ResponseSendKey::<Q::Response>::new(global_response_id);
529 output_list.push((user_key, response_send_key, request));
530 }
531
532 return IntoIterator::into_iter(output_list);
533 }
534
535 fn has(events: &Events<E>) -> bool {
536 let channel_kind: ChannelKind = ChannelKind::of::<C>();
537 if let Some(channel_map) = events.requests.get(&channel_kind) {
538 let message_kind: MessageKind = MessageKind::of::<Q>();
539 return channel_map.contains_key(&message_kind);
540 }
541 return false;
542 }
543}
544
545pub struct SpawnEntityEvent;
547impl<E: Copy> Event<E> for SpawnEntityEvent {
548 type Iter = IntoIter<(UserKey, E)>;
549
550 fn iter(events: &mut Events<E>) -> Self::Iter {
551 let list = std::mem::take(&mut events.spawns);
552 return IntoIterator::into_iter(list);
553 }
554
555 fn has(events: &Events<E>) -> bool {
556 !events.spawns.is_empty()
557 }
558}
559
560pub struct DespawnEntityEvent;
562impl<E: Copy> Event<E> for DespawnEntityEvent {
563 type Iter = IntoIter<(UserKey, E)>;
564
565 fn iter(events: &mut Events<E>) -> Self::Iter {
566 let list = std::mem::take(&mut events.despawns);
567 return IntoIterator::into_iter(list);
568 }
569
570 fn has(events: &Events<E>) -> bool {
571 !events.despawns.is_empty()
572 }
573}
574
575pub struct PublishEntityEvent;
577impl<E: Copy> Event<E> for PublishEntityEvent {
578 type Iter = IntoIter<(UserKey, E)>;
579
580 fn iter(events: &mut Events<E>) -> Self::Iter {
581 let list = std::mem::take(&mut events.publishes);
582 return IntoIterator::into_iter(list);
583 }
584
585 fn has(events: &Events<E>) -> bool {
586 !events.publishes.is_empty()
587 }
588}
589
590pub struct UnpublishEntityEvent;
592impl<E: Copy> Event<E> for UnpublishEntityEvent {
593 type Iter = IntoIter<(UserKey, E)>;
594
595 fn iter(events: &mut Events<E>) -> Self::Iter {
596 let list = std::mem::take(&mut events.unpublishes);
597 return IntoIterator::into_iter(list);
598 }
599
600 fn has(events: &Events<E>) -> bool {
601 !events.unpublishes.is_empty()
602 }
603}
604
605pub struct DelegateEntityEvent;
607impl<E: Copy> Event<E> for DelegateEntityEvent {
608 type Iter = IntoIter<(UserKey, E)>;
609
610 fn iter(events: &mut Events<E>) -> Self::Iter {
611 let list = std::mem::take(&mut events.delegates);
612 return IntoIterator::into_iter(list);
613 }
614
615 fn has(events: &Events<E>) -> bool {
616 !events.delegates.is_empty()
617 }
618}
619
620pub struct EntityAuthGrantEvent;
622impl<E: Copy> Event<E> for EntityAuthGrantEvent {
623 type Iter = IntoIter<(UserKey, E)>;
624
625 fn iter(events: &mut Events<E>) -> Self::Iter {
626 let list = std::mem::take(&mut events.auth_grants);
627 return IntoIterator::into_iter(list);
628 }
629
630 fn has(events: &Events<E>) -> bool {
631 !events.auth_grants.is_empty()
632 }
633}
634
635pub struct EntityAuthResetEvent;
637impl<E: Copy> Event<E> for EntityAuthResetEvent {
638 type Iter = IntoIter<E>;
639
640 fn iter(events: &mut Events<E>) -> Self::Iter {
641 let list = std::mem::take(&mut events.auth_resets);
642 return IntoIterator::into_iter(list);
643 }
644
645 fn has(events: &Events<E>) -> bool {
646 !events.auth_resets.is_empty()
647 }
648}
649
650pub struct InsertComponentEvent<C: Replicate> {
652 phantom_c: PhantomData<C>,
653}
654impl<E: Copy, C: Replicate> Event<E> for InsertComponentEvent<C> {
655 type Iter = IntoIter<(UserKey, E)>;
656
657 fn iter(events: &mut Events<E>) -> Self::Iter {
658 let component_kind: ComponentKind = ComponentKind::of::<C>();
659 if let Some(boxed_list) = events.inserts.remove(&component_kind) {
660 return IntoIterator::into_iter(boxed_list);
661 }
662
663 return IntoIterator::into_iter(Vec::new());
664 }
665
666 fn has(events: &Events<E>) -> bool {
667 let component_kind: ComponentKind = ComponentKind::of::<C>();
668 events.inserts.contains_key(&component_kind)
669 }
670}
671
672pub struct UpdateComponentEvent<C: Replicate> {
674 phantom_c: PhantomData<C>,
675}
676impl<E: Copy, C: Replicate> Event<E> for UpdateComponentEvent<C> {
677 type Iter = IntoIter<(UserKey, E)>;
678
679 fn iter(events: &mut Events<E>) -> Self::Iter {
680 let component_kind: ComponentKind = ComponentKind::of::<C>();
681 if let Some(boxed_list) = events.updates.remove(&component_kind) {
682 return IntoIterator::into_iter(boxed_list);
683 }
684
685 return IntoIterator::into_iter(Vec::new());
686 }
687
688 fn has(events: &Events<E>) -> bool {
689 let component_kind: ComponentKind = ComponentKind::of::<C>();
690 events.updates.contains_key(&component_kind)
691 }
692}
693
694pub struct RemoveComponentEvent<C: Replicate> {
696 phantom_c: PhantomData<C>,
697}
698impl<E: Copy, C: Replicate> Event<E> for RemoveComponentEvent<C> {
699 type Iter = IntoIter<(UserKey, E, C)>;
700
701 fn iter(events: &mut Events<E>) -> Self::Iter {
702 let component_kind: ComponentKind = ComponentKind::of::<C>();
703 if let Some(boxed_list) = events.removes.remove(&component_kind) {
704 let mut output_list: Vec<(UserKey, E, C)> = Vec::new();
705
706 for (user_key, entity, boxed_component) in boxed_list {
707 let boxed_any = boxed_component.to_boxed_any();
708 let component = boxed_any.downcast::<C>().unwrap();
709 output_list.push((user_key, entity, *component));
710 }
711
712 return IntoIterator::into_iter(output_list);
713 }
714
715 return IntoIterator::into_iter(Vec::new());
716 }
717
718 fn has(events: &Events<E>) -> bool {
719 let component_kind: ComponentKind = ComponentKind::of::<C>();
720 events.removes.contains_key(&component_kind)
721 }
722}