Skip to content

Commit

Permalink
move component ticks and review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
NathanSWard committed Jun 22, 2021
1 parent f0ffea8 commit c9b16ed
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 78 deletions.
3 changes: 2 additions & 1 deletion crates/bevy_ecs/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ pub use bevy_ecs_macros::Bundle;

use crate::{
archetype::ComponentStatus,
component::{Component, ComponentId, ComponentTicks, Components, StorageType, TypeInfo},
change_detection::ComponentTicks,
component::{Component, ComponentId, Components, StorageType, TypeInfo},
entity::Entity,
storage::{SparseSetIndex, SparseSets, Table},
};
Expand Down
71 changes: 68 additions & 3 deletions crates/bevy_ecs/src/change_detection.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::component::{Component, ComponentTicks};
use crate::component::Component;
use bevy_reflect::Reflect;
use std::ops::{Deref, DerefMut};

Expand All @@ -25,8 +25,8 @@ pub trait DetectChanges {
/// system.
fn is_added(&self) -> bool;

/// Returns true if (and only if) this value been changed since the last execution of this
/// system.
/// Returns true if (and only if) this value has been mutably accesses since the last execution
/// of this system.
fn is_changed(&self) -> bool;
}

Expand Down Expand Up @@ -133,6 +133,71 @@ macro_rules! impl_debug {
};
}

#[derive(Copy, Clone, Debug)]
pub struct ComponentTicks {
pub(crate) added: u32,
pub(crate) changed: u32,
}

impl ComponentTicks {
#[inline]
pub fn is_added(&self, last_change_tick: u32, change_tick: u32) -> bool {
// The comparison is relative to `change_tick` so that we can detect changes over the whole
// `u32` range. Comparing directly the ticks would limit to half that due to overflow
// handling.
let component_delta = change_tick.wrapping_sub(self.added);
let system_delta = change_tick.wrapping_sub(last_change_tick);

component_delta < system_delta
}

#[inline]
pub fn is_changed(&self, last_change_tick: u32, change_tick: u32) -> bool {
let component_delta = change_tick.wrapping_sub(self.changed);
let system_delta = change_tick.wrapping_sub(last_change_tick);

component_delta < system_delta
}

pub(crate) fn new(change_tick: u32) -> Self {
Self {
added: change_tick,
changed: change_tick,
}
}

pub(crate) fn check_ticks(&mut self, change_tick: u32) {
check_tick(&mut self.added, change_tick);
check_tick(&mut self.changed, change_tick);
}

/// Manually sets the change tick.
/// Usually, this is done automatically via the [`DerefMut`](std::ops::DerefMut) implementation
/// on [`Mut`](crate::world::Mut) or [`ResMut`](crate::system::ResMut) etc.
///
/// # Example
/// ```rust,no_run
/// # use bevy_ecs::{world::World, component::ComponentTicks};
/// let world: World = unimplemented!();
/// let component_ticks: ComponentTicks = unimplemented!();
///
/// component_ticks.set_changed(world.read_change_tick());
/// ```
#[inline]
pub fn set_changed(&mut self, change_tick: u32) {
self.changed = change_tick;
}
}

fn check_tick(last_change_tick: &mut u32, change_tick: u32) {
let tick_delta = change_tick.wrapping_sub(*last_change_tick);
const MAX_DELTA: u32 = (u32::MAX / 4) * 3;
// Clamp to max delta
if tick_delta > MAX_DELTA {
*last_change_tick = change_tick.wrapping_sub(MAX_DELTA);
}
}

pub(crate) struct Ticks {
pub(crate) component_ticks: ComponentTicks,
pub(crate) last_change_tick: u32,
Expand Down
65 changes: 0 additions & 65 deletions crates/bevy_ecs/src/component/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,68 +305,3 @@ impl Components {
ComponentId(*index)
}
}

#[derive(Copy, Clone, Debug)]
pub struct ComponentTicks {
pub(crate) added: u32,
pub(crate) changed: u32,
}

impl ComponentTicks {
#[inline]
pub fn is_added(&self, last_change_tick: u32, change_tick: u32) -> bool {
// The comparison is relative to `change_tick` so that we can detect changes over the whole
// `u32` range. Comparing directly the ticks would limit to half that due to overflow
// handling.
let component_delta = change_tick.wrapping_sub(self.added);
let system_delta = change_tick.wrapping_sub(last_change_tick);

component_delta < system_delta
}

#[inline]
pub fn is_changed(&self, last_change_tick: u32, change_tick: u32) -> bool {
let component_delta = change_tick.wrapping_sub(self.changed);
let system_delta = change_tick.wrapping_sub(last_change_tick);

component_delta < system_delta
}

pub(crate) fn new(change_tick: u32) -> Self {
Self {
added: change_tick,
changed: change_tick,
}
}

pub(crate) fn check_ticks(&mut self, change_tick: u32) {
check_tick(&mut self.added, change_tick);
check_tick(&mut self.changed, change_tick);
}

/// Manually sets the change tick.
/// Usually, this is done automatically via the [`DerefMut`](std::ops::DerefMut) implementation
/// on [`Mut`](crate::world::Mut) or [`ResMut`](crate::system::ResMut) etc.
///
/// # Example
/// ```rust,no_run
/// # use bevy_ecs::{world::World, component::ComponentTicks};
/// let world: World = unimplemented!();
/// let component_ticks: ComponentTicks = unimplemented!();
///
/// component_ticks.set_changed(world.read_change_tick());
/// ```
#[inline]
pub fn set_changed(&mut self, change_tick: u32) {
self.changed = change_tick;
}
}

fn check_tick(last_change_tick: &mut u32, change_tick: u32) {
let tick_delta = change_tick.wrapping_sub(*last_change_tick);
const MAX_DELTA: u32 = (u32::MAX / 4) * 3;
// Clamp to max delta
if tick_delta > MAX_DELTA {
*last_change_tick = change_tick.wrapping_sub(MAX_DELTA);
}
}
4 changes: 2 additions & 2 deletions crates/bevy_ecs/src/query/fetch.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
archetype::{Archetype, ArchetypeComponentId},
change_detection::TicksMut,
component::{Component, ComponentId, ComponentTicks, StorageType},
change_detection::{ComponentTicks, TicksMut},
component::{Component, ComponentId, StorageType},
entity::Entity,
query::{Access, FilteredAccess},
storage::{ComponentSparseSet, Table, Tables},
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_ecs/src/query/filter.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::{
archetype::{Archetype, ArchetypeComponentId},
bundle::Bundle,
component::{Component, ComponentId, ComponentTicks, StorageType},
change_detection::ComponentTicks,
component::{Component, ComponentId, StorageType},
entity::Entity,
query::{Access, Fetch, FetchState, FilteredAccess, WorldQuery},
storage::{ComponentSparseSet, Table, Tables},
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_ecs/src/storage/sparse_set.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
component::{ComponentId, ComponentInfo, ComponentTicks},
change_detection::ComponentTicks,
component::{ComponentId, ComponentInfo},
entity::Entity,
storage::BlobVec,
};
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_ecs/src/storage/table.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
component::{ComponentId, ComponentInfo, ComponentTicks, Components},
change_detection::ComponentTicks,
component::{ComponentId, ComponentInfo, Components},
entity::Entity,
storage::{BlobVec, SparseSet},
};
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ecs/src/world/entity_ref.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::{
archetype::{Archetype, ArchetypeId, Archetypes, ComponentStatus},
bundle::{Bundle, BundleInfo},
change_detection::TicksMut,
component::{Component, ComponentId, ComponentTicks, Components, StorageType},
change_detection::{ComponentTicks, TicksMut},
component::{Component, ComponentId, Components, StorageType},
entity::{Entities, Entity, EntityLocation},
storage::{SparseSet, Storages},
world::{Mut, World},
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ecs/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ pub use world_cell::*;
use crate::{
archetype::{ArchetypeComponentId, ArchetypeComponentInfo, ArchetypeId, Archetypes},
bundle::{Bundle, Bundles},
change_detection::ComponentTicks,
change_detection::TicksMut,
component::{
Component, ComponentDescriptor, ComponentId, ComponentTicks, Components, ComponentsError,
StorageType,
Component, ComponentDescriptor, ComponentId, Components, ComponentsError, StorageType,
},
entity::{Entities, Entity},
query::{FilterFetch, QueryState, WorldQuery},
Expand Down

0 comments on commit c9b16ed

Please sign in to comment.