Skip to content

Commit cb9b499

Browse files
authored
Preserve removals before inserts (#462)
* Use more explicit variable name * Remove `removals_id` into `removal_ids` * Preserve removals even when the component is immediately inserted To avoid inconsistent triggers behavior between the server and client.
1 parent 1e42c4f commit cb9b499

2 files changed

Lines changed: 28 additions & 16 deletions

File tree

src/server/removal_buffer.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ fn buffer_removals(
4141
mut removal_buffer: ResMut<RemovalBuffer>,
4242
rules: Res<ReplicationRules>,
4343
) {
44-
for (&entity, components) in removal_reader.read() {
44+
for (&entity, removed_components) in removal_reader.read() {
4545
let location = entities
4646
.get(entity)
4747
.expect("removals count only existing entities");
4848
let archetype = archetypes.get(location.archetype_id).unwrap();
4949

50-
removal_buffer.update(&rules, archetype, entity, components);
50+
removal_buffer.update(&rules, archetype, entity, removed_components);
5151
}
5252
}
5353

@@ -157,20 +157,20 @@ impl RemovalBuffer {
157157
rules: &ReplicationRules,
158158
archetype: &Archetype,
159159
entity: Entity,
160-
components: &HashSet<ComponentId>,
160+
removed_components: &HashSet<ComponentId>,
161161
) {
162162
let mut removed_ids = self.ids_buffer.pop().unwrap_or_default();
163163
for rule in rules
164164
.iter()
165-
.filter(|rule| rule.matches_removals(archetype, components))
165+
.filter(|rule| rule.matches_removals(archetype, removed_components))
166166
{
167167
for &(component_id, fns_id) in &rule.components {
168168
// Since rules are sorted by priority,
169169
// we are inserting only new components that aren't present.
170170
if removed_ids
171171
.iter()
172172
.all(|&(removed_id, _)| removed_id != component_id)
173-
&& !archetype.contains(component_id)
173+
&& removed_components.contains(&component_id)
174174
{
175175
removed_ids.push((component_id, fns_id));
176176
}
@@ -258,8 +258,8 @@ mod tests {
258258
let removal_buffer = app.world().resource::<RemovalBuffer>();
259259
assert_eq!(removal_buffer.removals.len(), 1);
260260

261-
let removals_id = removal_buffer.removals.get(&entity).unwrap();
262-
assert_eq!(removals_id.len(), 1);
261+
let removal_ids = removal_buffer.removals.get(&entity).unwrap();
262+
assert_eq!(removal_ids.len(), 1);
263263
}
264264

265265
#[test]
@@ -288,8 +288,8 @@ mod tests {
288288
let removal_buffer = app.world().resource::<RemovalBuffer>();
289289
assert_eq!(removal_buffer.removals.len(), 1);
290290

291-
let removals_id = removal_buffer.removals.get(&entity).unwrap();
292-
assert_eq!(removals_id.len(), 2);
291+
let removal_ids = removal_buffer.removals.get(&entity).unwrap();
292+
assert_eq!(removal_ids.len(), 2);
293293
}
294294

295295
#[test]
@@ -318,8 +318,8 @@ mod tests {
318318
let removal_buffer = app.world().resource::<RemovalBuffer>();
319319
assert_eq!(removal_buffer.removals.len(), 1);
320320

321-
let removals_id = removal_buffer.removals.get(&entity).unwrap();
322-
assert_eq!(removals_id.len(), 1);
321+
let removal_ids = removal_buffer.removals.get(&entity).unwrap();
322+
assert_eq!(removal_ids.len(), 1);
323323
}
324324

325325
#[test]
@@ -349,8 +349,8 @@ mod tests {
349349
let removal_buffer = app.world().resource::<RemovalBuffer>();
350350
assert_eq!(removal_buffer.removals.len(), 1);
351351

352-
let removals_id = removal_buffer.removals.get(&entity).unwrap();
353-
assert_eq!(removals_id.len(), 2);
352+
let removal_ids = removal_buffer.removals.get(&entity).unwrap();
353+
assert_eq!(removal_ids.len(), 2);
354354
}
355355

356356
#[test]
@@ -380,8 +380,8 @@ mod tests {
380380
let removal_buffer = app.world().resource::<RemovalBuffer>();
381381
assert_eq!(removal_buffer.removals.len(), 1);
382382

383-
let removals_id = removal_buffer.removals.get(&entity).unwrap();
384-
assert_eq!(removals_id.len(), 1);
383+
let removal_ids = removal_buffer.removals.get(&entity).unwrap();
384+
assert_eq!(removal_ids.len(), 1);
385385
}
386386

387387
#[test]

tests/insertion.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use bevy::{ecs::entity::MapEntities, prelude::*};
1+
use bevy::{
2+
ecs::{entity::MapEntities, system::SystemState},
3+
prelude::*,
4+
};
25
use bevy_replicon::{
36
client::confirm_history::{ConfirmHistory, EntityReplicated},
47
prelude::*,
@@ -388,6 +391,15 @@ fn after_removal() {
388391

389392
let mut components = client_app.world_mut().query::<&DummyComponent>();
390393
assert_eq!(components.iter(client_app.world()).count(), 1);
394+
395+
let mut system_state: SystemState<RemovedComponents<DummyComponent>> =
396+
SystemState::new(client_app.world_mut());
397+
let removals = system_state.get(client_app.world());
398+
assert_eq!(
399+
removals.len(),
400+
1,
401+
"removal for the old value should also be triggered"
402+
);
391403
}
392404

393405
#[test]

0 commit comments

Comments
 (0)