naia_shared/world/component/
property.rs

1use log::warn;
2use std::ops::{Deref, DerefMut};
3
4use naia_serde::{BitReader, BitWrite, BitWriter, Serde, SerdeErr};
5
6use crate::world::{
7    component::property_mutate::PropertyMutator, delegation::auth_channel::EntityAuthAccessor,
8};
9
10#[derive(Clone)]
11enum PropertyImpl<T: Serde> {
12    HostOwned(HostOwnedProperty<T>),
13    RemoteOwned(RemoteOwnedProperty<T>),
14    RemotePublic(RemotePublicProperty<T>),
15    Delegated(DelegatedProperty<T>),
16    Local(LocalProperty<T>),
17}
18
19impl<T: Serde> PropertyImpl<T> {
20    fn name(&self) -> &str {
21        match self {
22            PropertyImpl::HostOwned(_) => "HostOwned",
23            PropertyImpl::RemoteOwned(_) => "RemoteOwned",
24            PropertyImpl::RemotePublic(_) => "RemotePublic",
25            PropertyImpl::Delegated(_) => "Delegated",
26            PropertyImpl::Local(_) => "Local",
27        }
28    }
29}
30
31/// A Property of an Component/Message, that contains data
32/// which must be tracked for updates
33#[derive(Clone)]
34pub struct Property<T: Serde> {
35    inner: PropertyImpl<T>,
36}
37
38// should be shared
39impl<T: Serde> Property<T> {
40    /// Create a new Local Property
41    pub fn new_local(value: T) -> Self {
42        Self {
43            inner: PropertyImpl::Local(LocalProperty::new(value)),
44        }
45    }
46
47    /// Create a new host-owned Property
48    pub fn host_owned(value: T, mutator_index: u8) -> Self {
49        Self {
50            inner: PropertyImpl::HostOwned(HostOwnedProperty::new(value, mutator_index)),
51        }
52    }
53
54    /// Given a cursor into incoming packet data, initializes the Property with
55    /// the synced value
56    pub fn new_read(reader: &mut BitReader) -> Result<Self, SerdeErr> {
57        let inner_value = Self::read_inner(reader)?;
58
59        Ok(Self {
60            inner: PropertyImpl::RemoteOwned(RemoteOwnedProperty::new(inner_value)),
61        })
62    }
63
64    /// Set an PropertyMutator to track changes to the Property
65    pub fn set_mutator(&mut self, mutator: &PropertyMutator) {
66        match &mut self.inner {
67            PropertyImpl::HostOwned(inner) => {
68                inner.set_mutator(mutator);
69            }
70            PropertyImpl::RemoteOwned(_) | PropertyImpl::RemotePublic(_) => {
71                panic!("Remote Property should never call set_mutator().");
72            }
73            PropertyImpl::Delegated(_) => {
74                panic!("Delegated Property should never call set_mutator().");
75            }
76            PropertyImpl::Local(_) => {
77                panic!("Local Property should never have a mutator.");
78            }
79        }
80    }
81
82    // Serialization / deserialization
83
84    /// Writes contained value into outgoing byte stream
85    pub fn write(&self, writer: &mut dyn BitWrite) {
86        match &self.inner {
87            PropertyImpl::HostOwned(inner) => {
88                inner.write(writer);
89            }
90            PropertyImpl::RemoteOwned(_) => {
91                panic!("Remote Private Property should never be written.");
92            }
93            PropertyImpl::RemotePublic(inner) => {
94                inner.write(writer);
95            }
96            PropertyImpl::Local(_) => {
97                panic!("Local Property should never be written.");
98            }
99            PropertyImpl::Delegated(inner) => {
100                inner.write(writer);
101            }
102        }
103    }
104
105    /// Reads from a stream and immediately writes to a stream
106    /// Used to buffer updates for later
107    pub fn read_write(reader: &mut BitReader, writer: &mut BitWriter) -> Result<(), SerdeErr> {
108        T::de(reader)?.ser(writer);
109        Ok(())
110    }
111
112    /// Given a cursor into incoming packet data, updates the Property with the
113    /// synced value
114    pub fn read(&mut self, reader: &mut BitReader) -> Result<(), SerdeErr> {
115        match &mut self.inner {
116            PropertyImpl::HostOwned(_) => {
117                panic!("Host Property should never read.");
118            }
119            PropertyImpl::RemoteOwned(inner) => {
120                inner.read(reader)?;
121            }
122            PropertyImpl::RemotePublic(inner) => {
123                inner.read(reader)?;
124            }
125            PropertyImpl::Local(_) => {
126                panic!("Local Property should never read.");
127            }
128            PropertyImpl::Delegated(inner) => {
129                inner.read(reader)?;
130            }
131        }
132        Ok(())
133    }
134
135    fn read_inner(reader: &mut BitReader) -> Result<T, SerdeErr> {
136        T::de(reader)
137    }
138
139    // Comparison
140
141    fn inner(&self) -> &T {
142        match &self.inner {
143            PropertyImpl::HostOwned(inner) => &inner.inner,
144            PropertyImpl::RemoteOwned(inner) => &inner.inner,
145            PropertyImpl::RemotePublic(inner) => &inner.inner,
146            PropertyImpl::Local(inner) => &inner.inner,
147            PropertyImpl::Delegated(inner) => &inner.inner,
148        }
149    }
150
151    /// Compare to another property
152    pub fn equals(&self, other: &Self) -> bool {
153        self.inner() == other.inner()
154    }
155
156    /// Set value to the value of another Property, queues for update if value
157    /// changes
158    pub fn mirror(&mut self, other: &Self) {
159        let other_inner = other.inner();
160        match &mut self.inner {
161            PropertyImpl::HostOwned(inner) => {
162                inner.mirror(other_inner);
163            }
164            PropertyImpl::RemoteOwned(_) | PropertyImpl::RemotePublic(_) => {
165                panic!("Remote Property should never be set manually.");
166            }
167            PropertyImpl::Delegated(inner) => {
168                inner.mirror(other_inner);
169            }
170            PropertyImpl::Local(inner) => {
171                inner.mirror(other_inner);
172            }
173        }
174    }
175
176    /// Migrate Remote Property to Public version
177    pub fn remote_publish(&mut self, mutator_index: u8, mutator: &PropertyMutator) {
178        match &mut self.inner {
179            PropertyImpl::HostOwned(_) => {
180                panic!("Host Property should never be made public.");
181            }
182            PropertyImpl::RemoteOwned(inner) => {
183                let inner_value = inner.inner.clone();
184                self.inner = PropertyImpl::RemotePublic(RemotePublicProperty::new(
185                    inner_value,
186                    mutator_index,
187                    mutator,
188                ));
189            }
190            PropertyImpl::RemotePublic(_) => {
191                panic!("Remote Property should never be made public twice.");
192            }
193            PropertyImpl::Local(_) => {
194                panic!("Local Property should never be made public.");
195            }
196            PropertyImpl::Delegated(_) => {
197                panic!("Delegated Property should never be made public.");
198            }
199        }
200    }
201
202    /// Migrate Remote Property to Private version
203    pub fn remote_unpublish(&mut self) {
204        match &mut self.inner {
205            PropertyImpl::HostOwned(_) => {
206                panic!("Host Property should never be unpublished.");
207            }
208            PropertyImpl::RemoteOwned(_) => {
209                panic!("Private Remote Property should never be unpublished.");
210            }
211            PropertyImpl::RemotePublic(inner) => {
212                let inner_value = inner.inner.clone();
213                self.inner = PropertyImpl::RemoteOwned(RemoteOwnedProperty::new(inner_value));
214            }
215            PropertyImpl::Local(_) => {
216                panic!("Local Property should never be unpublished.");
217            }
218            PropertyImpl::Delegated(_) => {
219                panic!("Delegated Property should never be unpublished.");
220            }
221        }
222    }
223
224    /// Migrate Property to Delegated version
225    pub fn enable_delegation(
226        &mut self,
227        accessor: &EntityAuthAccessor,
228        mutator_opt: Option<(u8, &PropertyMutator)>,
229    ) {
230        let value = self.inner().clone();
231
232        let (mutator_index, mutator) = {
233            if let Some((mutator_index, mutator)) = mutator_opt {
234                match &mut self.inner {
235                    PropertyImpl::RemoteOwned(_) => (mutator_index, mutator),
236                    PropertyImpl::Local(_)
237                    | PropertyImpl::RemotePublic(_)
238                    | PropertyImpl::HostOwned(_)
239                    | PropertyImpl::Delegated(_) => {
240                        panic!(
241                            "Property of type `{:?}` should never enable delegation this way",
242                            self.inner.name()
243                        );
244                    }
245                }
246            } else {
247                match &mut self.inner {
248                    PropertyImpl::HostOwned(inner) => (
249                        inner.index,
250                        inner
251                            .mutator
252                            .as_ref()
253                            .expect("should have a mutator by now"),
254                    ),
255                    PropertyImpl::RemotePublic(inner) => (inner.index, &inner.mutator),
256                    PropertyImpl::RemoteOwned(_)
257                    | PropertyImpl::Delegated(_)
258                    | PropertyImpl::Local(_) => {
259                        panic!(
260                            "Property of type `{:?}` should never enable delegation this way",
261                            self.inner.name()
262                        );
263                    }
264                }
265            }
266        };
267
268        self.inner = PropertyImpl::Delegated(DelegatedProperty::new(
269            value,
270            accessor,
271            mutator,
272            mutator_index,
273        ));
274    }
275
276    /// Migrate Delegated Property to Host-Owned (Public) version
277    pub fn disable_delegation(&mut self) {
278        match &mut self.inner {
279            PropertyImpl::HostOwned(_) => {
280                panic!("Host Property should never disable delegation.");
281            }
282            PropertyImpl::RemoteOwned(_) => {
283                panic!("Private Remote Property should never disable delegation.");
284            }
285            PropertyImpl::RemotePublic(_) => {
286                panic!("Public Remote Property should never disable delegation.");
287            }
288            PropertyImpl::Local(_) => {
289                panic!("Local Property should never disable delegation.");
290            }
291            PropertyImpl::Delegated(inner) => {
292                let inner_value = inner.inner.clone();
293                let mut new_inner = HostOwnedProperty::new(inner_value, inner.index);
294                new_inner.set_mutator(&inner.mutator);
295                self.inner = PropertyImpl::HostOwned(new_inner);
296            }
297        }
298    }
299
300    /// Migrate Host Property to Local version
301    pub fn localize(&mut self) {
302        match &mut self.inner {
303            PropertyImpl::HostOwned(inner) => {
304                let inner_value = inner.inner.clone();
305                self.inner = PropertyImpl::Local(LocalProperty::new(inner_value));
306            }
307            PropertyImpl::RemoteOwned(_) | PropertyImpl::RemotePublic(_) => {
308                panic!("Remote Property should never be made local.");
309            }
310            PropertyImpl::Local(_) => {
311                panic!("Local Property should never be made local twice.");
312            }
313            PropertyImpl::Delegated(_) => {
314                panic!("Delegated Property should never be made local.");
315            }
316        }
317    }
318}
319
320// It could be argued that Property here is a type of smart-pointer,
321// but honestly this is mainly for the convenience of type coercion
322impl<T: Serde> Deref for Property<T> {
323    type Target = T;
324
325    fn deref(&self) -> &Self::Target {
326        self.inner()
327    }
328}
329
330impl<T: Serde> DerefMut for Property<T> {
331    fn deref_mut(&mut self) -> &mut Self::Target {
332        // Just assume inner value will be changed, queue for update
333        match &mut self.inner {
334            PropertyImpl::HostOwned(inner) => {
335                inner.mutate();
336                &mut inner.inner
337            }
338            PropertyImpl::RemoteOwned(_) | PropertyImpl::RemotePublic(_) => {
339                panic!("Remote Property should never be set manually.");
340            }
341            PropertyImpl::Local(inner) => &mut inner.inner,
342            PropertyImpl::Delegated(inner) => {
343                inner.mutate();
344                &mut inner.inner
345            }
346        }
347    }
348}
349
350#[derive(Clone)]
351pub struct HostOwnedProperty<T: Serde> {
352    inner: T,
353    mutator: Option<PropertyMutator>,
354    index: u8,
355}
356
357impl<T: Serde> HostOwnedProperty<T> {
358    /// Create a new HostOwnedProperty
359    pub fn new(value: T, mutator_index: u8) -> Self {
360        Self {
361            inner: value,
362            mutator: None,
363            index: mutator_index,
364        }
365    }
366
367    pub fn set_mutator(&mut self, mutator: &PropertyMutator) {
368        self.mutator = Some(mutator.clone_new());
369    }
370
371    pub fn write(&self, writer: &mut dyn BitWrite) {
372        self.inner.ser(writer);
373    }
374
375    pub fn mirror(&mut self, other: &T) {
376        self.mutate();
377        self.inner = other.clone();
378    }
379
380    pub fn mutate(&mut self) {
381        let Some(mutator) = &mut self.mutator else {
382            warn!("Host Property should have a mutator immediately after creation.");
383            return;
384        };
385        let _success = mutator.mutate(self.index);
386    }
387}
388
389#[derive(Clone)]
390pub struct LocalProperty<T: Serde> {
391    inner: T,
392}
393
394impl<T: Serde> LocalProperty<T> {
395    /// Create a new LocalProperty
396    pub fn new(value: T) -> Self {
397        Self { inner: value }
398    }
399
400    pub fn mirror(&mut self, other: &T) {
401        self.inner = other.clone();
402    }
403}
404
405#[derive(Clone)]
406pub struct RemoteOwnedProperty<T: Serde> {
407    inner: T,
408}
409
410impl<T: Serde> RemoteOwnedProperty<T> {
411    /// Create a new RemoteOwnedProperty
412    pub fn new(value: T) -> Self {
413        Self { inner: value }
414    }
415
416    pub fn read(&mut self, reader: &mut BitReader) -> Result<(), SerdeErr> {
417        self.inner = Property::read_inner(reader)?;
418        Ok(())
419    }
420}
421
422#[derive(Clone)]
423pub struct RemotePublicProperty<T: Serde> {
424    inner: T,
425    mutator: PropertyMutator,
426    index: u8,
427}
428
429impl<T: Serde> RemotePublicProperty<T> {
430    /// Create a new RemotePublicProperty
431    pub fn new(value: T, mutator_index: u8, mutator: &PropertyMutator) -> Self {
432        Self {
433            inner: value,
434            mutator: mutator.clone_new(),
435            index: mutator_index,
436        }
437    }
438
439    pub fn read(&mut self, reader: &mut BitReader) -> Result<(), SerdeErr> {
440        self.inner = Property::read_inner(reader)?;
441        self.mutate();
442        Ok(())
443    }
444
445    pub fn write(&self, writer: &mut dyn BitWrite) {
446        self.inner.ser(writer);
447    }
448
449    fn mutate(&mut self) {
450        let _success = self.mutator.mutate(self.index);
451    }
452}
453
454#[derive(Clone)]
455pub struct DelegatedProperty<T: Serde> {
456    inner: T,
457    auth_accessor: EntityAuthAccessor,
458    mutator: PropertyMutator,
459    index: u8,
460}
461
462impl<T: Serde> DelegatedProperty<T> {
463    /// Create a new DelegatedProperty
464    pub fn new(
465        value: T,
466        auth_accessor: &EntityAuthAccessor,
467        mutator: &PropertyMutator,
468        index: u8,
469    ) -> Self {
470        Self {
471            inner: value,
472            auth_accessor: auth_accessor.clone(),
473            mutator: mutator.clone_new(),
474            index,
475        }
476    }
477
478    pub fn read(&mut self, reader: &mut BitReader) -> Result<(), SerdeErr> {
479        let value = Property::read_inner(reader)?;
480
481        if self.can_read() {
482            self.inner = value;
483            if self.can_mutate() {
484                self.mutate();
485            }
486        }
487
488        Ok(())
489    }
490
491    pub fn write(&self, writer: &mut dyn BitWrite) {
492        if !self.can_write() {
493            panic!("Must have Authority over Entity before performing this operation. Current Authority: {:?}", self.auth_accessor.auth_status());
494        }
495        self.inner.ser(writer);
496    }
497
498    pub fn mirror(&mut self, other: &T) {
499        self.mutate();
500        self.inner = other.clone();
501    }
502
503    fn mutate(&mut self) {
504        if !self.can_mutate() {
505            panic!("Must request authority to mutate a Delegated Property.");
506        }
507        let _success = self.mutator.mutate(self.index);
508    }
509
510    fn can_mutate(&self) -> bool {
511        self.auth_accessor.auth_status().can_mutate()
512    }
513
514    fn can_read(&self) -> bool {
515        self.auth_accessor.auth_status().can_read()
516    }
517
518    fn can_write(&self) -> bool {
519        self.auth_accessor.auth_status().can_write()
520    }
521}