Skip to content

Commit

Permalink
wip pulling resources out of components
Browse files Browse the repository at this point in the history
  • Loading branch information
sseemayer committed Oct 24, 2021
1 parent 8a354c0 commit 2200887
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 83 deletions.
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/change_detection.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Types that detect when their internal data mutate.
use crate::{component::ComponentTicks, system::Resource};
use crate::{component::ComponentTicks, resource::Resource};
use bevy_reflect::Reflect;
use std::ops::{Deref, DerefMut};

Expand Down
54 changes: 3 additions & 51 deletions crates/bevy_ecs/src/component.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Types for declaring and storing [`Component`]s.
use crate::{
resource::Resource,
storage::{SparseSetIndex, Storages},
system::Resource,
};
pub use bevy_ecs_macros::Component;
use std::{
Expand Down Expand Up @@ -132,7 +132,7 @@ impl ComponentInfo {
self.descriptor.is_send_and_sync
}

fn new(id: ComponentId, descriptor: ComponentDescriptor) -> Self {
pub(crate) fn new(id: ComponentId, descriptor: ComponentDescriptor) -> Self {
ComponentInfo { id, descriptor }
}
}
Expand Down Expand Up @@ -205,7 +205,7 @@ impl ComponentDescriptor {
}
}

fn new_non_send<T: Any>(storage_type: StorageType) -> Self {
pub(crate) fn new_non_send<T: Any>(storage_type: StorageType) -> Self {
Self {
name: std::any::type_name::<T>().to_string(),
storage_type,
Expand Down Expand Up @@ -236,7 +236,6 @@ impl ComponentDescriptor {
pub struct Components {
components: Vec<ComponentInfo>,
indices: std::collections::HashMap<TypeId, usize, fxhash::FxBuildHasher>,
resource_indices: std::collections::HashMap<TypeId, usize, fxhash::FxBuildHasher>,
}

#[derive(Debug, Error)]
Expand Down Expand Up @@ -295,53 +294,6 @@ impl Components {
pub fn get_id(&self, type_id: TypeId) -> Option<ComponentId> {
self.indices.get(&type_id).map(|index| ComponentId(*index))
}

#[inline]
pub fn get_resource_id(&self, type_id: TypeId) -> Option<ComponentId> {
self.resource_indices
.get(&type_id)
.map(|index| ComponentId(*index))
}

#[inline]
pub fn init_resource<T: Resource>(&mut self) -> ComponentId {
// SAFE: The [`ComponentDescriptor`] matches the [`TypeId`]
unsafe {
self.get_or_insert_resource_with(TypeId::of::<T>(), || {
ComponentDescriptor::new_resource::<T>(StorageType::default())
})
}
}

#[inline]
pub fn init_non_send<T: Any>(&mut self) -> ComponentId {
// SAFE: The [`ComponentDescriptor`] matches the [`TypeId`]
unsafe {
self.get_or_insert_resource_with(TypeId::of::<T>(), || {
ComponentDescriptor::new_non_send::<T>(StorageType::default())
})
}
}

/// # Safety
///
/// The [`ComponentDescriptor`] must match the [`TypeId`]
#[inline]
unsafe fn get_or_insert_resource_with(
&mut self,
type_id: TypeId,
func: impl FnOnce() -> ComponentDescriptor,
) -> ComponentId {
let components = &mut self.components;
let index = self.resource_indices.entry(type_id).or_insert_with(|| {
let descriptor = func();
let index = components.len();
components.push(ComponentInfo::new(ComponentId(index), descriptor));
index
});

ComponentId(*index)
}
}

impl<'c> IntoIterator for &'c Components {
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/event.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Event handling types.
use crate::system::{Local, Res, ResMut, SystemParam};
use crate::{self as bevy_ecs, system::Resource};
use crate::{self as bevy_ecs, resource::Resource};
use bevy_utils::tracing::trace;
use std::{
fmt::{self},
Expand Down
5 changes: 3 additions & 2 deletions crates/bevy_ecs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod event;
pub mod query;
#[cfg(feature = "bevy_reflect")]
pub mod reflect;
pub mod resource;
pub mod schedule;
pub mod storage;
pub mod system;
Expand Down Expand Up @@ -997,7 +998,7 @@ mod tests {

world.insert_resource(123);
let resource_id = world
.components()
.resources()
.get_resource_id(TypeId::of::<i32>())
.unwrap();
let archetype_component_id = world
Expand Down Expand Up @@ -1062,7 +1063,7 @@ mod tests {
);

let current_resource_id = world
.components()
.resources()
.get_resource_id(TypeId::of::<i32>())
.unwrap();
assert_eq!(
Expand Down
110 changes: 110 additions & 0 deletions crates/bevy_ecs/src/resource.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//! Types for declaring and storing [`Resource`]s.
use crate::component::{ComponentDescriptor, ComponentId, ComponentInfo, StorageType};
use std::any::{Any, TypeId};
use thiserror::Error;

pub trait Resource: Send + Sync + 'static {}
impl<T> Resource for T where T: Send + Sync + 'static {}

#[derive(Debug, Default)]
pub struct Resources {
resources: Vec<ComponentInfo>,
resource_indices: std::collections::HashMap<TypeId, usize, fxhash::FxBuildHasher>,
}

#[derive(Debug, Error)]
pub enum ResourceError {
#[error("A resource of type {name:?} ({type_id:?}) already exists")]
ResourceAlreadyExists {
type_id: TypeId,
name: String,
existing_id: ComponentId,
},
}

impl Resources {
#[inline]
pub fn len(&self) -> usize {
self.resources.len()
}

#[inline]
pub fn is_empty(&self) -> bool {
self.resources.len() == 0
}

#[inline]
pub fn get_info(&self, id: ComponentId) -> Option<&ComponentInfo> {
self.resources.get(id.index())
}

#[inline]
pub fn get_resource_id(&self, type_id: TypeId) -> Option<ComponentId> {
self.resource_indices
.get(&type_id)
.map(|index| ComponentId::new(*index))
}

#[inline]
pub fn init_resource<T: Resource>(&mut self) -> ComponentId {
// SAFE: The [`ComponentDescriptor`] matches the [`TypeId`]
unsafe {
self.get_or_insert_resource_with(TypeId::of::<T>(), || {
ComponentDescriptor::new_resource::<T>(StorageType::default())
})
}
}

#[inline]
pub fn init_non_send<T: Any>(&mut self) -> ComponentId {
// SAFE: The [`ComponentDescriptor`] matches the [`TypeId`]
unsafe {
self.get_or_insert_resource_with(TypeId::of::<T>(), || {
ComponentDescriptor::new_non_send::<T>(StorageType::default())
})
}
}

/// # Safety
///
/// The [`ComponentDescriptor`] must match the [`TypeId`]
#[inline]
unsafe fn get_or_insert_resource_with(
&mut self,
type_id: TypeId,
func: impl FnOnce() -> ComponentDescriptor,
) -> ComponentId {
let resources = &mut self.resources;
let index = self.resource_indices.entry(type_id).or_insert_with(|| {
let descriptor = func();
let index = resources.len();
resources.push(ComponentInfo::new(ComponentId::new(index), descriptor));
index
});

ComponentId::new(*index)
}

/// # Safety
///
/// `id` must be a valid [ComponentId]
#[inline]
pub unsafe fn get_info_unchecked(&self, id: ComponentId) -> &ComponentInfo {
debug_assert!(id.index() < self.resources.len());
self.resources.get_unchecked(id.index())
}
}

impl<'c> IntoIterator for &'c Resources {
type Item = &'c ComponentInfo;

type IntoIter = std::slice::Iter<'c, ComponentInfo>;

fn into_iter(self) -> Self::IntoIter {
self.resources.iter()
}
}

#[cfg(test)]
mod tests {}
3 changes: 1 addition & 2 deletions crates/bevy_ecs/src/system/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ use crate::{
bundle::Bundle,
component::Component,
entity::{Entities, Entity},
resource::Resource,
world::World,
};
use bevy_utils::tracing::{error, warn};
pub use command_queue::CommandQueue;
use std::marker::PhantomData;

use super::Resource;

/// A [`World`] mutation.
pub trait Command: Send + Sync + 'static {
fn write(self, world: &mut World);
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/system/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ mod tests {

let conflicts = x.component_access().get_conflicts(y.component_access());
let b_id = world
.components()
.resources()
.get_resource_id(TypeId::of::<B>())
.unwrap();
let d_id = world.components().get_id(TypeId::of::<D>()).unwrap();
Expand Down
4 changes: 1 addition & 3 deletions crates/bevy_ecs/src/system/system_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
query::{
FilterFetch, FilteredAccess, FilteredAccessSet, QueryState, ReadOnlyFetch, WorldQuery,
},
resource::{Resource, Resources},
system::{CommandQueue, Commands, Query, SystemMeta},
world::{FromWorld, World},
};
Expand Down Expand Up @@ -200,9 +201,6 @@ pub struct QuerySetState<T>(T);

impl_query_set!();

pub trait Resource: Send + Sync + 'static {}
impl<T> Resource for T where T: Send + Sync + 'static {}

/// Shared borrow of a resource.
///
/// See the [`World`] documentation to see the usage of a resource.
Expand Down
Loading

0 comments on commit 2200887

Please sign in to comment.