naia_shared/messages/channels/senders/
request_sender.rs1use std::{collections::HashMap, time::Duration};
2
3use naia_derive::MessageRequest;
4use naia_serde::{BitWriter, SerdeInternal};
5
6use crate::messages::request::GlobalRequestId;
7use crate::{KeyGenerator, LocalEntityAndGlobalEntityConverterMut, MessageContainer, MessageKinds};
8
9pub struct RequestSender {
10 local_key_generator: KeyGenerator<LocalRequestId>,
11 local_to_global_ids: HashMap<LocalRequestId, GlobalRequestId>,
12}
13
14impl RequestSender {
15 pub fn new() -> Self {
16 Self {
17 local_key_generator: KeyGenerator::new(Duration::from_secs(60)),
18 local_to_global_ids: HashMap::new(),
19 }
20 }
21
22 pub(crate) fn process_outgoing_request(
23 &mut self,
24 message_kinds: &MessageKinds,
25 converter: &mut dyn LocalEntityAndGlobalEntityConverterMut,
26 global_request_id: GlobalRequestId,
27 request: MessageContainer,
28 ) -> MessageContainer {
29 let local_request_id = self.local_key_generator.generate();
30 self.local_to_global_ids
31 .insert(local_request_id, global_request_id);
32
33 let mut writer = BitWriter::with_max_capacity();
34 request.write(message_kinds, &mut writer, converter);
35 let request_bytes = writer.to_bytes();
36 let request_message = RequestOrResponse::request(local_request_id, request_bytes);
37 MessageContainer::from_write(Box::new(request_message), converter)
38 }
39
40 pub(crate) fn process_outgoing_response(
41 &mut self,
42 message_kinds: &MessageKinds,
43 converter: &mut dyn LocalEntityAndGlobalEntityConverterMut,
44 local_response_id: LocalResponseId,
45 response: MessageContainer,
46 ) -> MessageContainer {
47 let mut writer = BitWriter::with_max_capacity();
48 response.write(message_kinds, &mut writer, converter);
49 let response_bytes = writer.to_bytes();
50 let response_message = RequestOrResponse::response(local_response_id, response_bytes);
51 MessageContainer::from_write(Box::new(response_message), converter)
52 }
53
54 pub(crate) fn process_incoming_response(
55 &mut self,
56 local_request_id: &LocalRequestId,
57 ) -> Option<GlobalRequestId> {
58 self.local_key_generator.recycle_key(local_request_id);
59 self.local_to_global_ids.remove(local_request_id)
60 }
61}
62
63#[derive(MessageRequest)]
64pub struct RequestOrResponse {
65 id: LocalRequestOrResponseId,
66 bytes: Box<[u8]>,
67}
68
69impl RequestOrResponse {
70 pub fn request(id: LocalRequestId, bytes: Box<[u8]>) -> Self {
71 Self {
72 id: id.to_req_res_id(),
73 bytes,
74 }
75 }
76
77 pub fn response(id: LocalResponseId, bytes: Box<[u8]>) -> Self {
78 Self {
79 id: id.to_req_res_id(),
80 bytes,
81 }
82 }
83
84 pub(crate) fn to_id_and_bytes(self) -> (LocalRequestOrResponseId, Box<[u8]>) {
85 (self.id, self.bytes)
86 }
87}
88
89#[derive(Clone, PartialEq, Eq, SerdeInternal)]
90pub enum LocalRequestOrResponseId {
91 Request(LocalRequestId),
92 Response(LocalResponseId),
93}
94
95impl LocalRequestOrResponseId {
96 pub fn is_request(&self) -> bool {
97 match self {
98 LocalRequestOrResponseId::Request(_) => true,
99 LocalRequestOrResponseId::Response(_) => false,
100 }
101 }
102
103 pub fn is_response(&self) -> bool {
104 match self {
105 LocalRequestOrResponseId::Request(_) => false,
106 LocalRequestOrResponseId::Response(_) => true,
107 }
108 }
109
110 pub fn to_request_id(&self) -> LocalRequestId {
111 match self {
112 LocalRequestOrResponseId::Request(id) => *id,
113 LocalRequestOrResponseId::Response(_) => {
114 panic!("LocalRequestOrResponseId is a response")
115 }
116 }
117 }
118
119 pub fn to_response_id(&self) -> LocalResponseId {
120 match self {
121 LocalRequestOrResponseId::Request(_) => panic!("LocalRequestOrResponseId is a request"),
122 LocalRequestOrResponseId::Response(id) => *id,
123 }
124 }
125}
126
127#[derive(Clone, Copy, Eq, Hash, PartialEq, SerdeInternal)]
128pub struct LocalRequestId {
129 id: u8,
130}
131
132impl LocalRequestId {
133 pub fn to_req_res_id(&self) -> LocalRequestOrResponseId {
134 LocalRequestOrResponseId::Request(*self)
135 }
136
137 pub fn receive_from_remote(&self) -> LocalResponseId {
138 LocalResponseId { id: self.id }
139 }
140}
141
142impl From<u16> for LocalRequestId {
143 fn from(id: u16) -> Self {
144 Self { id: id as u8 }
145 }
146}
147
148impl Into<u16> for LocalRequestId {
149 fn into(self) -> u16 {
150 self.id as u16
151 }
152}
153
154#[derive(Clone, Copy, Eq, Hash, PartialEq, SerdeInternal)]
155pub struct LocalResponseId {
156 id: u8,
157}
158
159impl LocalResponseId {
160 pub fn to_req_res_id(&self) -> LocalRequestOrResponseId {
161 LocalRequestOrResponseId::Response(*self)
162 }
163
164 pub fn receive_from_remote(&self) -> LocalRequestId {
165 LocalRequestId { id: self.id }
166 }
167}