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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use std::{hash::Hash, marker::PhantomData};

use naia_shared::{
    ChannelIndex, Protocolize, ReplicaMutWrapper, ReplicaRefWrapper, Replicate, ReplicateSafe,
    WorldMutType, WorldRefType,
};

use crate::{room::RoomKey, server::Server};

// EntityRef

/// A reference to an Entity being tracked by the Server
pub struct EntityRef<P: Protocolize, E: Copy + Eq + Hash, W: WorldRefType<P, E>> {
    phantom_p: PhantomData<P>,
    world: W,
    entity: E,
}

impl<P: Protocolize, E: Copy + Eq + Hash, W: WorldRefType<P, E>> EntityRef<P, E, W> {
    /// Return a new EntityRef
    pub(crate) fn new(world: W, entity: &E) -> Self {
        EntityRef {
            phantom_p: PhantomData,
            world,
            entity: *entity,
        }
    }

    /// Return the Entity itself
    pub fn id(&self) -> E {
        self.entity
    }

    // Components

    /// Returns whether or not the Entity has an associated Component
    pub fn has_component<R: ReplicateSafe<P>>(&self) -> bool {
        self.world.has_component::<R>(&self.entity)
    }

    /// Gets a Ref to a Component associated with the Entity
    pub fn component<R: ReplicateSafe<P>>(&self) -> Option<ReplicaRefWrapper<P, R>> {
        self.world.component::<R>(&self.entity)
    }
}

// EntityMut
pub struct EntityMut<
    's,
    P: Protocolize,
    E: Copy + Eq + Hash + Send + Sync,
    W: WorldMutType<P, E>,
    C: ChannelIndex,
> {
    server: &'s mut Server<P, E, C>,
    world: W,
    entity: E,
}

impl<
        's,
        P: Protocolize,
        E: Copy + Eq + Hash + Send + Sync,
        W: WorldMutType<P, E>,
        C: ChannelIndex,
    > EntityMut<'s, P, E, W, C>
{
    pub(crate) fn new(server: &'s mut Server<P, E, C>, world: W, entity: &E) -> Self {
        EntityMut {
            server,
            world,
            entity: *entity,
        }
    }

    pub fn id(&self) -> E {
        self.entity
    }

    pub fn despawn(&mut self) {
        self.server.despawn_entity(&mut self.world, &self.entity);
    }

    // Components

    pub fn has_component<R: ReplicateSafe<P>>(&self) -> bool {
        self.world.has_component::<R>(&self.entity)
    }

    pub fn component<R: ReplicateSafe<P>>(&mut self) -> Option<ReplicaMutWrapper<P, R>> {
        self.world.component_mut::<R>(&self.entity)
    }

    pub fn insert_component<R: ReplicateSafe<P>>(&mut self, component_ref: R) -> &mut Self {
        self.server
            .insert_component(&mut self.world, &self.entity, component_ref);

        self
    }

    pub fn insert_components<R: ReplicateSafe<P>>(
        &mut self,
        mut component_refs: Vec<R>,
    ) -> &mut Self {
        while let Some(component_ref) = component_refs.pop() {
            self.insert_component(component_ref);
        }

        self
    }

    pub fn remove_component<R: Replicate<P>>(&mut self) -> Option<R> {
        self.server
            .remove_component::<R, W>(&mut self.world, &self.entity)
    }

    // Rooms

    pub fn enter_room(&mut self, room_key: &RoomKey) -> &mut Self {
        self.server.room_add_entity(room_key, &self.entity);

        self
    }

    pub fn leave_room(&mut self, room_key: &RoomKey) -> &mut Self {
        self.server.room_remove_entity(room_key, &self.entity);

        self
    }
}