Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ComponentId to all component-related contexts #343

Merged
merged 2 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [0.28.4] - 2024-10-15

### Added

- `ComponentId` to all component-related contexts.

### Fixed

- Synchronize server events with init messages properly when `ServerTick` is not updated every app tick.
Expand Down
16 changes: 11 additions & 5 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,11 @@ fn apply_init_components(
let mut components_len = 0u32;
while cursor.position() < end_pos {
let fns_id = DefaultOptions::new().deserialize_from(&mut *cursor)?;
let (component_fns, rule_fns) = params.registry.get(fns_id);
let (component_id, component_fns, rule_fns) = params.registry.get(fns_id);
match components_kind {
ComponentsKind::Insert => {
let mut ctx = WriteCtx::new(&mut commands, params.entity_map, message_tick);
let mut ctx =
WriteCtx::new(&mut commands, params.entity_map, component_id, message_tick);

// SAFETY: `rule_fns` and `component_fns` were created for the same type.
unsafe {
Expand All @@ -355,7 +356,11 @@ fn apply_init_components(
}
}
ComponentsKind::Removal => {
let mut ctx = RemoveCtx::new(&mut commands, message_tick);
let mut ctx = RemoveCtx {
commands: &mut commands,
message_tick,
component_id,
};
component_fns.remove(&mut ctx, params.entity_markers, &mut client_entity);
}
}
Expand Down Expand Up @@ -465,8 +470,9 @@ fn apply_update_components(
let mut components_count = 0u32;
while cursor.position() < end_pos {
let fns_id = DefaultOptions::new().deserialize_from(&mut *cursor)?;
let (component_fns, rule_fns) = params.registry.get(fns_id);
let mut ctx = WriteCtx::new(&mut commands, params.entity_map, message_tick);
let (component_id, component_fns, rule_fns) = params.registry.get(fns_id);
let mut ctx =
WriteCtx::new(&mut commands, params.entity_map, component_id, message_tick);

// SAFETY: `rule_fns` and `component_fns` were created for the same type.
unsafe {
Expand Down
20 changes: 11 additions & 9 deletions src/core/ctx.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy::{prelude::*, reflect::TypeRegistry};
use bevy::{ecs::component::ComponentId, prelude::*, reflect::TypeRegistry};

use super::{replicon_tick::RepliconTick, server_entity_map::ServerEntityMap, Replicated};

Expand All @@ -7,6 +7,9 @@ use super::{replicon_tick::RepliconTick, server_entity_map::ServerEntityMap, Rep
pub struct SerializeCtx {
/// Current tick.
pub server_tick: RepliconTick,

/// ID of the serializing component.
pub component_id: ComponentId,
}

/// Replication context for writing and deserialization.
Expand All @@ -18,6 +21,9 @@ pub struct WriteCtx<'a, 'w, 's> {
/// Maps server entities to client entities and vice versa.
pub entity_map: &'a mut ServerEntityMap,

/// ID of the writing component.
pub component_id: ComponentId,

/// Tick for the currently processing message.
pub message_tick: RepliconTick,

Expand All @@ -29,11 +35,13 @@ impl<'a, 'w, 's> WriteCtx<'a, 'w, 's> {
pub(crate) fn new(
commands: &'a mut Commands<'w, 's>,
entity_map: &'a mut ServerEntityMap,
component_id: ComponentId,
message_tick: RepliconTick,
) -> Self {
Self {
commands,
entity_map,
component_id,
message_tick,
ignore_mapping: false,
}
Expand All @@ -59,15 +67,9 @@ pub struct RemoveCtx<'a, 'w, 's> {

/// Tick for the currently processing message.
pub message_tick: RepliconTick,
}

impl<'a, 'w, 's> RemoveCtx<'a, 'w, 's> {
pub(crate) fn new(commands: &'a mut Commands<'w, 's>, message_tick: RepliconTick) -> Self {
Self {
commands,
message_tick,
}
}
/// ID of the removing component.
pub component_id: ComponentId,
}

/// Replication context for despawn.
Expand Down
18 changes: 9 additions & 9 deletions src/core/replication_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct ReplicationRegistry {
/// Functions for replicated components.
///
/// Unique for each component.
components: Vec<(ComponentFns, ComponentId)>,
components: Vec<(ComponentId, ComponentFns)>,

/// Serialization/deserialization functions for a component and
/// the component's index in [`Self::components`].
Expand All @@ -45,7 +45,7 @@ impl ReplicationRegistry {
/// [`CommandMarkers::insert`](super::command_markers::CommandMarkers::insert)
pub(super) fn register_marker(&mut self, marker_id: CommandMarkerIndex) {
self.marker_slots += 1;
for (command_fns, _) in &mut self.components {
for (_, command_fns) in &mut self.components {
command_fns.add_marker_slot(marker_id);
}
}
Expand All @@ -67,7 +67,7 @@ impl ReplicationRegistry {
remove: RemoveFn,
) {
let (index, _) = self.init_component_fns::<C>(world);
let (component_fns, _) = &mut self.components[index];
let (_, component_fns) = &mut self.components[index];
let command_fns = UntypedCommandFns::new(write, remove);

// SAFETY: `component_fns` and `command_fns` were created for `C`.
Expand All @@ -86,7 +86,7 @@ impl ReplicationRegistry {
remove: RemoveFn,
) {
let (index, _) = self.init_component_fns::<C>(world);
let (component_fns, _) = &mut self.components[index];
let (_, component_fns) = &mut self.components[index];
let command_fns = UntypedCommandFns::new(write, remove);

// SAFETY: `component_fns` and `command_fns` were created for `C`.
Expand Down Expand Up @@ -122,10 +122,10 @@ impl ReplicationRegistry {
let index = self
.components
.iter()
.position(|&(_, id)| id == component_id)
.position(|&(id, _)| id == component_id)
.unwrap_or_else(|| {
self.components
.push((ComponentFns::new::<C>(self.marker_slots), component_id));
.push((component_id, ComponentFns::new::<C>(self.marker_slots)));
self.components.len() - 1
});

Expand All @@ -135,16 +135,16 @@ impl ReplicationRegistry {
/// Returns associates functions.
///
/// See also [`Self::register_rule_fns`].
pub(crate) fn get(&self, fns_id: FnsId) -> (&ComponentFns, &UntypedRuleFns) {
pub(crate) fn get(&self, fns_id: FnsId) -> (ComponentId, &ComponentFns, &UntypedRuleFns) {
let (rule_fns, index) = self
.rules
.get(fns_id.0)
.expect("serde function IDs should be obtained from the same instance");

// SAFETY: index obtained from `rules` is always valid.
let (command_fns, _) = unsafe { self.components.get_unchecked(*index) };
let (component_id, command_fns) = unsafe { self.components.get_unchecked(*index) };

(command_fns, rule_fns)
(*component_id, command_fns, rule_fns)
}
}

Expand Down
20 changes: 14 additions & 6 deletions src/core/replication_registry/test_fns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,12 @@ pub trait TestFnsEntityExt {
impl TestFnsEntityExt for EntityWorldMut<'_> {
fn serialize(&mut self, fns_info: FnsInfo, server_tick: RepliconTick) -> Vec<u8> {
let registry = self.world().resource::<ReplicationRegistry>();
let (component_fns, rule_fns) = registry.get(fns_info.fns_id());
let (component_id, component_fns, rule_fns) = registry.get(fns_info.fns_id());
let mut cursor = Cursor::default();
let ctx = SerializeCtx { server_tick };
let ctx = SerializeCtx {
server_tick,
component_id,
};
let ptr = self.get_by_id(fns_info.component_id()).unwrap_or_else(|| {
let components = self.world().components();
let component_name = components
Expand Down Expand Up @@ -133,9 +136,10 @@ impl TestFnsEntityExt for EntityWorldMut<'_> {
let mut commands =
Commands::new_from_entities(&mut queue, world_cell.entities());

let (component_fns, rule_fns) = registry.get(fns_info.fns_id());
let (component_id, component_fns, rule_fns) = registry.get(fns_info.fns_id());
let mut cursor = Cursor::new(data);
let mut ctx = WriteCtx::new(&mut commands, &mut entity_map, message_tick);
let mut ctx =
WriteCtx::new(&mut commands, &mut entity_map, component_id, message_tick);

unsafe {
component_fns
Expand Down Expand Up @@ -172,8 +176,12 @@ impl TestFnsEntityExt for EntityWorldMut<'_> {
let mut queue = CommandQueue::default();
let mut commands = Commands::new_from_entities(&mut queue, world_cell.entities());

let (component_fns, _) = registry.get(fns_info.fns_id());
let mut ctx = RemoveCtx::new(&mut commands, message_tick);
let (component_id, component_fns, _) = registry.get(fns_info.fns_id());
let mut ctx = RemoveCtx {
commands: &mut commands,
message_tick,
component_id,
};

component_fns.remove(&mut ctx, &entity_markers, &mut entity);

Expand Down
8 changes: 6 additions & 2 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,12 @@ fn collect_changes(
)
};

let (component_fns, rule_fns) = registry.get(replicated_component.fns_id);
let ctx = SerializeCtx { server_tick };
let (component_id, component_fns, rule_fns) =
registry.get(replicated_component.fns_id);
let ctx = SerializeCtx {
server_tick,
component_id,
};
let mut shared_bytes = None;
for (init_message, update_message, client) in messages.iter_mut_with_clients() {
let visibility = client.visibility().cached_visibility();
Expand Down