Move Resource trait to its own file (#17469)

# Objective

`bevy_ecs`'s `system` module is something of a grab bag, and *very*
large. This is particularly true for the `system_param` module, which is
more than 2k lines long!

While it could be defensible to put `Res` and `ResMut` there (lol no
they're in change_detection.rs, obviously), it doesn't make any sense to
put the `Resource` trait there. This is confusing to navigate (and
painful to work on and review).

## Solution

- Create a root level `bevy_ecs/resource.rs` module to mirror
`bevy_ecs/component.rs`
- move the `Resource` trait to that module
- move the `Resource` derive macro to that module as well (Rust really
likes when you pun on the names of the derive macro and trait and put
them in the same path)
- fix all of the imports

## Notes to reviewers

- We could probably move more stuff into here, but I wanted to keep this
PR as small as possible given the absurd level of import changes.
- This PR is ground work for my upcoming attempts to store resource data
on components (resources-as-entities). Splitting this code out will make
the work and review a bit easier, and is the sort of overdue refactor
that's good to do as part of more meaningful work.

## Testing

cargo build works!

## Migration Guide

`bevy_ecs::system::Resource` has been moved to
`bevy_ecs::resource::Resource`.
This commit is contained in:
Alice Cecile 2025-01-21 14:47:08 -05:00 committed by GitHub
parent 85eceb022d
commit 44ad3bf62b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
110 changed files with 261 additions and 190 deletions

View File

@ -23,8 +23,8 @@ use bevy_app::Plugin;
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{
prelude::{Component, Event},
resource::Resource,
schedule::SystemSet,
system::Resource,
};
/// Wrapper struct for [`accesskit::ActionRequest`]. Required to allow it to be used as an `Event`.

View File

@ -14,7 +14,8 @@ use bevy_ecs::{
component::Component,
event::EventReader,
reflect::ReflectComponent,
system::{Res, ResMut, Resource},
resource::Resource,
system::{Res, ResMut},
};
use bevy_reflect::{prelude::ReflectDefault, Reflect, ReflectSerialize};
use bevy_utils::HashMap;

View File

@ -1423,8 +1423,9 @@ mod tests {
event::{Event, EventWriter, Events},
query::With,
removal_detection::RemovedComponents,
resource::Resource,
schedule::{IntoSystemConfigs, ScheduleLabel},
system::{Commands, Query, Resource},
system::{Commands, Query},
world::{FromWorld, World},
};

View File

@ -1,11 +1,12 @@
use crate::{App, Plugin};
use alloc::{vec, vec::Vec};
use bevy_ecs::{
resource::Resource,
schedule::{
ExecutorKind, InternedScheduleLabel, IntoSystemSetConfigs, Schedule, ScheduleLabel,
SystemSet,
},
system::{Local, Resource},
system::Local,
world::{Mut, World},
};

View File

@ -226,7 +226,7 @@ impl PluginGroup for PluginGroupBuilder {
/// Facilitates the creation and configuration of a [`PluginGroup`].
///
/// Provides a build ordering to ensure that [`Plugin`]s which produce/require a [`Resource`](bevy_ecs::system::Resource)
/// Provides a build ordering to ensure that [`Plugin`]s which produce/require a [`Resource`](bevy_ecs::resource::Resource)
/// are built before/after dependent/depending [`Plugin`]s. [`Plugin`]s inside the group
/// can be disabled, enabled or reordered.
pub struct PluginGroupBuilder {

View File

@ -298,7 +298,8 @@ mod tests {
use bevy_ecs::{
component::Component,
event::EventWriter,
system::{Commands, IntoSystem, Local, Query, Res, ResMut, Resource},
resource::Resource,
system::{Commands, IntoSystem, Local, Query, Res, ResMut},
};
use bevy_reflect::TypePath;

View File

@ -6,7 +6,8 @@ use crate::{
use alloc::{sync::Arc, vec::Vec};
use bevy_ecs::{
prelude::EventWriter,
system::{Res, ResMut, Resource, SystemChangeTick},
resource::Resource,
system::{Res, ResMut, SystemChangeTick},
};
use bevy_reflect::{Reflect, TypePath};
use bevy_utils::HashMap;

View File

@ -9,7 +9,7 @@ use crate::io::{
AssetSource, AssetSourceBuilders,
};
use alloc::boxed::Box;
use bevy_ecs::system::Resource;
use bevy_ecs::resource::Resource;
use std::path::{Path, PathBuf};
#[cfg(feature = "embedded_watcher")]

View File

@ -8,7 +8,7 @@ use alloc::{
sync::Arc,
};
use atomicow::CowArc;
use bevy_ecs::system::Resource;
use bevy_ecs::resource::Resource;
use bevy_utils::HashMap;
use core::{fmt::Display, hash::Hash, time::Duration};
use thiserror::Error;

View File

@ -521,7 +521,8 @@ impl AssetServer {
///
/// ```
/// use bevy_asset::{Assets, Handle, LoadedUntypedAsset};
/// use bevy_ecs::system::{Res, Resource};
/// use bevy_ecs::system::Res;
/// use bevy_ecs::resource::Resource;
///
/// #[derive(Resource)]
/// struct LoadingUntypedHandle(Handle<LoadedUntypedAsset>);

View File

@ -2,7 +2,8 @@ use super::{Bloom, BLOOM_SHADER_HANDLE, BLOOM_TEXTURE_FORMAT};
use crate::fullscreen_vertex_shader::fullscreen_shader_vertex_state;
use bevy_ecs::{
prelude::{Component, Entity},
system::{Commands, Query, Res, ResMut, Resource},
resource::Resource,
system::{Commands, Query, Res, ResMut},
world::{FromWorld, World},
};
use bevy_math::{Vec2, Vec4};

View File

@ -5,7 +5,8 @@ use super::{
use crate::fullscreen_vertex_shader::fullscreen_shader_vertex_state;
use bevy_ecs::{
prelude::{Component, Entity},
system::{Commands, Query, Res, ResMut, Resource},
resource::Resource,
system::{Commands, Query, Res, ResMut},
world::{FromWorld, World},
};
use bevy_render::{

View File

@ -22,8 +22,9 @@ use bevy_ecs::{
entity::Entity,
query::{QueryItem, With},
reflect::ReflectComponent,
resource::Resource,
schedule::IntoSystemConfigs as _,
system::{lifetimeless::Read, Commands, Query, Res, ResMut, Resource},
system::{lifetimeless::Read, Commands, Query, Res, ResMut},
world::{FromWorld, World},
};
use bevy_image::BevyDefault as _;

View File

@ -2,7 +2,8 @@ use bevy_ecs::{
component::Component,
entity::Entity,
query::With,
system::{Commands, Query, Res, ResMut, Resource},
resource::Resource,
system::{Commands, Query, Res, ResMut},
world::FromWorld,
};
use bevy_image::BevyDefault as _;

View File

@ -10,8 +10,9 @@ use bevy_ecs::{
entity::Entity,
query::{QueryItem, With},
reflect::ReflectComponent,
resource::Resource,
schedule::IntoSystemConfigs as _,
system::{lifetimeless::Read, Commands, Query, Res, ResMut, Resource},
system::{lifetimeless::Read, Commands, Query, Res, ResMut},
world::{FromWorld, World},
};
use bevy_image::{BevyDefault, Image};

View File

@ -3,8 +3,9 @@ use bevy_asset::{load_internal_asset, Handle};
use bevy_ecs::{
prelude::{Component, Entity},
query::{QueryItem, With},
resource::Resource,
schedule::IntoSystemConfigs,
system::{Commands, Query, Res, ResMut, Resource},
system::{Commands, Query, Res, ResMut},
};
use bevy_image::{BevyDefault, Image};
use bevy_math::{Mat4, Quat};

View File

@ -5,7 +5,8 @@ use bevy_ecs::{
component::Component,
entity::Entity,
query::{Has, With},
system::{Commands, Query, Res, ResMut, Resource},
resource::Resource,
system::{Commands, Query, Res, ResMut},
world::{FromWorld, World},
};
use bevy_render::{

View File

@ -45,8 +45,9 @@ use bevy_ecs::{
entity::Entity,
query::{QueryItem, With},
reflect::ReflectComponent,
resource::Resource,
schedule::IntoSystemConfigs as _,
system::{lifetimeless::Read, Commands, Query, Res, ResMut, Resource},
system::{lifetimeless::Read, Commands, Query, Res, ResMut},
world::{FromWorld, World},
};
use bevy_image::{BevyDefault, Image};

View File

@ -10,8 +10,9 @@ use bevy_diagnostic::FrameCount;
use bevy_ecs::{
prelude::{require, Component, Entity, ReflectComponent},
query::{QueryItem, With},
resource::Resource,
schedule::IntoSystemConfigs,
system::{Commands, Query, Res, ResMut, Resource},
system::{Commands, Query, Res, ResMut},
world::{FromWorld, World},
};
use bevy_image::BevyDefault as _;

View File

@ -9,8 +9,9 @@ use bevy_ecs::{
component::Component,
entity::Entity,
query::With,
resource::Resource,
schedule::{common_conditions::resource_changed, IntoSystemConfigs},
system::{Commands, Query, Res, Resource},
system::{Commands, Query, Res},
};
use bevy_render::view::Visibility;
use bevy_text::{Font, TextColor, TextFont, TextSpan};

View File

@ -5,7 +5,8 @@ use core::{
};
use bevy_app::{App, SubApp};
use bevy_ecs::system::{Deferred, Res, Resource, SystemBuffer, SystemParam};
use bevy_ecs::resource::Resource;
use bevy_ecs::system::{Deferred, Res, SystemBuffer, SystemParam};
use bevy_platform_support::time::Instant;
use bevy_utils::{HashMap, PassHash};
use const_fnv1a_hash::fnv1a_hash_str_64;

View File

@ -1,6 +1,6 @@
use crate::DiagnosticPath;
use bevy_app::prelude::*;
use bevy_ecs::system::Resource;
use bevy_ecs::resource::Resource;
/// Adds a System Information Diagnostic, specifically `cpu_usage` (in %) and `mem_usage` (in %)
///
@ -64,7 +64,7 @@ pub mod internal {
use std::{sync::Mutex, time::Instant};
use bevy_app::{App, First, Startup, Update};
use bevy_ecs::system::Resource;
use bevy_ecs::resource::Resource;
use bevy_tasks::{available_parallelism, block_on, poll_once, AsyncComputeTaskPool, Task};
use sysinfo::{CpuRefreshKind, MemoryRefreshKind, RefreshKind, System};
use tracing::info;

View File

@ -46,7 +46,7 @@ pub fn derive_resource(input: TokenStream) -> TokenStream {
let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl();
TokenStream::from(quote! {
impl #impl_generics #bevy_ecs_path::system::Resource for #struct_name #type_generics #where_clause {
impl #impl_generics #bevy_ecs_path::resource::Resource for #struct_name #type_generics #where_clause {
}
})
}

View File

@ -766,7 +766,7 @@ struct ArchetypeComponents {
///
/// [`Component`]: crate::component::Component
/// [`World`]: crate::world::World
/// [`Resource`]: crate::system::Resource
/// [`Resource`]: crate::resource::Resource
/// [many-to-many relationship]: https://en.wikipedia.org/wiki/Many-to-many_(data_model)
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct ArchetypeComponentId(usize);

View File

@ -3,7 +3,7 @@
use crate::{
component::{Tick, TickCells},
ptr::PtrMut,
system::Resource,
resource::Resource,
};
use alloc::borrow::ToOwned;
use bevy_ptr::{Ptr, UnsafeCellDeref};

View File

@ -7,8 +7,9 @@ use crate::{
change_detection::MAX_CHANGE_AGE,
entity::{ComponentCloneCtx, Entity},
query::DebugCheckedUnwrap,
resource::Resource,
storage::{SparseSetIndex, SparseSets, Storages, Table, TableRow},
system::{Local, Resource, SystemParam},
system::{Local, SystemParam},
world::{DeferredWorld, FromWorld, World},
};
#[cfg(feature = "bevy_reflect")]

View File

@ -2,7 +2,7 @@ use crate as bevy_ecs;
use alloc::vec::Vec;
use bevy_ecs::{
event::{Event, EventCursor, EventId, EventInstance},
system::Resource,
resource::Resource,
};
#[cfg(feature = "track_location")]
use core::panic::Location;

View File

@ -4,7 +4,7 @@ use bevy_ecs::{
change_detection::{DetectChangesMut, MutUntyped},
component::{ComponentId, Tick},
event::{Event, Events},
system::Resource,
resource::Resource,
world::World,
};

View File

@ -52,6 +52,7 @@ pub mod query;
pub mod reflect;
pub mod relationship;
pub mod removal_detection;
pub mod resource;
pub mod result;
pub mod schedule;
pub mod storage;
@ -81,6 +82,7 @@ pub mod prelude {
observer::{CloneEntityWithObserversExt, Observer, Trigger},
query::{Added, AnyOf, Changed, Has, Or, QueryBuilder, QueryState, With, Without},
removal_detection::RemovedComponents,
resource::Resource,
result::{Error, Result},
schedule::{
apply_deferred, common_conditions::*, ApplyDeferred, Condition, IntoSystemConfigs,
@ -89,7 +91,7 @@ pub mod prelude {
system::{
Command, Commands, Deferred, EntityCommand, EntityCommands, In, InMut, InRef,
IntoSystem, Local, NonSend, NonSendMut, ParamSet, Populated, Query, ReadOnlySystem,
Res, ResMut, Resource, Single, System, SystemIn, SystemInput, SystemParamBuilder,
Res, ResMut, Single, System, SystemIn, SystemInput, SystemParamBuilder,
SystemParamFunction, WithParamWarnPolicy,
},
world::{
@ -134,7 +136,7 @@ mod tests {
entity::Entity,
prelude::Or,
query::{Added, Changed, FilteredAccess, QueryFilter, With, Without},
system::Resource,
resource::Resource,
world::{EntityMut, EntityRef, Mut, World},
};
use alloc::{
@ -1223,7 +1225,7 @@ mod tests {
#[test]
fn resource() {
use crate::system::Resource;
use crate::resource::Resource;
#[derive(Resource, PartialEq, Debug)]
struct Num(i32);

View File

@ -116,7 +116,8 @@ mod tests {
entity::EntityCloneBuilder,
event::Event,
observer::{CloneEntityWithObserversExt, Trigger},
system::{ResMut, Resource},
resource::Resource,
system::ResMut,
world::World,
};

View File

@ -2,7 +2,8 @@ use crate::{
entity::Entity,
prelude::Mut,
reflect::{AppTypeRegistry, ReflectBundle, ReflectComponent},
system::{EntityCommands, Resource},
resource::Resource,
system::EntityCommands,
world::{EntityWorldMut, World},
};
use alloc::{borrow::Cow, boxed::Box};

View File

@ -6,7 +6,7 @@ use core::{
};
use crate as bevy_ecs;
use crate::{system::Resource, world::World};
use crate::{resource::Resource, world::World};
use bevy_reflect::{
std_traits::ReflectDefault, PartialReflect, Reflect, ReflectFromReflect, TypePath,
TypeRegistry, TypeRegistryArc,

View File

@ -7,7 +7,7 @@
use crate::{
change_detection::Mut,
component::ComponentId,
system::Resource,
resource::Resource,
world::{unsafe_world_cell::UnsafeWorldCell, World},
};
use bevy_reflect::{FromReflect, FromType, PartialReflect, Reflect, TypePath, TypeRegistry};

View File

@ -0,0 +1,75 @@
//! Resources are unique, singleton-like data types that can be accessed from systems and stored in the [`World`](crate::world::World).
// The derive macro for the `Resource` trait
pub use bevy_ecs_macros::Resource;
/// A type that can be inserted into a [`World`] as a singleton.
///
/// You can access resource data in systems using the [`Res`] and [`ResMut`] system parameters
///
/// Only one resource of each type can be stored in a [`World`] at any given time.
///
/// # Examples
///
/// ```
/// # let mut world = World::default();
/// # let mut schedule = Schedule::default();
/// # use bevy_ecs::prelude::*;
/// #[derive(Resource)]
/// struct MyResource { value: u32 }
///
/// world.insert_resource(MyResource { value: 42 });
///
/// fn read_resource_system(resource: Res<MyResource>) {
/// assert_eq!(resource.value, 42);
/// }
///
/// fn write_resource_system(mut resource: ResMut<MyResource>) {
/// assert_eq!(resource.value, 42);
/// resource.value = 0;
/// assert_eq!(resource.value, 0);
/// }
/// # schedule.add_systems((read_resource_system, write_resource_system).chain());
/// # schedule.run(&mut world);
/// ```
///
/// # `!Sync` Resources
/// A `!Sync` type cannot implement `Resource`. However, it is possible to wrap a `Send` but not `Sync`
/// type in [`SyncCell`] or the currently unstable [`Exclusive`] to make it `Sync`. This forces only
/// having mutable access (`&mut T` only, never `&T`), but makes it safe to reference across multiple
/// threads.
///
/// This will fail to compile since `RefCell` is `!Sync`.
/// ```compile_fail
/// # use std::cell::RefCell;
/// # use bevy_ecs::resource::Resource;
///
/// #[derive(Resource)]
/// struct NotSync {
/// counter: RefCell<usize>,
/// }
/// ```
///
/// This will compile since the `RefCell` is wrapped with `SyncCell`.
/// ```
/// # use std::cell::RefCell;
/// # use bevy_ecs::resource::Resource;
/// use bevy_utils::synccell::SyncCell;
///
/// #[derive(Resource)]
/// struct ActuallySync {
/// counter: SyncCell<RefCell<usize>>,
/// }
/// ```
///
/// [`Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html
/// [`World`]: crate::world::World
/// [`Res`]: crate::system::Res
/// [`ResMut`]: crate::system::ResMut
/// [`SyncCell`]: bevy_utils::synccell::SyncCell
#[diagnostic::on_unimplemented(
message = "`{Self}` is not a `Resource`",
label = "invalid `Resource`",
note = "consider annotating `{Self}` with `#[derive(Resource)]`"
)]
pub trait Resource: Send + Sync + 'static {}

View File

@ -400,7 +400,8 @@ pub mod common_conditions {
prelude::{Component, Query, With},
query::QueryFilter,
removal_detection::RemovedComponents,
system::{In, IntoSystem, Local, Res, Resource, System, SystemInput},
resource::Resource,
system::{In, IntoSystem, Local, Res, System, SystemInput},
};
use alloc::format;

View File

@ -22,8 +22,9 @@ mod tests {
pub use crate as bevy_ecs;
pub use crate::{
prelude::World,
resource::Resource,
schedule::{Schedule, SystemSet},
system::{Res, ResMut, Resource},
system::{Res, ResMut},
};
#[derive(SystemSet, Clone, Debug, PartialEq, Eq, Hash)]

View File

@ -23,9 +23,10 @@ use crate::{
self as bevy_ecs,
component::{ComponentId, Components, Tick},
prelude::Component,
resource::Resource,
result::Result,
schedule::*,
system::{IntoSystem, Resource, ScheduleSystem},
system::{IntoSystem, ScheduleSystem},
world::World,
};

View File

@ -217,8 +217,8 @@ where
#[cfg(test)]
mod tests {
use crate::{
resource::Resource,
schedule::{tests::ResMut, Schedule},
system::Resource,
};
use super::*;

View File

@ -1,6 +1,7 @@
use crate::{
resource::Resource,
schedule::{InternedScheduleLabel, NodeId, Schedule, ScheduleLabel},
system::{IntoSystem, ResMut, Resource},
system::{IntoSystem, ResMut},
};
use alloc::vec::Vec;
use bevy_utils::{HashMap, TypeIdMap};

View File

@ -308,7 +308,7 @@ impl<const SEND: bool> ResourceData<SEND> {
/// The backing store for all [`Resource`]s stored in the [`World`].
///
/// [`Resource`]: crate::system::Resource
/// [`Resource`]: crate::resource::Resource
/// [`World`]: crate::world::World
#[derive(Default)]
pub struct Resources<const SEND: bool> {

View File

@ -5,6 +5,7 @@ use variadics_please::all_tuples;
use crate::{
prelude::QueryBuilder,
query::{QueryData, QueryFilter, QueryState},
resource::Resource,
system::{
DynSystemParam, DynSystemParamState, Local, ParamSet, Query, SystemMeta, SystemParam,
},
@ -15,7 +16,7 @@ use crate::{
};
use core::fmt::Debug;
use super::{init_query_param, Res, ResMut, Resource, SystemState};
use super::{init_query_param, Res, ResMut, SystemState};
/// A builder that can create a [`SystemParam`].
///

View File

@ -12,9 +12,10 @@ use crate::{
entity::Entity,
event::{Event, Events},
observer::TriggerTargets,
resource::Resource,
result::{Error, Result},
schedule::ScheduleLabel,
system::{error_handler, IntoSystem, Resource, SystemId, SystemInput},
system::{error_handler, IntoSystem, SystemId, SystemInput},
world::{FromWorld, SpawnBatchIter, World},
};

View File

@ -26,11 +26,12 @@ use crate::{
entity::{Entities, Entity, EntityCloneBuilder},
event::Event,
observer::{Observer, TriggerTargets},
resource::Resource,
result::Error,
schedule::ScheduleLabel,
system::{
command::HandleError, entity_command::CommandWithEntity, input::SystemInput, Deferred,
IntoObserverSystem, IntoSystem, RegisteredSystem, Resource, SystemId,
IntoObserverSystem, IntoSystem, RegisteredSystem, SystemId,
},
world::{
command_queue::RawCommandQueue, unsafe_world_cell::UnsafeWorldCell, CommandQueue,
@ -2166,7 +2167,8 @@ mod tests {
use crate::{
self as bevy_ecs,
component::{require, Component},
system::{Commands, Resource},
resource::Resource,
system::Commands,
world::{CommandQueue, FromWorld, World},
};
use alloc::{string::String, sync::Arc, vec, vec::Vec};

View File

@ -339,6 +339,7 @@ mod tests {
prelude::{AnyOf, EntityRef},
query::{Added, Changed, Or, With, Without},
removal_detection::RemovedComponents,
resource::Resource,
result::Result,
schedule::{
common_conditions::resource_exists, ApplyDeferred, Condition, IntoSystemConfigs,
@ -346,7 +347,7 @@ mod tests {
},
system::{
Commands, In, IntoSystem, Local, NonSend, NonSendMut, ParamSet, Query, Res, ResMut,
Resource, Single, StaticSystemParam, System, SystemState,
Single, StaticSystemParam, System, SystemState,
},
world::{EntityMut, FromWorld, World},
};
@ -397,7 +398,7 @@ mod tests {
#[test]
fn get_many_is_ordered() {
use crate::system::Resource;
use crate::resource::Resource;
const ENTITIES_COUNT: usize = 1000;
#[derive(Resource)]
@ -478,7 +479,7 @@ mod tests {
#[test]
fn changed_resource_system() {
use crate::system::Resource;
use crate::resource::Resource;
#[derive(Resource)]
struct Flipper(bool);

View File

@ -9,6 +9,7 @@ use crate::{
Access, FilteredAccess, FilteredAccessSet, QueryData, QueryFilter, QuerySingleError,
QueryState, ReadOnlyQueryData,
},
resource::Resource,
storage::ResourceData,
system::{Query, Single, SystemMeta},
world::{
@ -17,7 +18,7 @@ use crate::{
},
};
use alloc::{borrow::ToOwned, boxed::Box, vec::Vec};
pub use bevy_ecs_macros::{Resource, SystemParam};
pub use bevy_ecs_macros::SystemParam;
use bevy_ptr::UnsafeCellDeref;
use bevy_utils::synccell::SyncCell;
#[cfg(feature = "track_location")]
@ -797,73 +798,6 @@ macro_rules! impl_param_set {
all_tuples_enumerated!(impl_param_set, 1, 8, P, m, p);
/// A type that can be inserted into a [`World`] as a singleton.
///
/// You can access resource data in systems using the [`Res`] and [`ResMut`] system parameters
///
/// Only one resource of each type can be stored in a [`World`] at any given time.
///
/// # Examples
///
/// ```
/// # let mut world = World::default();
/// # let mut schedule = Schedule::default();
/// # use bevy_ecs::prelude::*;
/// #[derive(Resource)]
/// struct MyResource { value: u32 }
///
/// world.insert_resource(MyResource { value: 42 });
///
/// fn read_resource_system(resource: Res<MyResource>) {
/// assert_eq!(resource.value, 42);
/// }
///
/// fn write_resource_system(mut resource: ResMut<MyResource>) {
/// assert_eq!(resource.value, 42);
/// resource.value = 0;
/// assert_eq!(resource.value, 0);
/// }
/// # schedule.add_systems((read_resource_system, write_resource_system).chain());
/// # schedule.run(&mut world);
/// ```
///
/// # `!Sync` Resources
/// A `!Sync` type cannot implement `Resource`. However, it is possible to wrap a `Send` but not `Sync`
/// type in [`SyncCell`] or the currently unstable [`Exclusive`] to make it `Sync`. This forces only
/// having mutable access (`&mut T` only, never `&T`), but makes it safe to reference across multiple
/// threads.
///
/// This will fail to compile since `RefCell` is `!Sync`.
/// ```compile_fail
/// # use std::cell::RefCell;
/// # use bevy_ecs::system::Resource;
///
/// #[derive(Resource)]
/// struct NotSync {
/// counter: RefCell<usize>,
/// }
/// ```
///
/// This will compile since the `RefCell` is wrapped with `SyncCell`.
/// ```
/// # use std::cell::RefCell;
/// # use bevy_ecs::system::Resource;
/// use bevy_utils::synccell::SyncCell;
///
/// #[derive(Resource)]
/// struct ActuallySync {
/// counter: SyncCell<RefCell<usize>>,
/// }
/// ```
///
/// [`Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html
#[diagnostic::on_unimplemented(
message = "`{Self}` is not a `Resource`",
label = "invalid `Resource`",
note = "consider annotating `{Self}` with `#[derive(Resource)]`"
)]
pub trait Resource: Send + Sync + 'static {}
// SAFETY: Res only reads a single World resource
unsafe impl<'a, T: Resource> ReadOnlySystemParam for Res<'a, T> {}

View File

@ -335,7 +335,7 @@ impl SystemBuffer for CommandQueue {
#[cfg(test)]
mod test {
use super::*;
use crate::{self as bevy_ecs, system::Resource};
use crate::{self as bevy_ecs, resource::Resource};
use alloc::{borrow::ToOwned, string::String, sync::Arc};
use core::{
panic::AssertUnwindSafe,

View File

@ -9,7 +9,8 @@ use crate::{
observer::{Observers, TriggerTargets},
prelude::{Component, QueryState},
query::{QueryData, QueryFilter},
system::{Commands, Query, Resource},
resource::Resource,
system::{Commands, Query},
traversal::Traversal,
world::{error::EntityFetchError, WorldEntityFetch},
};

View File

@ -10,8 +10,9 @@ use crate::{
observer::Observer,
query::{Access, ReadOnlyQueryData},
removal_detection::RemovedComponentEvents,
resource::Resource,
storage::Storages,
system::{IntoObserverSystem, Resource},
system::IntoObserverSystem,
world::{
error::EntityComponentError, unsafe_world_cell::UnsafeEntityCell, DeferredWorld, Mut, Ref,
World, ON_DESPAWN, ON_REMOVE, ON_REPLACE,

View File

@ -2,7 +2,7 @@ use crate::{
change_detection::{Mut, MutUntyped, Ref, Ticks, TicksMut},
component::{ComponentId, Tick},
query::Access,
system::Resource,
resource::Resource,
world::{unsafe_world_cell::UnsafeWorldCell, World},
};
use bevy_ptr::Ptr;

View File

@ -44,10 +44,11 @@ use crate::{
observer::Observers,
query::{DebugCheckedUnwrap, QueryData, QueryFilter, QueryState},
removal_detection::RemovedComponentEvents,
resource::Resource,
result::Result,
schedule::{Schedule, ScheduleLabel, Schedules},
storage::{ResourceData, Storages},
system::{Commands, Resource},
system::Commands,
world::{
command_queue::RawCommandQueue,
error::{EntityFetchError, TryRunScheduleError},
@ -3698,7 +3699,7 @@ mod tests {
component::{ComponentDescriptor, ComponentInfo, StorageType},
entity::hash_set::EntityHashSet,
ptr::OwningPtr,
system::Resource,
resource::Resource,
world::error::EntityFetchError,
};
use alloc::{

View File

@ -11,8 +11,8 @@ use crate::{
prelude::Component,
query::{DebugCheckedUnwrap, ReadOnlyQueryData},
removal_detection::RemovedComponentEvents,
resource::Resource,
storage::{ComponentSparseSet, Storages, Table},
system::Resource,
world::RawCommandQueue,
};
use bevy_platform_support::sync::atomic::Ordering;
@ -51,7 +51,7 @@ use {bevy_ptr::UnsafeCellDeref, core::panic::Location};
/// ```
/// use bevy_ecs::world::World;
/// use bevy_ecs::change_detection::Mut;
/// use bevy_ecs::system::Resource;
/// use bevy_ecs::resource::Resource;
/// use bevy_ecs::world::unsafe_world_cell::UnsafeWorldCell;
///
/// // INVARIANT: existence of this struct means that users of it are the only ones being able to access resources in the world

View File

@ -9,7 +9,7 @@ pub use bevy_gizmos_macros::GizmoConfigGroup;
))]
use {crate::GizmoAsset, bevy_asset::Handle, bevy_ecs::component::Component};
use bevy_ecs::{reflect::ReflectResource, system::Resource};
use bevy_ecs::{reflect::ReflectResource, resource::Resource};
use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypePath};
use bevy_utils::TypeIdMap;
use core::{

View File

@ -10,7 +10,8 @@ use core::{
use bevy_color::{Color, LinearRgba};
use bevy_ecs::{
component::Tick,
system::{Deferred, ReadOnlySystemParam, Res, Resource, SystemBuffer, SystemMeta, SystemParam},
resource::Resource,
system::{Deferred, ReadOnlySystemParam, Res, SystemBuffer, SystemMeta, SystemParam},
world::{unsafe_world_cell::UnsafeWorldCell, World},
};
use bevy_math::{Isometry2d, Isometry3d, Vec2, Vec3};

View File

@ -78,8 +78,9 @@ pub mod prelude {
use bevy_app::{App, FixedFirst, FixedLast, Last, Plugin, RunFixedMainLoop};
use bevy_asset::{Asset, AssetApp, AssetId, Assets, Handle};
use bevy_ecs::{
resource::Resource,
schedule::{IntoSystemConfigs, SystemSet},
system::{Res, ResMut, Resource},
system::{Res, ResMut},
};
use bevy_math::{Vec3, Vec4};
use bevy_reflect::TypePath;

View File

@ -9,8 +9,9 @@ use bevy_core_pipeline::core_2d::{Transparent2d, CORE_2D_DEPTH_FORMAT};
use bevy_ecs::{
prelude::Entity,
resource::Resource,
schedule::{IntoSystemConfigs, IntoSystemSetConfigs},
system::{Query, Res, ResMut, Resource},
system::{Query, Res, ResMut},
world::{FromWorld, World},
};
use bevy_image::BevyDefault as _;

View File

@ -13,8 +13,9 @@ use bevy_core_pipeline::{
use bevy_ecs::{
prelude::Entity,
query::Has,
resource::Resource,
schedule::{IntoSystemConfigs, IntoSystemSetConfigs},
system::{Query, Res, ResMut, Resource},
system::{Query, Res, ResMut},
world::{FromWorld, World},
};
use bevy_image::BevyDefault as _;

View File

@ -2293,7 +2293,7 @@ mod test {
},
AssetApp, AssetPlugin, AssetServer, Assets, Handle, LoadState,
};
use bevy_ecs::{system::Resource, world::World};
use bevy_ecs::{resource::Resource, world::World};
use bevy_log::LogPlugin;
use bevy_render::mesh::{skinning::SkinnedMeshInverseBindposes, MeshPlugin};
use bevy_scene::ScenePlugin;

View File

@ -1,6 +1,6 @@
//! The generic axis type.
use bevy_ecs::system::Resource;
use bevy_ecs::resource::Resource;
use bevy_utils::HashMap;
use core::hash::Hash;

View File

@ -1,6 +1,6 @@
//! The generic input type.
use bevy_ecs::system::Resource;
use bevy_ecs::resource::Resource;
use bevy_utils::HashSet;
use core::hash::Hash;
#[cfg(feature = "bevy_reflect")]

View File

@ -5,7 +5,8 @@ use bevy_ecs::{
change_detection::DetectChangesMut,
entity::Entity,
event::{Event, EventReader},
system::{ResMut, Resource},
resource::Resource,
system::ResMut,
};
use bevy_math::Vec2;
#[cfg(feature = "bevy_reflect")]

View File

@ -3,7 +3,8 @@
use bevy_ecs::{
entity::Entity,
event::{Event, EventReader},
system::{ResMut, Resource},
resource::Resource,
system::ResMut,
};
use bevy_math::Vec2;
#[cfg(feature = "bevy_reflect")]

View File

@ -62,7 +62,7 @@ use tracing_subscriber::{
};
#[cfg(feature = "tracing-chrome")]
use {
bevy_ecs::system::Resource,
bevy_ecs::resource::Resource,
bevy_utils::synccell::SyncCell,
tracing_subscriber::fmt::{format::DefaultFields, FormattedFields},
};

View File

@ -1,6 +1,6 @@
use alloc::sync::Arc;
use bevy_derive::EnumVariantMeta;
use bevy_ecs::system::Resource;
use bevy_ecs::resource::Resource;
use bevy_math::Vec3;
use bevy_utils::HashSet;
use bytemuck::cast_slice;

View File

@ -8,7 +8,8 @@ use bevy_ecs::{
entity::{hash_map::EntityHashMap, Entity},
query::{With, Without},
reflect::ReflectComponent,
system::{Commands, Query, Res, Resource},
resource::Resource,
system::{Commands, Query, Res},
world::{FromWorld, World},
};
use bevy_math::{uvec4, AspectRatio, UVec2, UVec3, UVec4, Vec3Swizzles as _, Vec4};

View File

@ -9,8 +9,9 @@ use bevy_ecs::{
entity::Entity,
query::With,
reflect::ReflectComponent,
resource::Resource,
schedule::IntoSystemConfigs,
system::{Commands, Local, Query, Res, ResMut, Resource},
system::{Commands, Local, Query, Res, ResMut},
};
use bevy_image::Image;
use bevy_math::{Affine3A, FloatOrd, Mat4, Vec3A, Vec4};

View File

@ -40,8 +40,9 @@ use bevy_ecs::{
query::{Changed, Or},
reflect::ReflectComponent,
removal_detection::RemovedComponents,
resource::Resource,
schedule::IntoSystemConfigs,
system::{Query, Res, ResMut, Resource},
system::{Query, Res, ResMut},
world::{FromWorld, World},
};
use bevy_image::Image;

View File

@ -7,7 +7,7 @@
use crate::Material;
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{
system::Resource,
resource::Resource,
world::{FromWorld, World},
};
use bevy_reflect::{std_traits::ReflectDefault, Reflect};

View File

@ -8,7 +8,8 @@ use bevy_ecs::{
entity::{hash_map::EntityHashMap, Entities, Entity},
event::EventReader,
query::Has,
system::{Local, Query, Res, ResMut, Resource, SystemState},
resource::Resource,
system::{Local, Query, Res, ResMut, SystemState},
};
use bevy_render::{
render_resource::StorageBuffer, sync_world::MainEntity, view::RenderLayers, MainWorld,

View File

@ -6,7 +6,8 @@ use super::{
use alloc::sync::Arc;
use bevy_asset::{AssetId, Assets};
use bevy_ecs::{
system::{Res, ResMut, Resource},
resource::Resource,
system::{Res, ResMut},
world::{FromWorld, World},
};
use bevy_math::Vec2;

View File

@ -4,7 +4,7 @@ use bevy_core_pipeline::{
core_3d::CORE_3D_DEPTH_FORMAT, fullscreen_vertex_shader::fullscreen_shader_vertex_state,
};
use bevy_ecs::{
system::Resource,
resource::Resource,
world::{FromWorld, World},
};
use bevy_render::render_resource::*;

View File

@ -9,7 +9,8 @@ use bevy_ecs::{
component::Component,
entity::{hash_map::EntityHashMap, Entity},
query::AnyOf,
system::{Commands, Query, Res, ResMut, Resource},
resource::Resource,
system::{Commands, Query, Res, ResMut},
};
use bevy_math::{UVec2, Vec4Swizzles};
use bevy_render::{

View File

@ -16,8 +16,9 @@ use bevy_ecs::{
component::Component,
entity::Entity,
query::{Has, QueryState, Without},
resource::Resource,
schedule::{common_conditions::resource_exists, IntoSystemConfigs as _},
system::{lifetimeless::Read, Commands, Res, ResMut, Resource},
system::{lifetimeless::Read, Commands, Res, ResMut},
world::{FromWorld, World},
};
use bevy_render::{

View File

@ -12,7 +12,8 @@ use bevy_ecs::{
component::Component,
entity::Entity,
query::Has,
system::{Commands, Query, Res, Resource},
resource::Resource,
system::{Commands, Query, Res},
world::{FromWorld, World},
};
use bevy_image::BevyDefault as _;

View File

@ -10,8 +10,9 @@ use bevy_ecs::{
prelude::{require, Component, Entity},
query::{Has, QueryItem, With},
reflect::ReflectComponent,
resource::Resource,
schedule::IntoSystemConfigs,
system::{Commands, Query, Res, ResMut, Resource},
system::{Commands, Query, Res, ResMut},
world::{FromWorld, World},
};
use bevy_reflect::{std_traits::ReflectDefault, Reflect};

View File

@ -16,8 +16,9 @@ use bevy_ecs::{
entity::Entity,
query::{Has, QueryItem, With},
reflect::ReflectComponent,
resource::Resource,
schedule::IntoSystemConfigs as _,
system::{lifetimeless::Read, Commands, Query, Res, ResMut, Resource},
system::{lifetimeless::Read, Commands, Query, Res, ResMut},
world::{FromWorld, World},
};
use bevy_image::BevyDefault as _;

View File

@ -13,7 +13,8 @@ use bevy_ecs::{
component::Component,
entity::Entity,
query::{Has, QueryItem, With},
system::{lifetimeless::Read, Commands, Local, Query, Res, ResMut, Resource},
resource::Resource,
system::{lifetimeless::Read, Commands, Local, Query, Res, ResMut},
world::{FromWorld, World},
};
use bevy_image::{BevyDefault, Image};

View File

@ -1512,7 +1512,7 @@ mod tests {
);
}
use super::*;
use bevy_ecs::{component::Component, system::Resource};
use bevy_ecs::{component::Component, resource::Resource};
use bevy_reflect::Reflect;
#[test]

View File

@ -15,7 +15,8 @@ use anyhow::Result as AnyhowResult;
use async_channel::{Receiver, Sender};
use async_io::Async;
use bevy_app::{App, Plugin, Startup};
use bevy_ecs::system::{Res, Resource};
use bevy_ecs::resource::Resource;
use bevy_ecs::system::Res;
use bevy_tasks::{futures_lite::StreamExt, IoTaskPool};
use core::{
convert::Infallible,

View File

@ -323,8 +323,9 @@ use bevy_app::{prelude::*, MainScheduleOrder};
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{
entity::Entity,
resource::Resource,
schedule::{IntoSystemConfigs, IntoSystemSetConfigs, ScheduleLabel, SystemSet},
system::{Commands, In, IntoSystem, ResMut, Resource, System, SystemId},
system::{Commands, In, IntoSystem, ResMut, System, SystemId},
world::World,
};
use bevy_utils::{prelude::default, HashMap};

View File

@ -6,8 +6,9 @@ use bevy_app::{App, Plugin};
use bevy_ecs::{
entity::{hash_map::EntityHashMap, Entity},
query::{Has, With},
resource::Resource,
schedule::IntoSystemConfigs as _,
system::{Query, Res, ResMut, Resource, StaticSystemParam},
system::{Query, Res, ResMut, StaticSystemParam},
world::{FromWorld, World},
};
use bevy_encase_derive::ShaderType;

View File

@ -1,7 +1,8 @@
//! Batching functionality when GPU preprocessing isn't in use.
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::system::{Res, ResMut, Resource, StaticSystemParam};
use bevy_ecs::resource::Resource;
use bevy_ecs::system::{Res, ResMut, StaticSystemParam};
use smallvec::{smallvec, SmallVec};
use tracing::error;
use wgpu::BindingResource;

View File

@ -28,7 +28,8 @@ use bevy_ecs::{
prelude::{require, With},
query::Has,
reflect::ReflectComponent,
system::{Commands, Query, Res, ResMut, Resource},
resource::Resource,
system::{Commands, Query, Res, ResMut},
world::DeferredWorld,
};
use bevy_image::Image;

View File

@ -1,5 +1,5 @@
use crate::{extract_resource::ExtractResource, render_resource::TextureView};
use bevy_ecs::{prelude::Component, reflect::ReflectComponent, system::Resource};
use bevy_ecs::{prelude::Component, reflect::ReflectComponent, resource::Resource};
use bevy_image::BevyDefault as _;
use bevy_math::UVec2;
use bevy_reflect::prelude::*;

View File

@ -6,7 +6,8 @@ use core::{
use std::thread::{self, ThreadId};
use bevy_diagnostic::{Diagnostic, DiagnosticMeasurement, DiagnosticPath, DiagnosticsStore};
use bevy_ecs::system::{Res, ResMut, Resource};
use bevy_ecs::resource::Resource;
use bevy_ecs::system::{Res, ResMut};
use bevy_platform_support::time::Instant;
use std::sync::Mutex;
use wgpu::{

View File

@ -11,7 +11,8 @@ use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{
prelude::Entity,
query::{QueryFilter, QueryItem, ReadOnlyQueryData},
system::{Query, ResMut, Resource},
resource::Resource,
system::{Query, ResMut},
};
use crate::sync_world::MainEntityHashMap;

View File

@ -11,8 +11,9 @@ use bevy_app::{App, Plugin};
use bevy_asset::AssetId;
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{
resource::Resource,
schedule::IntoSystemConfigs as _,
system::{Res, ResMut, Resource},
system::{Res, ResMut},
world::{FromWorld, World},
};
use bevy_utils::{default, HashMap, HashSet};

View File

@ -2,8 +2,8 @@ use async_channel::{Receiver, Sender};
use bevy_app::{App, AppExit, AppLabel, Plugin, SubApp};
use bevy_ecs::{
resource::Resource,
schedule::MainThreadExecutor,
system::Resource,
world::{Mut, World},
};
use bevy_tasks::ComputeTaskPool;

View File

@ -5,7 +5,7 @@ use crate::{
},
renderer::RenderContext,
};
use bevy_ecs::{define_label, intern::Interned, prelude::World, system::Resource};
use bevy_ecs::{define_label, intern::Interned, prelude::World, resource::Resource};
use bevy_utils::HashMap;
use core::fmt::Debug;

View File

@ -3,7 +3,8 @@ use bevy_app::{App, SubApp};
use bevy_ecs::{
entity::Entity,
query::{QueryEntityError, QueryState, ROQueryItem, ReadOnlyQueryData},
system::{ReadOnlySystemParam, Resource, SystemParam, SystemParamItem, SystemState},
resource::Resource,
system::{ReadOnlySystemParam, SystemParam, SystemParamItem, SystemState},
world::World,
};
use bevy_utils::TypeIdMap;

View File

@ -6,7 +6,7 @@ use crate::{
render_resource::batched_uniform_buffer::BatchedUniformBuffer,
renderer::{RenderDevice, RenderQueue},
};
use bevy_ecs::{prelude::Component, system::Resource};
use bevy_ecs::{prelude::Component, resource::Resource};
use core::marker::PhantomData;
use encase::{private::WriteInto, ShaderSize, ShaderType};
use nonmax::NonMaxU32;

View File

@ -8,7 +8,8 @@ use alloc::{borrow::Cow, sync::Arc};
use bevy_asset::{AssetEvent, AssetId, Assets};
use bevy_ecs::{
event::EventReader,
system::{Res, ResMut, Resource},
resource::Resource,
system::{Res, ResMut},
};
use bevy_tasks::Task;
use bevy_utils::{default, hashbrown::hash_map::EntryRef, HashMap, HashSet};

View File

@ -5,7 +5,7 @@ use crate::{
RenderPipelineDescriptor,
},
};
use bevy_ecs::system::Resource;
use bevy_ecs::resource::Resource;
use bevy_utils::{
default,
hashbrown::hash_map::{RawEntryMut, VacantEntry},

View File

@ -2,7 +2,7 @@ use crate::define_atomic_id;
use crate::renderer::WgpuWrapper;
use alloc::sync::Arc;
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::system::Resource;
use bevy_ecs::resource::Resource;
use core::ops::Deref;
define_atomic_id!(TextureId);

View File

@ -5,7 +5,7 @@ use crate::render_resource::{
};
use crate::WgpuWrapper;
use alloc::sync::Arc;
use bevy_ecs::system::Resource;
use bevy_ecs::resource::Resource;
use wgpu::{
util::DeviceExt, BindGroupDescriptor, BindGroupEntry, BindGroupLayoutDescriptor,
BindGroupLayoutEntry, BufferAsyncError, BufferBindingType, MaintainResult,

View File

@ -7,7 +7,8 @@ use bevy_ecs::{
observer::Trigger,
query::With,
reflect::ReflectComponent,
system::{Local, Query, ResMut, Resource, SystemState},
resource::Resource,
system::{Local, Query, ResMut, SystemState},
world::{Mut, OnAdd, OnRemove, World},
};
use bevy_reflect::Reflect;

View File

@ -7,7 +7,8 @@ use crate::{
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{
prelude::{FromWorld, Res, ResMut},
system::{Resource, SystemParam},
resource::Resource,
system::SystemParam,
};
use bevy_image::{BevyDefault, Image, ImageSampler, TextureFormatPixelInfo};
use bevy_utils::HashMap;

View File

@ -2,7 +2,7 @@ use crate::{
render_resource::{Texture, TextureView},
renderer::RenderDevice,
};
use bevy_ecs::{prelude::ResMut, system::Resource};
use bevy_ecs::{prelude::ResMut, resource::Resource};
use bevy_utils::{Entry, HashMap};
use wgpu::{TextureDescriptor, TextureViewDescriptor};

View File

@ -13,8 +13,9 @@ use bevy_ecs::{
query::{Changed, With},
reflect::ReflectComponent,
removal_detection::RemovedComponents,
resource::Resource,
schedule::IntoSystemConfigs as _,
system::{Query, Res, ResMut, Resource},
system::{Query, Res, ResMut},
};
use bevy_math::{vec4, FloatOrd, Vec4};
use bevy_reflect::Reflect;

View File

@ -205,7 +205,7 @@ mod tests {
},
hierarchy::ChildOf,
reflect::{AppTypeRegistry, ReflectComponent, ReflectMapEntities, ReflectResource},
system::Resource,
resource::Resource,
world::World,
};
use bevy_reflect::Reflect;

View File

@ -4,7 +4,7 @@ use bevy_ecs::{
component::{Component, ComponentId},
prelude::Entity,
reflect::{AppTypeRegistry, ReflectComponent, ReflectResource},
system::Resource,
resource::Resource,
world::World,
};
use bevy_reflect::{PartialReflect, ReflectFromReflect};

Some files were not shown because too many files have changed in this diff Show More