1
+ pub mod client_visibility;
2
+
1
3
use std:: mem;
2
4
3
5
use bevy:: {
@@ -7,11 +9,15 @@ use bevy::{
7
9
} ;
8
10
use bevy_renet:: renet:: ClientId ;
9
11
10
- use crate :: replicon_core:: replicon_tick:: RepliconTick ;
12
+ use crate :: { replicon_core:: replicon_tick:: RepliconTick , server:: VisibilityPolicy } ;
13
+ use client_visibility:: ClientVisibility ;
11
14
12
15
/// Stores meta-information about connected clients.
13
- #[ derive( Default , Resource ) ]
14
- pub struct ClientsInfo ( Vec < ClientInfo > ) ;
16
+ #[ derive( Resource , Default ) ]
17
+ pub struct ClientsInfo {
18
+ info : Vec < ClientInfo > ,
19
+ policy : VisibilityPolicy ,
20
+ }
15
21
16
22
/// Reusable buffers for [`ClientsInfo`] and [`ClientInfo`].
17
23
#[ derive( Default , Resource ) ]
@@ -28,19 +34,73 @@ pub(crate) struct ClientBuffers {
28
34
}
29
35
30
36
impl ClientsInfo {
31
- /// Returns an iterator over clients information.
32
- pub ( crate ) fn iter ( & self ) -> impl Iterator < Item = & ClientInfo > {
33
- self . 0 . iter ( )
37
+ pub ( super ) fn new ( policy : VisibilityPolicy ) -> Self {
38
+ Self {
39
+ info : Default :: default ( ) ,
40
+ policy,
41
+ }
42
+ }
43
+
44
+ /// Returns a reference to a connected client's info.
45
+ ///
46
+ /// This operation is *O*(*n*).
47
+ /// See also [`Self::get_client`] for the fallible version.
48
+ ///
49
+ /// # Panics
50
+ ///
51
+ /// Panics if the passed client ID is not connected.
52
+ pub fn client ( & self , client_id : ClientId ) -> & ClientInfo {
53
+ self . get_client ( client_id)
54
+ . unwrap_or_else ( || panic ! ( "{client_id:?} should be connected" ) )
34
55
}
35
56
36
- /// Returns a mutable iterator over clients information.
37
- pub ( super ) fn iter_mut ( & mut self ) -> impl Iterator < Item = & mut ClientInfo > {
38
- self . 0 . iter_mut ( )
57
+ /// Returns a mutable reference to a connected client's info.
58
+ ///
59
+ /// This operation is *O*(*n*).
60
+ /// See also [`Self::get_client_mut`] for the fallible version.
61
+ ///
62
+ /// # Panics
63
+ ///
64
+ /// Panics if the passed client ID is not connected.
65
+ pub fn client_mut ( & mut self , client_id : ClientId ) -> & mut ClientInfo {
66
+ self . get_client_mut ( client_id)
67
+ . unwrap_or_else ( || panic ! ( "{client_id:?} should be connected" ) )
39
68
}
40
69
41
- /// Returns number of connected clients.
42
- pub ( super ) fn len ( & self ) -> usize {
43
- self . 0 . len ( )
70
+ /// Returns a reference to a connected client's info.
71
+ ///
72
+ /// This operation is *O*(*n*).
73
+ /// See also [`Self::client`] for the panicking version.
74
+ pub fn get_client ( & self , client_id : ClientId ) -> Option < & ClientInfo > {
75
+ self . info . iter ( ) . find ( |info| info. id == client_id)
76
+ }
77
+
78
+ /// Returns a mutable reference to a connected client's info.
79
+ ///
80
+ /// This operation is *O*(*n*).
81
+ /// See also [`Self::client`] for the panicking version.
82
+ pub fn get_client_mut ( & mut self , client_id : ClientId ) -> Option < & mut ClientInfo > {
83
+ self . info . iter_mut ( ) . find ( |info| info. id == client_id)
84
+ }
85
+
86
+ /// Returns an iterator over client information.
87
+ pub fn iter ( & self ) -> impl Iterator < Item = & ClientInfo > {
88
+ self . info . iter ( )
89
+ }
90
+
91
+ /// Returns a mutable iterator over client information.
92
+ pub fn iter_mut ( & mut self ) -> impl Iterator < Item = & mut ClientInfo > {
93
+ self . info . iter_mut ( )
94
+ }
95
+
96
+ /// Returns the number of connected clients.
97
+ pub fn len ( & self ) -> usize {
98
+ self . info . len ( )
99
+ }
100
+
101
+ /// Returns `true` if no clients are connected.
102
+ pub fn is_empty ( & self ) -> bool {
103
+ self . info . is_empty ( )
44
104
}
45
105
46
106
/// Initializes a new [`ClientInfo`] for this client.
@@ -51,22 +111,22 @@ impl ClientsInfo {
51
111
client_info. reset ( client_id) ;
52
112
client_info
53
113
} else {
54
- ClientInfo :: new ( client_id)
114
+ ClientInfo :: new ( client_id, self . policy )
55
115
} ;
56
116
57
- self . 0 . push ( client_info) ;
117
+ self . info . push ( client_info) ;
58
118
}
59
119
60
120
/// Removes info for the client.
61
121
///
62
122
/// Keeps allocated memory in the buffers for reuse.
63
123
pub ( super ) fn remove ( & mut self , client_buffers : & mut ClientBuffers , client_id : ClientId ) {
64
124
let index = self
65
- . 0
125
+ . info
66
126
. iter ( )
67
127
. position ( |info| info. id == client_id)
68
128
. expect ( "clients info should contain all connected clients" ) ;
69
- let mut client_info = self . 0 . remove ( index) ;
129
+ let mut client_info = self . info . remove ( index) ;
70
130
client_buffers. entities . extend ( client_info. drain_entities ( ) ) ;
71
131
client_buffers. info . push ( client_info) ;
72
132
}
@@ -75,23 +135,23 @@ impl ClientsInfo {
75
135
///
76
136
/// Keeps allocated memory in the buffers for reuse.
77
137
pub ( super ) fn clear ( & mut self , client_buffers : & mut ClientBuffers ) {
78
- for mut client_info in self . 0 . drain ( ..) {
138
+ for mut client_info in self . info . drain ( ..) {
79
139
client_buffers. entities . extend ( client_info. drain_entities ( ) ) ;
80
140
client_buffers. info . push ( client_info) ;
81
141
}
82
142
}
83
143
}
84
144
85
- pub ( crate ) struct ClientInfo {
145
+ pub struct ClientInfo {
86
146
/// Client's ID.
87
147
id : ClientId ,
88
148
89
- /// Indicates whether the client connected in this tick.
90
- pub ( super ) just_connected : bool ,
91
-
92
149
/// Lowest tick for use in change detection for each entity.
93
150
ticks : EntityHashMap < Entity , Tick > ,
94
151
152
+ /// Entity visibility settings.
153
+ visibility : ClientVisibility ,
154
+
95
155
/// The last tick in which a replicated entity was spawned, despawned, or gained/lost a component from the perspective
96
156
/// of the client.
97
157
///
@@ -108,11 +168,11 @@ pub(crate) struct ClientInfo {
108
168
}
109
169
110
170
impl ClientInfo {
111
- fn new ( id : ClientId ) -> Self {
171
+ fn new ( id : ClientId , policy : VisibilityPolicy ) -> Self {
112
172
Self {
113
173
id,
114
- just_connected : true ,
115
174
ticks : Default :: default ( ) ,
175
+ visibility : ClientVisibility :: new ( policy) ,
116
176
change_tick : Default :: default ( ) ,
117
177
updates : Default :: default ( ) ,
118
178
next_update_index : Default :: default ( ) ,
@@ -124,6 +184,16 @@ impl ClientInfo {
124
184
self . id
125
185
}
126
186
187
+ /// Returns a reference to the client's visibility settings.
188
+ pub fn visibility ( & self ) -> & ClientVisibility {
189
+ & self . visibility
190
+ }
191
+
192
+ /// Returns a mutable reference to the client's visibility settings.
193
+ pub fn visibility_mut ( & mut self ) -> & mut ClientVisibility {
194
+ & mut self . visibility
195
+ }
196
+
127
197
/// Clears all entities for unacknowledged updates, returning them as an iterator.
128
198
///
129
199
/// Keeps the allocated memory for reuse.
@@ -138,7 +208,7 @@ impl ClientInfo {
138
208
/// Keeps the allocated memory for reuse.
139
209
fn reset ( & mut self , id : ClientId ) {
140
210
self . id = id;
141
- self . just_connected = true ;
211
+ self . visibility . clear ( ) ;
142
212
self . ticks . clear ( ) ;
143
213
self . updates . clear ( ) ;
144
214
self . next_update_index = 0 ;
@@ -229,10 +299,20 @@ impl ClientInfo {
229
299
/// Removes a despawned entity tracked by this client.
230
300
pub fn remove_despawned ( & mut self , entity : Entity ) {
231
301
self . ticks . remove ( & entity) ;
302
+ self . visibility . remove_despawned ( entity) ;
232
303
// We don't clean up `self.updates` for efficiency reasons.
233
304
// `Self::acknowledge()` will properly ignore despawned entities.
234
305
}
235
306
307
+ /// Drains all entities for which visibility was lost during this tick.
308
+ ///
309
+ /// Internal cleanup happens lazily during the iteration.
310
+ pub ( super ) fn drain_lost_visibility ( & mut self ) -> impl Iterator < Item = Entity > + ' _ {
311
+ self . visibility . drain_lost_visibility ( ) . inspect ( |entity| {
312
+ self . ticks . remove ( entity) ;
313
+ } )
314
+ }
315
+
236
316
/// Removes all updates older then `min_timestamp`.
237
317
///
238
318
/// Keeps allocated memory in the buffers for reuse.
0 commit comments