Skip to content

Commit

Permalink
Implement ResFlags
Browse files Browse the repository at this point in the history
  • Loading branch information
TheRawMeatball committed Feb 12, 2021
1 parent da6b071 commit c99d37a
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 30 deletions.
56 changes: 33 additions & 23 deletions crates/bevy_ecs/src/resource/resource_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,47 @@ use std::{
#[derive(Debug)]
pub struct Res<'a, T: Resource> {
value: &'a T,
}

pub struct ResFlags<'a, T: Resource> {
added: bool,
mutated: bool,
_marker: PhantomData<&'a T>,
}

impl<'a, T: Resource> ResFlags<'a, T> {
pub fn new(added: bool, mutated: bool) -> Self {
Self {
added,
mutated,
_marker: Default::default(),
}
}

#[inline(always)]
pub fn added(&self) -> bool {
self.added
}

#[inline(always)]
pub fn mutated(&self) -> bool {
self.mutated
}

#[inline(always)]
pub fn changed(&self) -> bool {
self.added || self.mutated
}
}

impl<'a, T: Resource> Res<'a, T> {
/// Creates a reference cell to a Resource from a pointer
///
/// # Safety
/// The pointer must have correct lifetime / storage
pub unsafe fn new(value: NonNull<T>, added: bool, changed: bool) -> Self {
pub unsafe fn new(value: NonNull<T>) -> Self {
Self {
value: &*value.as_ptr(),
added,
mutated: changed,
}
}
}
Expand All @@ -38,23 +65,6 @@ impl<'a, T: Resource> Deref for Res<'a, T> {
}
}

impl<'a, T: Resource> Res<'a, T> {
#[inline(always)]
pub fn added(this: &Self) -> bool {
this.added
}

#[inline(always)]
pub fn mutated(this: &Self) -> bool {
this.mutated
}

#[inline(always)]
pub fn changed(this: &Self) -> bool {
this.added || this.mutated
}
}

/// Unique borrow of a Resource
#[derive(Debug)]
pub struct ResMut<'a, T: Resource> {
Expand Down Expand Up @@ -98,17 +108,17 @@ impl<'a, T: Resource> DerefMut for ResMut<'a, T> {

impl<'a, T: Resource> ResMut<'a, T> {
#[inline(always)]
pub fn added(this: Self) -> bool {
pub fn added(this: &Self) -> bool {
this.added
}

#[inline(always)]
pub fn mutated(this: Self) -> bool {
pub fn mutated(this: &Self) -> bool {
unsafe { *this.mutated }
}

#[inline(always)]
pub fn changed(this: Self) -> bool {
pub fn changed(this: &Self) -> bool {
this.added || Self::mutated(this)
}
}
Expand Down
8 changes: 4 additions & 4 deletions crates/bevy_ecs/src/system/into_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,8 @@ mod tests {
clear_trackers_system,
resource::{Res, ResMut, Resources},
schedule::Schedule,
Entity, IntoExclusiveSystem, Local, Query, QuerySet, Stage, System, SystemStage, With,
World,
Entity, IntoExclusiveSystem, Local, Query, QuerySet, ResFlags, Stage, System, SystemStage,
With, World,
};

#[derive(Debug, Eq, PartialEq, Default)]
Expand Down Expand Up @@ -444,8 +444,8 @@ mod tests {

#[test]
fn changed_resource_system() {
fn incr_e_on_flip(run_on_flip: Res<bool>, mut query: Query<&mut i32>) {
if !Res::changed(&run_on_flip) {
fn incr_e_on_flip(run_on_flip: ResFlags<bool>, mut query: Query<&mut i32>) {
if !run_on_flip.changed() {
return;
}

Expand Down
40 changes: 37 additions & 3 deletions crates/bevy_ecs/src/system/system_param.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
ArchetypeComponent, Commands, Fetch, FromResources, Local, NonSend, Or, Query, QueryAccess,
QueryFilter, QuerySet, QueryTuple, Res, ResMut, Resource, ResourceIndex, Resources,
QueryFilter, QuerySet, QueryTuple, Res, ResFlags, ResMut, Resource, ResourceIndex, Resources,
SystemState, TypeAccess, World, WorldQuery,
};
use parking_lot::Mutex;
Expand Down Expand Up @@ -173,8 +173,42 @@ impl<'a, T: Resource> FetchSystemParam<'a> for FetchRes<T> {
_world: &'a World,
resources: &'a Resources,
) -> Option<Self::Item> {
let result = resources.get_unsafe_ref_with_added_and_mutated::<T>(ResourceIndex::Global);
Some(Res::new(result.0, *result.1.as_ptr(), *result.2.as_ptr()))
Some(Res::new(
resources.get_unsafe_ref::<T>(ResourceIndex::Global),
))
}
}

pub struct FetchResFlags<T>(PhantomData<T>);

impl<'a, T: Resource> SystemParam for ResFlags<'a, T> {
type Fetch = FetchResFlags<T>;
}

impl<'a, T: Resource> FetchSystemParam<'a> for FetchResFlags<T> {
type Item = ResFlags<'a, T>;

fn init(system_state: &mut SystemState, _world: &World, _resources: &mut Resources) {
if system_state.resource_access.is_write(&TypeId::of::<T>()) {
panic!(
"System `{}` has a `Res<{res}>` parameter that conflicts with \
another parameter with mutable access to the same `{res}` resource.",
system_state.name,
res = std::any::type_name::<T>()
);
}
system_state.resource_access.add_read(TypeId::of::<T>());
}

#[inline]
unsafe fn get_param(
_system_state: &'a SystemState,
_world: &'a World,
resources: &'a Resources,
) -> Option<Self::Item> {
let (_, added, mutated) =
resources.get_unsafe_ref_with_added_and_mutated::<T>(ResourceIndex::Global);
Some(ResFlags::new(*added.as_ptr(), *mutated.as_ptr()))
}
}

Expand Down

0 comments on commit c99d37a

Please sign in to comment.