1use std::collections::VecDeque;
2
3use wrym_transport::{ReliableTransport, Transport};
4
5use crate::Opcode;
6
7pub enum ClientEvent {
8 Connected,
9 Disconnected,
10 MessageReceived(Vec<u8>),
11}
12
13pub struct Client<T: Transport> {
14 transport: T,
15 server_addr: String,
16 events: VecDeque<ClientEvent>,
17}
18
19impl<T: Transport> Client<T> {
20 pub fn new(transport: T, server_addr: &str) -> Self {
21 let client = Self {
22 transport,
23 server_addr: server_addr.to_string(),
24 events: VecDeque::new(),
25 };
26
27 client
28 .transport
29 .send_to(server_addr, &[Opcode::ClientConnected as u8]);
30
31 client
32 }
33
34 pub fn poll(&mut self) {
35 if let Some((_addr, mut bytes)) = self.transport.recv() {
36 if bytes.is_empty() {
37 return;
38 }
39
40 match bytes.remove(0).into() {
41 Opcode::ClientConnected => {
42 self.events.push_back(ClientEvent::Connected);
43 }
44 Opcode::ClientDisconnected => {
45 self.events.push_back(ClientEvent::Disconnected);
46 }
47 Opcode::Message => {
48 self.events.push_back(ClientEvent::MessageReceived(bytes));
49 }
50 }
51 }
52 }
53
54 pub fn recv_event(&mut self) -> Option<ClientEvent> {
55 self.events.pop_front()
56 }
57
58 pub fn send(&self, bytes: &[u8]) {
59 self.transport
60 .send_to(&self.server_addr, &Opcode::Message.with_bytes(bytes));
61 }
62
63 pub fn disconnect(&self) {
64 self.transport
65 .send_to(&self.server_addr, &[Opcode::ClientDisconnected as u8]);
66 }
67}
68
69impl<T: Transport + ReliableTransport> Client<T> {
70 pub fn send_reliable(&self, bytes: &[u8], ordered: bool) {
71 self.transport.send_reliable_to(
72 &self.server_addr,
73 &Opcode::Message.with_bytes(bytes),
74 ordered,
75 );
76 }
77}
78
79impl<T: Transport> Drop for Client<T> {
80 fn drop(&mut self) {
81 self.disconnect();
82 }
83}