naia_shared/world/host/
mut_channel.rs

1use std::{
2    hash::Hash,
3    net::SocketAddr,
4    sync::{Arc, RwLock, RwLockReadGuard},
5};
6
7use crate::{DiffMask, GlobalWorldManagerType, PropertyMutate};
8
9pub trait MutChannelType: Send + Sync {
10    fn new_receiver(&mut self, address: &Option<SocketAddr>) -> Option<MutReceiver>;
11    fn send(&self, diff: u8);
12}
13
14// MutChannel
15#[derive(Clone)]
16pub struct MutChannel {
17    data: Arc<RwLock<dyn MutChannelType>>,
18}
19
20impl MutChannel {
21    pub fn new_channel<E: Copy + Eq + Hash>(
22        global_world_manager: &dyn GlobalWorldManagerType<E>,
23        diff_mask_length: u8,
24    ) -> (MutSender, MutReceiverBuilder) {
25        let channel = Self {
26            data: global_world_manager.new_mut_channel(diff_mask_length),
27        };
28
29        let sender = channel.new_sender();
30
31        let builder = MutReceiverBuilder::new(&channel);
32
33        (sender, builder)
34    }
35
36    pub fn new_sender(&self) -> MutSender {
37        MutSender::new(self)
38    }
39
40    pub fn new_receiver(&self, address: &Option<SocketAddr>) -> Option<MutReceiver> {
41        if let Ok(mut data) = self.data.as_ref().write() {
42            return data.new_receiver(address);
43        }
44        None
45    }
46
47    pub fn send(&self, diff: u8) -> bool {
48        if let Ok(data) = self.data.as_ref().read() {
49            data.send(diff);
50            return true;
51        }
52        false
53    }
54}
55
56// MutReceiver
57#[derive(Clone)]
58pub struct MutReceiver {
59    mask: Arc<RwLock<DiffMask>>,
60}
61
62impl MutReceiver {
63    pub fn new(diff_mask_length: u8) -> Self {
64        Self {
65            mask: Arc::new(RwLock::new(DiffMask::new(diff_mask_length))),
66        }
67    }
68
69    pub fn mask(&self) -> RwLockReadGuard<DiffMask> {
70        let Ok(mask) = self.mask.as_ref().read() else {
71            panic!("Mask held on current thread");
72        };
73
74        mask
75    }
76
77    pub fn diff_mask_is_clear(&self) -> bool {
78        let Ok(mask) = self.mask.as_ref().read() else {
79            panic!("Mask held on current thread");
80        };
81        return mask.is_clear();
82    }
83
84    pub fn mutate(&self, diff: u8) {
85        let Ok(mut mask) = self.mask.as_ref().write() else {
86            panic!("Mask held on current thread");
87        };
88        mask.set_bit(diff, true);
89    }
90
91    pub fn or_mask(&self, other_mask: &DiffMask) {
92        let Ok(mut mask) = self.mask.as_ref().write() else {
93            panic!("Mask held on current thread");
94        };
95        mask.or(other_mask);
96    }
97
98    pub fn clear_mask(&self) {
99        let Ok(mut mask) = self.mask.as_ref().write() else {
100            panic!("Mask held on current thread");
101        };
102        mask.clear();
103    }
104}
105
106// MutSender
107#[derive(Clone)]
108pub struct MutSender {
109    channel: MutChannel,
110}
111
112impl MutSender {
113    pub fn new(channel: &MutChannel) -> Self {
114        Self {
115            channel: channel.clone(),
116        }
117    }
118}
119
120impl PropertyMutate for MutSender {
121    fn mutate(&mut self, property_index: u8) -> bool {
122        let success = self.channel.send(property_index);
123        success
124    }
125}
126
127// MutReceiverBuilder
128pub struct MutReceiverBuilder {
129    channel: MutChannel,
130}
131
132impl MutReceiverBuilder {
133    pub fn new(channel: &MutChannel) -> Self {
134        Self {
135            channel: channel.clone(),
136        }
137    }
138
139    pub fn build(&self, address: &Option<SocketAddr>) -> Option<MutReceiver> {
140        self.channel.new_receiver(address)
141    }
142}