Skip to content

Commit

Permalink
Rename InitMessageArrays into InitMessageFlags
Browse files Browse the repository at this point in the history
I planning to encode other things inside it.
Also this name fits better in general.
  • Loading branch information
Shatur committed Nov 18, 2024
1 parent a37d3ca commit 9f204f8
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 97 deletions.
24 changes: 12 additions & 12 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::core::{
channels::{ReplicationChannel, RepliconChannels},
common_conditions::{client_connected, client_just_connected, client_just_disconnected},
replication::{
change_message_arrays::ChangeMessageArrays,
change_message_flags::ChangeMessageFlags,
command_markers::{CommandMarkers, EntityMarkers},
deferred_entity::DeferredEntity,
replication_registry::{
Expand Down Expand Up @@ -187,26 +187,26 @@ fn apply_change_message(
stats.bytes += end_pos;
}

let arrays = ChangeMessageArrays::from_bits_retain(cursor.read_fixedint()?);
debug_assert!(!arrays.is_empty(), "message can't be empty");
let flags = ChangeMessageFlags::from_bits_retain(cursor.read_fixedint()?);
debug_assert!(!flags.is_empty(), "message can't be empty");

let message_tick = DefaultOptions::new().deserialize_from(&mut cursor)?;
trace!("applying change message for {message_tick:?}");
world.resource_mut::<ServerChangeTick>().0 = message_tick;

let last_array = arrays.last();
for (_, array) in arrays.iter_names() {
match array {
ChangeMessageArrays::MAPPINGS => {
let last_flag = flags.last();
for (_, flag) in flags.iter_names() {
match flag {
ChangeMessageFlags::MAPPINGS => {
let len = apply_sized_array(&mut cursor, |cursor| {
apply_entity_mapping(world, params, cursor)
})?;
if let Some(stats) = &mut params.stats {
stats.mappings += len as u32;
}
}
ChangeMessageArrays::DESPAWNS => {
let len = if array != last_array {
ChangeMessageFlags::DESPAWNS => {
let len = if flag != last_flag {
apply_sized_array(&mut cursor, |cursor| {
apply_despawn(world, params, cursor, message_tick)
})?
Expand All @@ -219,8 +219,8 @@ fn apply_change_message(
stats.despawns += len as u32;
}
}
ChangeMessageArrays::REMOVALS => {
let len = if array != last_array {
ChangeMessageFlags::REMOVALS => {
let len = if flag != last_flag {
apply_sized_array(&mut cursor, |cursor| {
apply_removals(world, params, cursor, message_tick)
})?
Expand All @@ -233,7 +233,7 @@ fn apply_change_message(
stats.entities_changed += len as u32;
}
}
ChangeMessageArrays::CHANGES => {
ChangeMessageFlags::CHANGES => {
let len = apply_dyn_array(&mut cursor, |cursor| {
apply_changes(world, params, cursor, message_tick)
})?;
Expand Down
2 changes: 1 addition & 1 deletion src/core/replication.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod change_message_arrays;
pub mod change_message_flags;
pub mod command_markers;
pub mod deferred_entity;
pub mod replicated_clients;
Expand Down
48 changes: 0 additions & 48 deletions src/core/replication/change_message_arrays.rs

This file was deleted.

48 changes: 48 additions & 0 deletions src/core/replication/change_message_flags.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use bitflags::bitflags;

bitflags! {
/// Types of data included in the change message if the bit is set.
///
/// Serialized at the beginning of the message.
#[derive(Default, Clone, Copy, PartialEq, Eq, Debug)]
pub(crate) struct ChangeMessageFlags: u8 {
const MAPPINGS = 0b00000001;
const DESPAWNS = 0b00000010;
const REMOVALS = 0b00000100;
const CHANGES = 0b00001000;
}
}

impl ChangeMessageFlags {
/// Returns the last set flag in the message.
pub(crate) fn last(self) -> ChangeMessageFlags {
debug_assert!(!self.is_empty());
let zeroes = u8::BITS - 1 - self.bits().leading_zeros();
ChangeMessageFlags::from_bits_retain(1 << zeroes)
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn last() {
assert_eq!(
ChangeMessageFlags::CHANGES.last(),
ChangeMessageFlags::CHANGES
);
assert_eq!(
ChangeMessageFlags::MAPPINGS.last(),
ChangeMessageFlags::MAPPINGS
);
assert_eq!(
ChangeMessageFlags::all().last(),
ChangeMessageFlags::CHANGES
);
assert_eq!(
(ChangeMessageFlags::DESPAWNS | ChangeMessageFlags::REMOVALS).last(),
ChangeMessageFlags::REMOVALS
);
}
}
68 changes: 33 additions & 35 deletions src/server/replication_messages/change_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use super::{
use crate::core::{
channels::ReplicationChannel,
replication::{
change_message_arrays::ChangeMessageArrays,
change_message_flags::ChangeMessageFlags,
replicated_clients::{client_visibility::Visibility, ReplicatedClient},
},
replicon_server::RepliconServer,
Expand All @@ -20,14 +20,12 @@ use crate::core::{
/// Contains tick, mappings, insertions, removals and despawns that
/// happened on this tick.
///
/// The data is serialized manyally and stored in the form of ranges
/// The data is serialized manually and stored in the form of ranges
/// from [`SerializedData`].
///
/// Sent over [`ReplicationChannel::Changes`] channel.
///
/// All fields encoded as optional arrays, and their presence is encoded in
/// the [`ChangeMessageArrays`] bitset. Removals and changes also have nested
/// arrays for entity components.
/// Some data is optional, and their presence is encoded in the [`ChangeMessageFlags`] bitset.
///
/// To know how much data array takes, we serialize it's length. We use `usize`,
/// but we use variable integer encoding, so they are correctly deserialized even
Expand Down Expand Up @@ -205,27 +203,27 @@ impl ChangeMessage {
serialized: &SerializedData,
server_tick: Range<usize>,
) -> bincode::Result<()> {
let arrays = self.arrays();
let last_array = arrays.last();
let flags = self.flags();
let last_flag = flags.last();

// Precalcualte size first to avoid extra allocations.
let mut message_size = size_of::<ChangeMessageArrays>() + server_tick.len();
for (_, array) in arrays.iter_names() {
match array {
ChangeMessageArrays::MAPPINGS => {
if array != last_array {
let mut message_size = size_of::<ChangeMessageFlags>() + server_tick.len();
for (_, flag) in flags.iter_names() {
match flag {
ChangeMessageFlags::MAPPINGS => {
if flag != last_flag {
message_size += self.mappings_len.required_space();
}
message_size += self.mappings.len();
}
ChangeMessageArrays::DESPAWNS => {
if array != last_array {
ChangeMessageFlags::DESPAWNS => {
if flag != last_flag {
message_size += self.despawns_len.required_space();
}
message_size += self.despawns.iter().map(|range| range.len()).sum::<usize>();
}
ChangeMessageArrays::REMOVALS => {
if array != last_array {
ChangeMessageFlags::REMOVALS => {
if flag != last_flag {
message_size += self.removals.len().required_space();
}
message_size += self
Expand All @@ -234,7 +232,7 @@ impl ChangeMessage {
.map(|removals| removals.size())
.sum::<usize>();
}
ChangeMessageArrays::CHANGES => {
ChangeMessageFlags::CHANGES => {
message_size += self
.changes
.iter()
Expand All @@ -250,28 +248,28 @@ impl ChangeMessage {
}

let mut message = Vec::with_capacity(message_size);
message.write_fixedint(arrays.bits())?;
message.write_fixedint(flags.bits())?;
message.extend_from_slice(&serialized[server_tick]);
for (_, array) in arrays.iter_names() {
match array {
ChangeMessageArrays::MAPPINGS => {
// Always write size since the message can't have only mappings array.
for (_, flag) in flags.iter_names() {
match flag {
ChangeMessageFlags::MAPPINGS => {
// Always write size since the message can't have only mappings.
// Otherwise this would mean that the client already received the mapped
// entity and it's already mapped or server sends an invisible entity which
// is an error.
message.write_varint(self.mappings_len)?;
message.extend_from_slice(&serialized[self.mappings.clone()]);
}
ChangeMessageArrays::DESPAWNS => {
if array != last_array {
ChangeMessageFlags::DESPAWNS => {
if flag != last_flag {
message.write_varint(self.despawns_len)?;
}
for range in &self.despawns {
message.extend_from_slice(&serialized[range.clone()]);
}
}
ChangeMessageArrays::REMOVALS => {
if array != last_array {
ChangeMessageFlags::REMOVALS => {
if flag != last_flag {
message.write_varint(self.removals.len())?;
}
for removals in &self.removals {
Expand All @@ -280,8 +278,8 @@ impl ChangeMessage {
message.extend_from_slice(&serialized[removals.fn_ids.clone()]);
}
}
ChangeMessageArrays::CHANGES => {
// Changes are always the last array, don't write len for it.
ChangeMessageFlags::CHANGES => {
// Changes are always last, don't write len for it.
for changes in &self.changes {
message.extend_from_slice(&serialized[changes.entity.clone()]);
message.write_varint(changes.components_len)?;
Expand All @@ -301,23 +299,23 @@ impl ChangeMessage {
Ok(())
}

fn arrays(&self) -> ChangeMessageArrays {
let mut header = ChangeMessageArrays::default();
fn flags(&self) -> ChangeMessageFlags {
let mut flags = ChangeMessageFlags::default();

if !self.mappings.is_empty() {
header |= ChangeMessageArrays::MAPPINGS;
flags |= ChangeMessageFlags::MAPPINGS;
}
if !self.despawns.is_empty() {
header |= ChangeMessageArrays::DESPAWNS;
flags |= ChangeMessageFlags::DESPAWNS;
}
if !self.removals.is_empty() {
header |= ChangeMessageArrays::REMOVALS;
flags |= ChangeMessageFlags::REMOVALS;
}
if !self.changes.is_empty() {
header |= ChangeMessageArrays::CHANGES;
flags |= ChangeMessageFlags::CHANGES;
}

header
flags
}

/// Clears all chunks.
Expand Down
2 changes: 1 addition & 1 deletion src/server/replication_messages/mutate_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::core::{
/// independently on the client.
/// Message splits only happen per-entity to avoid weird behavior from partial entity mutations.
///
/// The data is serialized manyally and stored in the form of ranges
/// The data is serialized manually and stored in the form of ranges
/// from [`SerializedData`].
///
/// Sent over the [`ReplicationChannel::Mutations`] channel. If the message gets lost, we try to resend it manually,
Expand Down

0 comments on commit 9f204f8

Please sign in to comment.