naia_shared/messages/
message_kinds.rs1use std::{any::TypeId, collections::HashMap};
2
3use naia_serde::{BitReader, BitWrite, ConstBitLength, Serde, SerdeErr};
4
5use crate::{LocalEntityAndGlobalEntityConverter, Message, MessageBuilder, MessageContainer};
6
7type NetId = u16;
8
9#[derive(Eq, Hash, Copy, Clone, PartialEq, Debug)]
11pub struct MessageKind {
12 type_id: TypeId,
13}
14
15impl MessageKind {
24 pub fn of<M: Message>() -> Self {
25 Self {
26 type_id: TypeId::of::<M>(),
27 }
28 }
29
30 pub fn ser(&self, message_kinds: &MessageKinds, writer: &mut dyn BitWrite) {
31 message_kinds.kind_to_net_id(self).ser(writer);
32 }
33
34 pub fn de(message_kinds: &MessageKinds, reader: &mut BitReader) -> Result<Self, SerdeErr> {
35 let net_id: NetId = NetId::de(reader)?;
36 Ok(message_kinds.net_id_to_kind(&net_id))
37 }
38}
39
40impl ConstBitLength for MessageKind {
41 fn const_bit_length() -> u32 {
42 <NetId as ConstBitLength>::const_bit_length()
43 }
44}
45
46pub struct MessageKinds {
48 current_net_id: NetId,
49 kind_map: HashMap<MessageKind, (NetId, Box<dyn MessageBuilder>)>,
50 net_id_map: HashMap<NetId, MessageKind>,
51}
52
53impl MessageKinds {
54 pub fn new() -> Self {
55 Self {
56 current_net_id: 0,
57 kind_map: HashMap::new(),
58 net_id_map: HashMap::new(),
59 }
60 }
61
62 pub fn add_message<M: Message>(&mut self) {
63 let message_kind = MessageKind::of::<M>();
64
65 let net_id = self.current_net_id;
66 self.kind_map
67 .insert(message_kind, (net_id, M::create_builder()));
68 self.net_id_map.insert(net_id, message_kind);
69 self.current_net_id += 1;
70 }
72
73 pub fn read(
74 &self,
75 reader: &mut BitReader,
76 converter: &dyn LocalEntityAndGlobalEntityConverter,
77 ) -> Result<MessageContainer, SerdeErr> {
78 let message_kind: MessageKind = MessageKind::de(self, reader)?;
79 return self.kind_to_builder(&message_kind).read(reader, converter);
80 }
81
82 fn net_id_to_kind(&self, net_id: &NetId) -> MessageKind {
83 return *self.net_id_map.get(net_id).expect(
84 "Must properly initialize Message with Protocol via `add_message()` function!",
85 );
86 }
87
88 fn kind_to_net_id(&self, message_kind: &MessageKind) -> NetId {
89 return self
90 .kind_map
91 .get(message_kind)
92 .expect("Must properly initialize Message with Protocol via `add_message()` function!")
93 .0;
94 }
95
96 fn kind_to_builder(&self, message_kind: &MessageKind) -> &Box<dyn MessageBuilder> {
97 return &self
98 .kind_map
99 .get(&message_kind)
100 .expect("Must properly initialize Message with Protocol via `add_message()` function!")
101 .1;
102 }
103}