Skip to content

Commit 7b69a10

Browse files
committed
Migrate to the new Entity layout
For details see bevyengine/bevy#19121 bevyengine/bevy#18704 The niche is now in the index, which makes the compression logic even simpler.
1 parent 8935fbc commit 7b69a10

File tree

4 files changed

+36
-27
lines changed

4 files changed

+36
-27
lines changed

src/compact_entity.rs

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,34 @@
1717
1818
use core::fmt::{self, Formatter};
1919

20-
use bevy::prelude::*;
20+
use bevy::{
21+
ecs::entity::{EntityGeneration, EntityRow},
22+
prelude::*,
23+
};
2124
use serde::{
2225
Deserializer, Serialize, Serializer,
2326
de::{self, SeqAccess, Visitor},
2427
};
2528

2629
/// Serializes an entity by writing its index and generation as separate numbers.
2730
///
28-
/// This reduces the space used for serializers with varint encoding.
31+
/// This reduces the space required when using serializers with varint encoding.
2932
///
30-
/// The index is first prepended with a bit flag to indicate if the generation
31-
/// is serialized or not. It is not serialized if <= 1; note that generations are [`NonZeroU32`](core::num::NonZeroU32)
32-
/// and a value of zero is used in [`Option<Entity>`] to signify [`None`], so generation 1 is the first
33-
/// generation.
33+
/// Since the index can never be [`u32::MAX`], we reuse that extra niche to indicate
34+
/// whether the generation isn't [`EntityGeneration::FIRST`]. If it doesn't,
35+
/// the generation is skipped during serialization.
3436
///
3537
/// See also [`deserialize`] and [`postcard_utils::entity_to_extend_mut`](crate::postcard_utils::entity_to_extend_mut).
3638
pub fn serialize<S: Serializer>(entity: &Entity, serializer: S) -> Result<S::Ok, S::Error> {
37-
let mut flagged_index = (entity.index() as u64) << 1;
38-
let flag = entity.generation() > 1;
39-
flagged_index |= flag as u64;
39+
let mut index = entity.index() << 1;
40+
let has_generation = entity.generation() != EntityGeneration::FIRST;
41+
index |= has_generation as u32;
4042

41-
if flag {
42-
let generation = entity.generation() - 1;
43-
(flagged_index, generation).serialize(serializer)
43+
if has_generation {
44+
let generation = entity.generation().to_bits();
45+
(index, generation).serialize(serializer)
4446
} else {
45-
flagged_index.serialize(serializer)
47+
index.serialize(serializer)
4648
}
4749
}
4850

@@ -63,22 +65,23 @@ impl<'de> Visitor<'de> for EntityVisitor {
6365
}
6466

6567
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
66-
let flagged_index: u64 = seq
68+
let index: u32 = seq
6769
.next_element()?
6870
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
6971

70-
let has_generation = (flagged_index & 1) != 0;
72+
let has_generation = (index & 1) != 0;
7173

7274
let generation = if has_generation {
73-
let generation: u32 = seq
74-
.next_element()?
75-
.ok_or_else(|| de::Error::invalid_length(1, &self))?;
76-
generation as u64 + 1
75+
seq.next_element()?
76+
.ok_or_else(|| de::Error::invalid_length(1, &self))?
7777
} else {
78-
1
78+
0
7979
};
8080

81-
let bits = (flagged_index >> 1) | (generation << 32);
82-
Ok(Entity::from_bits(bits))
81+
// SAFETY: `index` is non-max after shift.
82+
let row = unsafe { EntityRow::from_raw_u32(index >> 1).unwrap_unchecked() };
83+
let generation = EntityGeneration::from_bits(generation);
84+
85+
Ok(Entity::from_row_and_generation(row, generation))
8386
}
8487
}

src/postcard_utils.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,13 @@ impl<'a, T: Buf> DeFlavor<'a> for BufFlavor<'a, T> {
212212

213213
#[cfg(test)]
214214
mod tests {
215+
use bevy::ecs::entity::{EntityGeneration, EntityRow};
216+
215217
use super::*;
216218

217219
#[test]
218220
fn entity_without_generation() {
219-
let expected_entity = Entity::from_raw(1);
221+
let expected_entity = Entity::from_raw_u32(1).unwrap();
220222
let mut buffer = Vec::new();
221223
entity_to_extend_mut(&expected_entity, &mut buffer).unwrap();
222224
assert_eq!(buffer.len(), 1);
@@ -227,7 +229,10 @@ mod tests {
227229

228230
#[test]
229231
fn entity_with_generation() {
230-
let expected_entity = Entity::from_bits(1 | (2 << 32));
232+
let expected_entity = Entity::from_row_and_generation(
233+
EntityRow::from_raw_u32(1).unwrap(),
234+
EntityGeneration::from_bits(1),
235+
);
231236
let mut buffer = Vec::new();
232237
entity_to_extend_mut(&expected_entity, &mut buffer).unwrap();
233238
assert_eq!(buffer.len(), 2);

src/shared/server_entity_map.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@ mod tests {
155155

156156
#[test]
157157
fn mapping() {
158-
const SERVER_ENTITY: Entity = Entity::from_raw(0);
159-
const CLIENT_ENTITY: Entity = Entity::from_raw(1);
158+
const SERVER_ENTITY: Entity = Entity::from_raw_u32(0).unwrap();
159+
const CLIENT_ENTITY: Entity = Entity::from_raw_u32(1).unwrap();
160160

161161
let mut map = ServerEntityMap::default();
162162
assert_eq!(map.server_entry(SERVER_ENTITY).get(), None);

tests/server_event.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,8 @@ fn local_resending() {
187187
.add_server_event::<TestEvent>(Channel::Ordered)
188188
.finish();
189189

190-
const PLACEHOLDER_CLIENT_ID: ClientId = ClientId::Client(Entity::from_raw(1));
190+
const CLIENT_ENTITY: Entity = Entity::from_raw_u32(1).unwrap();
191+
const PLACEHOLDER_CLIENT_ID: ClientId = ClientId::Client(CLIENT_ENTITY);
191192
for (mode, events_count) in [
192193
(SendMode::Broadcast, 1),
193194
(SendMode::Direct(ClientId::Server), 1),

0 commit comments

Comments
 (0)