1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use Sender;
use UIMessage;
use UdpSocket;
use ;
/// This is for your UI to listen on the data coming out of the core.
/// import this and use directly, or modify to suit your own needs.
/// By default you can use this to run in the background, and subscribe to the outgoing events
/// using crossbeam.
/// Events will be sent to the crossbeam sender, and received in your UI with the crossbeam
/// receiver.
/// ```rust
/// use metaverse_session::client_subscriber::listen_for_server_events;
/// use crossbeam_channel::{unbounded, Receiver, Sender};
/// use std::thread::spawn;
/// use tokio::runtime::Runtime;
/// use portpicker::pick_unused_port;
///
/// let server_to_ui_socket = pick_unused_port().map_or_else(|| "No port found".to_string(), |port| port.to_string());
///
/// spawn(move || {
/// let rt = Runtime::new().expect("Failed to create Tokio runtime");
/// rt.block_on(async {
/// listen_for_server_events(server_to_ui_socket, sender).await;
/// });
/// });
/// ```
///
/// In your UI you can use something like this to handle events.
/// just remember to keep your crossbeam_channels as shared resources.
/// for example, create the crossbeam_channels in your main function, start your thread, save that
/// channel to a global variable, and then run handle_queue once per frame.
/// ```text
/// use crossbeam_channel::Receiver;
///
///fn handle_queue(receiver: Receiver) {
/// while let Ok(event) = receiver.try_recv() {
/// match event{
/// PacketType::LoginResponse(login_response) => {
/// // handle the login response
/// }
/// PacketType::CoarseLocationUpdate(coarse_location_update) => {
/// // handle the coarse location update
/// }
/// // etc for the rest of the event packets
/// }
/// }
///}
///```
pub async