use std::any::TypeId; use std::collections::{HashMap, HashSet}; use std::marker::PhantomData; use bevy_ecs::prelude::*; use crate::*; //------------------------------------------------------------------------------------------------------------------- /// Used to register simplenet event types that can be sent over the network. /// /// We parameterize on `E` so the registry does not cause interference between multiple clients/servers in the same /// app. We also use the event registry as a proxy for checking if simplenet event framework initialization has /// occurred yet. #[derive(Resource, Debug)] pub(crate) struct EventRegistry { id_counter: u16, message_map: HashMap, message_ids: HashSet, request_map: HashMap, response_map: HashMap, request_response_map: HashMap, request_response_ids: HashMap, phantom: PhantomData, } impl EventRegistry { pub(crate) fn register_message(&mut self) -> u16 { // allow re-entry in case of client/server having same message type let type_id = std::any::TypeId::of::(); if let Some(id) = self.message_map.get(&type_id) { return *id; } // make new entry self.id_counter += 1; let id = self.id_counter; if self.message_map.insert(type_id, id).is_some() { panic!("message map has this key already"); } self.message_ids.insert(id); id } pub(crate) fn register_request_response(&mut self) -> (u16, u16) { self.id_counter += 1; let req_id = self.id_counter; self.id_counter += 1; let resp_id = self.id_counter; let req_type_id = std::any::TypeId::of::(); let resp_type_id = std::any::TypeId::of::(); if self.request_map.insert(req_type_id, req_id).is_some() { panic!("request_map has this key already"); } let _ = self.response_map.insert(resp_type_id, resp_id); //allow reentry if self .request_response_map .insert(req_type_id, resp_type_id) .is_some() { panic!("request_response_map has this key already"); } if self.request_response_ids.insert(req_id, resp_id).is_some() { panic!("request_response_ids has this key already"); } (req_id, resp_id) } pub(crate) fn get_message_id(&self) -> Option { self.message_map .get(&std::any::TypeId::of::()) .map(|i| *i) } pub(crate) fn has_message_id(&self, id: u16) -> bool { self.message_ids.contains(&id) } pub(crate) fn get_request_id(&self) -> Option { self.request_map .get(&std::any::TypeId::of::()) .map(|i| *i) } pub(crate) fn get_response_id(&self) -> Option { self.response_map .get(&std::any::TypeId::of::()) .map(|i| *i) } pub(crate) fn get_response_id_from_request(&self) -> Option { self.request_response_map .get(&std::any::TypeId::of::()) .map(|t| self.response_map.get(t).map(|i| *i)) .flatten() } pub(crate) fn get_response_id_from_request_id(&self, request_event_id: u16) -> Option { self.request_response_ids.get(&request_event_id).copied() } } impl Default for EventRegistry { fn default() -> Self { Self { id_counter: 0u16, message_map: HashMap::default(), message_ids: HashSet::default(), request_map: HashMap::default(), response_map: HashMap::default(), request_response_map: HashMap::default(), request_response_ids: HashMap::default(), phantom: PhantomData::default(), } } } //-------------------------------------------------------------------------------------------------------------------