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
use std::{
    any::TypeId,
    cell::RefCell,
    fmt::{Debug, Formatter, Result},
    rc::Rc,
};

use super::{actor_mutator::ActorMutator, actor_type::ActorType, state_mask::StateMask};

use crate::PacketReader;

/// An Actor is a container of Properties that can be scoped, tracked, and
/// synced, with a remote host
pub trait Actor<T: ActorType> {
    /// Gets the number of bytes of the Actor's State Mask
    fn get_state_mask_size(&self) -> u8;
    /// Gets a copy of the Actor, wrapped in an ActorType enum (which is the
    /// common protocol between the server/host)
    fn get_typed_copy(&self) -> T;
    /// Gets the TypeId of the Actor's implementation, used to map to a
    /// registered ActorType
    fn get_type_id(&self) -> TypeId;
    /// Writes data into an outgoing byte stream, sufficient to completely
    /// recreate the Actor on the client
    fn write(&self, out_bytes: &mut Vec<u8>);
    /// Write data into an outgoing byte stream, sufficient only to update the
    /// mutated Properties of the Actor on the client
    fn write_partial(&self, state_mask: &StateMask, out_bytes: &mut Vec<u8>);
    /// Reads data from an incoming packet, sufficient to sync the in-memory
    /// Actor with it's state on the Server
    fn read_full(&mut self, reader: &mut PacketReader, packet_index: u16);
    /// Reads data from an incoming packet, sufficient to sync the in-memory
    /// Actor with it's state on the Server
    fn read_partial(
        &mut self,
        state_mask: &StateMask,
        reader: &mut PacketReader,
        packet_index: u16,
    );
    /// Set the Actor's ActorMutator, which keeps track of which Properties
    /// have been mutated, necessary to sync only the Properties that have
    /// changed with the client
    fn set_mutator(&mut self, mutator: &Rc<RefCell<dyn ActorMutator>>);
    /// Returns whether or not the Actor has any interpolated properties
    fn is_interpolated(&self) -> bool;
    /// Returns whether or not the Actor has any predicted properties
    fn is_predicted(&self) -> bool;
}

//TODO: do we really need another trait here?
/// Handles equality of Actors.. can't just derive PartialEq because we want
/// to only compare Properties
pub trait ActorEq<T: ActorType, Impl = Self>: Actor<T> {
    /// Compare properties in another Actor
    fn equals(&self, other: &Impl) -> bool;
    /// Compare only predicted properties in another Actor
    fn equals_prediction(&self, other: &Impl) -> bool;
    /// Sets the current Actor to an interpolated state between two other
    /// Actors of the same type
    fn set_to_interpolation(&mut self, old: &Impl, new: &Impl, fraction: f32);
    /// Sets the current Actor to the state of another Actor of the same type
    fn mirror(&mut self, other: &Impl);
}

impl<T: ActorType> Debug for dyn Actor<T> {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        f.write_str("Actor")
    }
}