Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
114 commits
Select commit Hold shift + click to select a range
042337f
add back all changes
Trashtalk217 Jul 10, 2025
47c20a5
Merge branch 'main' of https://github.com/bevyengine/bevy into resour…
Trashtalk217 Jul 10, 2025
64eac9a
cargo fmt
Trashtalk217 Jul 10, 2025
956c1a6
cargo clippy
Trashtalk217 Jul 10, 2025
073df4b
add entities with resources, auto disabled IsResource
Trashtalk217 Jul 12, 2025
6c8281d
fixed and tests
Trashtalk217 Jul 12, 2025
f9dc9f1
fixed more tests
Trashtalk217 Jul 12, 2025
07723ac
fixed moore tests
Trashtalk217 Jul 12, 2025
1ba7af2
fix ci
Trashtalk217 Jul 12, 2025
b89c042
fix mooore tests (benches)
Trashtalk217 Jul 12, 2025
9b33933
fix docs
Trashtalk217 Jul 12, 2025
c7b4f1d
add migration guide
Trashtalk217 Jul 12, 2025
96aef45
fixed spelling errors to prove I'm not AI
Trashtalk217 Jul 12, 2025
e3ccd1b
Merge branch 'main' of https://github.com/bevyengine/bevy into resour…
Trashtalk217 Jul 12, 2025
5758134
addressed comments
Trashtalk217 Jul 13, 2025
9824c3a
testing robustness
Trashtalk217 Jul 14, 2025
9acf43f
Merge branch 'main' of https://github.com/bevyengine/bevy into resour…
Trashtalk217 Jul 14, 2025
da1d203
merge upstream
Trashtalk217 Jul 23, 2025
4d4e914
cleanup
Trashtalk217 Jul 23, 2025
78a0672
fix more stuff
Trashtalk217 Jul 23, 2025
4a2416d
update migration guides
Trashtalk217 Jul 24, 2025
3942c56
spelling
Trashtalk217 Jul 24, 2025
511e0b9
update resource macros to implement Component
Trashtalk217 Jul 24, 2025
d4c98eb
fix tests
Trashtalk217 Jul 24, 2025
724a4c4
merge
Trashtalk217 Aug 22, 2025
f442ff6
fix imports
Trashtalk217 Aug 22, 2025
acb539e
second attempt at fixing a test
Trashtalk217 Aug 22, 2025
a0d76c3
merge
Trashtalk217 Aug 30, 2025
c99df9c
Merge branch 'resource_entity_lookup' of github.com:trashtalk217/bevy…
Trashtalk217 Aug 30, 2025
12383a3
Merge branch 'main' of https://github.com/bevyengine/bevy into resour…
Trashtalk217 Sep 2, 2025
34570e8
Merge branch 'resource_entity_lookup' into resource-as-components
Trashtalk217 Sep 2, 2025
f43905d
removed send resources from Storages
Trashtalk217 Sep 8, 2025
36e8191
fixed more tests
Trashtalk217 Sep 8, 2025
d1b9b56
Merge branch 'main' of https://github.com/bevyengine/bevy into resour…
Trashtalk217 Sep 8, 2025
bfb2829
Merge branch 'resource_entity_lookup' into resource-as-components
Trashtalk217 Sep 8, 2025
011b068
cleanup
Trashtalk217 Sep 8, 2025
a12ec78
partly fixed bevy_scene
Trashtalk217 Sep 12, 2025
2261f8b
Merge branch 'main' of https://github.com/bevyengine/bevy into resour…
Trashtalk217 Sep 14, 2025
7f224be
address comments
Trashtalk217 Sep 14, 2025
4b0c77b
Merge branch 'resource_entity_lookup' into resource-as-components
Trashtalk217 Sep 14, 2025
6fdf25e
fixed try_resource_scope in part
Trashtalk217 Sep 14, 2025
2b1a5b5
fixed require() statement for AmbientLight
Trashtalk217 Sep 17, 2025
e8c67cc
change location of resource_entities
Trashtalk217 Sep 18, 2025
a01dc7d
changed scene serialization
Trashtalk217 Sep 18, 2025
9aecdf3
removed ResourceEntity, redid bevy_scene, require ReflectComponent for
Trashtalk217 Sep 22, 2025
3ddf8bf
fixed final tests
Trashtalk217 Sep 23, 2025
f0e973a
cargo clippy fixes
Trashtalk217 Sep 23, 2025
02c2b5f
Merge branch 'main' of https://github.com/bevyengine/bevy into resour…
Trashtalk217 Sep 23, 2025
8c1c818
removed dead code
Trashtalk217 Sep 23, 2025
1383efd
typo
Trashtalk217 Sep 23, 2025
2f9990a
more clippy
Trashtalk217 Sep 23, 2025
678da53
fixed get_resources_mut and unsoundness Res and ResMut
Trashtalk217 Sep 25, 2025
67810f4
updated docs
Trashtalk217 Sep 25, 2025
af03cec
improve docs and name
Trashtalk217 Sep 25, 2025
25b49d0
cargo clippy
Trashtalk217 Sep 25, 2025
1117cfa
typos
Trashtalk217 Sep 25, 2025
e3b12c2
fixed bevy_render bug
Trashtalk217 Sep 25, 2025
33bd43d
fixed bevy_remove
Trashtalk217 Sep 25, 2025
18c7664
Merge branch 'main' of https://github.com/bevyengine/bevy into resour…
Trashtalk217 Sep 25, 2025
c75da2c
added ReflectComponent to debug_overlay
Trashtalk217 Sep 25, 2025
0e4d5c2
fixed docs
Trashtalk217 Sep 25, 2025
0eef31b
addressed comments
Trashtalk217 Sep 26, 2025
e68d5c2
fixed a bug with try_resource_scope
Trashtalk217 Sep 27, 2025
44c526b
typos
Trashtalk217 Sep 27, 2025
fb01522
clippy
Trashtalk217 Sep 27, 2025
d70a178
Merge branch 'main' of https://github.com/bevyengine/bevy into resour…
Trashtalk217 Sep 27, 2025
8afc908
Merge branch 'main' of https://github.com/bevyengine/bevy into resour…
Trashtalk217 Oct 17, 2025
44927a5
remove all unnecessary resourceComponent
Trashtalk217 Oct 24, 2025
e953fa1
Merge branch 'main' of https://github.com/bevyengine/bevy into resour…
Trashtalk217 Oct 26, 2025
4cbdaa5
remove entity_ref
Trashtalk217 Oct 26, 2025
2ec2182
further cleanup
Trashtalk217 Oct 26, 2025
ea36fec
more cleanup
Trashtalk217 Oct 26, 2025
1203662
more more cleanup
Trashtalk217 Oct 26, 2025
e751f15
removed a test and made IsResource automatically disabled (temporary)
Trashtalk217 Oct 26, 2025
2fa538e
rewrite resource component derive
Trashtalk217 Oct 26, 2025
740752d
change the hooks to be public under the Resource trait
Trashtalk217 Oct 26, 2025
737f04c
fixed compile problems, goto v2 implementation with hooks
Trashtalk217 Oct 26, 2025
8a1727b
deprecate dyanamic (send) resources
Trashtalk217 Oct 27, 2025
ff0e195
made ReflectResource deref to ReflectComponent
Trashtalk217 Oct 27, 2025
c9f7ec5
made resource entity stable, fixed bevy_scene
Trashtalk217 Oct 27, 2025
86962a8
fixed bevy_remote, added logging to hooks
Trashtalk217 Oct 27, 2025
3989f2e
remove pointless printing
Trashtalk217 Oct 27, 2025
d7d647e
Merge branch 'main' of https://github.com/bevyengine/bevy into resour…
Trashtalk217 Oct 28, 2025
6ceed0d
fixed ci
Trashtalk217 Oct 28, 2025
b2b2248
fix ci some more
Trashtalk217 Oct 28, 2025
5028619
updated example asset
Trashtalk217 Oct 28, 2025
039cd0b
fix ci some more
Trashtalk217 Oct 28, 2025
1014aad
fix ci some more
Trashtalk217 Oct 28, 2025
9fd6129
Merge branch 'main' of https://github.com/bevyengine/bevy into resour…
Trashtalk217 Oct 29, 2025
485c03a
revert to previous Res/ResMut implementation
Trashtalk217 Oct 30, 2025
8c67aa3
change doc comments
Trashtalk217 Oct 30, 2025
fe921d2
revert a weird bevy_render thing
Trashtalk217 Oct 30, 2025
75069d8
revert bevy_scene changes
Trashtalk217 Oct 30, 2025
da3f903
space
Trashtalk217 Oct 30, 2025
2453314
remove dead code
Trashtalk217 Oct 30, 2025
c9c0f95
cargo fmt
Trashtalk217 Oct 30, 2025
a4234fb
documentation
Trashtalk217 Oct 30, 2025
779b668
markdown fix
Trashtalk217 Oct 30, 2025
c919a69
fixed access bug
Trashtalk217 Nov 2, 2025
5438039
make is_resource not a dfq
Trashtalk217 Nov 2, 2025
4be1ccf
fix a broad query for animation conflicting with a resource
Trashtalk217 Nov 2, 2025
aa4d563
review comments
Trashtalk217 Nov 3, 2025
28ca0ac
fix
Trashtalk217 Nov 3, 2025
411a681
address review comments
Trashtalk217 Nov 7, 2025
a570cc3
forgot to make a change
Trashtalk217 Nov 7, 2025
e72f38e
Merge branch 'main' of https://github.com/bevyengine/bevy into resour…
Trashtalk217 Nov 29, 2025
a5e9612
spelling
Trashtalk217 Nov 29, 2025
73a9293
fixed tests
Trashtalk217 Nov 29, 2025
a3bef34
oops forgot to save
Trashtalk217 Nov 29, 2025
57ca7d6
rename non-send resources to non-send data
Trashtalk217 Dec 4, 2025
3e36aba
misc changes based on review
Trashtalk217 Dec 4, 2025
31530f6
docs
Trashtalk217 Dec 4, 2025
89c5622
Merge branch 'main' of https://github.com/bevyengine/bevy into resour…
Trashtalk217 Dec 4, 2025
f3153da
reflect dependency
Trashtalk217 Dec 4, 2025
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
7 changes: 5 additions & 2 deletions crates/bevy_animation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use crate::{

use bevy_app::{AnimationSystems, App, Plugin, PostUpdate};
use bevy_asset::{Asset, AssetApp, AssetEventSystems, Assets};
use bevy_ecs::{prelude::*, world::EntityMutExcept};
use bevy_ecs::{prelude::*, resource::IsResource, world::EntityMutExcept};
use bevy_math::FloatOrd;
use bevy_platform::{collections::HashMap, hash::NoOpHash};
use bevy_reflect::{prelude::ReflectDefault, Reflect, TypePath};
Expand Down Expand Up @@ -1032,7 +1032,10 @@ pub fn animate_targets(
graphs: Res<Assets<AnimationGraph>>,
threaded_animation_graphs: Res<ThreadedAnimationGraphs>,
players: Query<(&AnimationPlayer, &AnimationGraphHandle)>,
mut targets: Query<(Entity, &AnimationTargetId, &AnimatedBy, AnimationEntityMut)>,
mut targets: Query<
(Entity, &AnimationTargetId, &AnimatedBy, AnimationEntityMut),
Without<IsResource>,
>,
animation_evaluation_state: Local<ThreadLocal<RefCell<AnimationEvaluationState>>>,
) {
// Evaluate all animation targets in parallel.
Expand Down
18 changes: 9 additions & 9 deletions crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,10 +471,10 @@ impl App {
self
}

/// Inserts the [`!Send`](Send) resource into the app, overwriting any existing resource
/// Inserts the [`!Send`](Send) data into the app, overwriting any existing data
/// of the same type.
///
/// There is also an [`init_non_send_resource`](Self::init_non_send_resource) for
/// There is also an [`init_non_send`](Self::init_non_send) for
/// resources that implement [`Default`]
///
/// # Examples
Expand All @@ -488,20 +488,20 @@ impl App {
/// }
///
/// App::new()
/// .insert_non_send_resource(MyCounter { counter: 0 });
/// .insert_non_send(MyCounter { counter: 0 });
/// ```
pub fn insert_non_send_resource<R: 'static>(&mut self, resource: R) -> &mut Self {
self.world_mut().insert_non_send_resource(resource);
pub fn insert_non_send<R: 'static>(&mut self, resource: R) -> &mut Self {
self.world_mut().insert_non_send(resource);
self
}

/// Inserts the [`!Send`](Send) resource into the app if there is no existing instance of `R`.
/// Inserts the [`!Send`](Send) data into the app if there is no existing instance of `R`.
///
/// `R` must implement [`FromWorld`].
/// If `R` implements [`Default`], [`FromWorld`] will be automatically implemented and
/// initialize the [`Resource`] with [`Default::default`].
pub fn init_non_send_resource<R: 'static + FromWorld>(&mut self) -> &mut Self {
self.world_mut().init_non_send_resource::<R>();
pub fn init_non_send<R: 'static + FromWorld>(&mut self) -> &mut Self {
self.world_mut().init_non_send::<R>();
self
}

Expand Down Expand Up @@ -1961,7 +1961,7 @@ mod tests {
}

App::new()
.init_non_send_resource::<NonSendTestResource>()
.init_non_send::<NonSendTestResource>()
.init_resource::<TestResource>();
}

Expand Down
77 changes: 75 additions & 2 deletions crates/bevy_ecs/macros/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,91 @@ pub fn derive_resource(input: TokenStream) -> TokenStream {
return err.into_compile_error().into();
}

// implement the Component trait
let map_entities = map_entities(
&ast.data,
&bevy_ecs_path,
Ident::new("this", Span::call_site()),
false,
false,
None
).map(|map_entities_impl| quote! {
fn map_entities<M: #bevy_ecs_path::entity::EntityMapper>(this: &mut Self, mapper: &mut M) {
use #bevy_ecs_path::entity::MapEntities;
#map_entities_impl
}
});

let storage = storage_path(&bevy_ecs_path, StorageTy::Table);

let on_add_path = Some(quote!(#bevy_ecs_path::resource::resource_on_add_hook));
let on_remove_path = None;
let on_insert_path = None;
let on_replace_path = None;
let on_despawn_path = Some(quote!(#bevy_ecs_path::resource::resource_on_despawn_hook));

let on_add = hook_register_function_call(&bevy_ecs_path, quote! {on_add}, on_add_path);
let on_remove = hook_register_function_call(&bevy_ecs_path, quote! {on_remove}, on_remove_path);
let on_insert = hook_register_function_call(&bevy_ecs_path, quote! {on_insert}, on_insert_path);
let on_replace =
hook_register_function_call(&bevy_ecs_path, quote! {on_replace}, on_replace_path);
let on_despawn =
hook_register_function_call(&bevy_ecs_path, quote! {on_despawn}, on_despawn_path);

ast.generics
.make_where_clause()
.predicates
.push(parse_quote! { Self: Send + Sync + 'static });

let mut register_required = Vec::with_capacity(1);
register_required.push(quote! {
required_components.register_required::<#bevy_ecs_path::resource::IsResource>(<#bevy_ecs_path::resource::IsResource as Default>::default);
});

let struct_name = &ast.ident;
let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl();

TokenStream::from(quote! {
// This puts `register_required` before `register_recursive_requires` to ensure that the constructors of _all_ top
// level components are initialized first, giving them precedence over recursively defined constructors for the same component type
let component_derive_token_stream = TokenStream::from(quote! {
impl #impl_generics #bevy_ecs_path::component::Component for #struct_name #type_generics #where_clause {
const STORAGE_TYPE: #bevy_ecs_path::component::StorageType = #storage;
type Mutability = #bevy_ecs_path::component::Mutable;
fn register_required_components(
_requiree: #bevy_ecs_path::component::ComponentId,
required_components: &mut #bevy_ecs_path::component::RequiredComponentsRegistrator,
) {
#(#register_required)*
}

#on_add
#on_insert
#on_replace
#on_remove
#on_despawn

fn clone_behavior() -> #bevy_ecs_path::component::ComponentCloneBehavior {
#bevy_ecs_path::component::ComponentCloneBehavior::Default
}

#map_entities

fn relationship_accessor() -> Option<#bevy_ecs_path::relationship::ComponentRelationshipAccessor<Self>> {
None
}
}
});

// implement the Resource trait
let resource_impl_token_stream = TokenStream::from(quote! {
impl #impl_generics #bevy_ecs_path::resource::Resource for #struct_name #type_generics #where_clause {
}
})
});

resource_impl_token_stream
.into_iter()
.chain(component_derive_token_stream)
.collect()
}

/// Component derive syntax is documented on both the macro and the trait.
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ pub fn derive_resource(input: TokenStream) -> TokenStream {
/// #[component(hook_name = function)]
/// struct MyComponent;
/// ```
/// where `hook_name` is `on_add`, `on_insert`, `on_replace` or `on_remove`;
/// where `hook_name` is `on_add`, `on_insert`, `on_replace` or `on_remove`;
/// `function` can be either a path, e.g. `some_function::<Self>`,
/// or a function call that returns a function that can be turned into
/// a `ComponentHook`, e.g. `get_closure("Hi!")`.
Expand Down
14 changes: 14 additions & 0 deletions crates/bevy_ecs/src/component/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//! Constant components included in every world.

/// `usize` for the [`Add`] component used in lifecycle observers.
pub const ADD: usize = 0;
/// `usize` for the [`Insert`] component used in lifecycle observers.
pub const INSERT: usize = 1;
/// `usize` for the [`Replace`] component used in lifecycle observers.
pub const REPLACE: usize = 2;
/// `usize` for the [`Remove`] component used in lifecycle observers.
pub const REMOVE: usize = 3;
/// `usize` for [`Despawn`] component used in lifecycle observers.
pub const DESPAWN: usize = 4;
/// `usize` of the [`IsResource`] component used to mark entities with resources.
pub const IS_RESOURCE: usize = 5;
31 changes: 8 additions & 23 deletions crates/bevy_ecs/src/component/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,19 +302,7 @@ impl ComponentDescriptor {
///
/// The [`StorageType`] for resources is always [`StorageType::Table`].
pub fn new_resource<T: Resource>() -> Self {
Self {
name: DebugName::type_name::<T>(),
// PERF: `SparseStorage` may actually be a more
// reasonable choice as `storage_type` for resources.
storage_type: StorageType::Table,
is_send_and_sync: true,
type_id: Some(TypeId::of::<T>()),
layout: Layout::new::<T>(),
drop: needs_drop::<T>().then_some(Self::drop_ptr::<T> as _),
mutable: true,
clone_behavior: ComponentCloneBehavior::Default,
relationship_accessor: None,
}
Self::new::<T>()
}

pub(super) fn new_non_send<T: Any>(storage_type: StorageType) -> Self {
Expand Down Expand Up @@ -362,7 +350,6 @@ impl ComponentDescriptor {
pub struct Components {
pub(super) components: Vec<Option<ComponentInfo>>,
pub(super) indices: TypeIdMap<ComponentId>,
pub(super) resource_indices: TypeIdMap<ComponentId>,
// This is kept internal and local to verify that no deadlocks can occur.
pub(super) queued: bevy_platform::sync::RwLock<QueuedComponents>,
}
Expand Down Expand Up @@ -407,7 +394,7 @@ impl Components {
#[inline]
pub fn num_queued(&self) -> usize {
let queued = self.queued.read().unwrap_or_else(PoisonError::into_inner);
queued.components.len() + queued.dynamic_registrations.len() + queued.resources.len()
queued.components.len() + queued.dynamic_registrations.len()
}

/// Returns `true` if there are any components registered with this instance. Otherwise, this returns `false`.
Expand All @@ -423,7 +410,7 @@ impl Components {
.queued
.get_mut()
.unwrap_or_else(PoisonError::into_inner);
queued.components.len() + queued.dynamic_registrations.len() + queued.resources.len()
queued.components.len() + queued.dynamic_registrations.len()
}

/// A faster version of [`Self::any_queued`].
Expand Down Expand Up @@ -470,7 +457,6 @@ impl Components {
queued
.components
.values()
.chain(queued.resources.values())
.chain(queued.dynamic_registrations.iter())
.find(|queued| queued.id == id)
.map(|queued| Cow::Owned(queued.descriptor.clone()))
Expand All @@ -492,7 +478,6 @@ impl Components {
queued
.components
.values()
.chain(queued.resources.values())
.chain(queued.dynamic_registrations.iter())
.find(|queued| queued.id == id)
.map(|queued| queued.descriptor.name.clone())
Expand Down Expand Up @@ -602,7 +587,7 @@ impl Components {
/// Type-erased equivalent of [`Components::valid_resource_id()`].
#[inline]
pub fn get_valid_resource_id(&self, type_id: TypeId) -> Option<ComponentId> {
self.resource_indices.get(&type_id).copied()
self.indices.get(&type_id).copied()
}

/// Returns the [`ComponentId`] of the given [`Resource`] type `T` if it is fully registered.
Expand Down Expand Up @@ -680,11 +665,11 @@ impl Components {
/// Type-erased equivalent of [`Components::resource_id()`].
#[inline]
pub fn get_resource_id(&self, type_id: TypeId) -> Option<ComponentId> {
self.resource_indices.get(&type_id).copied().or_else(|| {
self.indices.get(&type_id).copied().or_else(|| {
self.queued
.read()
.unwrap_or_else(PoisonError::into_inner)
.resources
.components
.get(&type_id)
.map(|queued| queued.id)
})
Expand Down Expand Up @@ -728,7 +713,7 @@ impl Components {
/// The [`ComponentId`] must be unique.
/// The [`TypeId`] and [`ComponentId`] must not be registered or queued.
#[inline]
pub(super) unsafe fn register_resource_unchecked(
pub(super) unsafe fn register_non_send_unchecked(
&mut self,
type_id: TypeId,
component_id: ComponentId,
Expand All @@ -738,7 +723,7 @@ impl Components {
unsafe {
self.register_component_inner(component_id, descriptor);
}
let prev = self.resource_indices.insert(type_id, component_id);
let prev = self.indices.insert(type_id, component_id);
debug_assert!(prev.is_none());
}

Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_ecs/src/component/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! Types for declaring and storing [`Component`]s.

mod clone;
mod constants;
mod info;
mod register;
mod required;

pub use clone::*;
pub use constants::*;
pub use info::*;
pub use register::*;
pub use required::*;
Expand Down
Loading
Loading