Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Make Resource trait opt-in, requiring #[derive(Resource)] V2 #5577

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
4 changes: 2 additions & 2 deletions benches/benches/bevy_ecs/scheduling/run_criteria.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bevy_ecs::{
component::Component,
prelude::{ParallelSystemDescriptorCoercion, Res, RunCriteriaDescriptorCoercion},
prelude::{ParallelSystemDescriptorCoercion, Res, Resource, RunCriteriaDescriptorCoercion},
schedule::{ShouldRun, Stage, SystemStage},
system::Query,
world::World,
Expand Down Expand Up @@ -136,7 +136,7 @@ pub fn run_criteria_no_with_labels(criterion: &mut Criterion) {
group.finish();
}

#[derive(Component)]
#[derive(Component, Resource)]
struct TestBool(pub bool);

pub fn run_criteria_yes_with_query(criterion: &mut Criterion) {
Expand Down
21 changes: 16 additions & 5 deletions crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{CoreStage, Plugin, PluginGroup, PluginGroupBuilder, StartupSchedule, StartupStage};
pub use bevy_derive::AppLabel;
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{
event::{Event, Events},
prelude::{FromWorld, IntoExclusiveSystem},
Expand All @@ -22,6 +23,11 @@ bevy_utils::define_label!(
AppLabelId,
);

/// The [`Resource`] that stores the [`App`]'s [`TypeRegistry`](bevy_reflect::TypeRegistry).
#[cfg(feature = "bevy_reflect")]
#[derive(Resource, Clone, Deref, DerefMut, Default)]
pub struct AppTypeRegistry(pub bevy_reflect::TypeRegistryArc);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not an issue to be solved in this pr, but given that this is the only TypeRegistry instance 99.99% of Bevy users will interact with, I think it might be worth trying to sort out a non-confusing way to give it the TypeRegistry name directly. Not sure the best way to do that. Just something to think about.


#[allow(clippy::needless_doctest_main)]
/// A container of app logic and data.
///
Expand Down Expand Up @@ -74,7 +80,7 @@ impl Default for App {
fn default() -> Self {
let mut app = App::empty();
#[cfg(feature = "bevy_reflect")]
app.init_resource::<bevy_reflect::TypeRegistryArc>();
app.init_resource::<AppTypeRegistry>();

app.add_default_stages()
.add_event::<AppExit>()
Expand Down Expand Up @@ -647,7 +653,9 @@ impl App {
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// #
/// #[derive(Resource)]
/// struct MyCounter {
/// counter: usize,
/// }
Expand All @@ -660,15 +668,16 @@ impl App {
self
}

/// Inserts a non-send [`Resource`] to the app.
/// Inserts a non-send resource to the app.
///
/// You usually want to use [`insert_resource`](Self::insert_resource),
/// but there are some special cases when a [`Resource`] cannot be sent across threads.
/// but there are some special cases when a resource cannot be sent across threads.
tim-blackbird marked this conversation as resolved.
Show resolved Hide resolved
///
/// # Examples
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// #
/// struct MyCounter {
/// counter: usize,
Expand All @@ -694,7 +703,9 @@ impl App {
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// #
/// #[derive(Resource)]
/// struct MyCounter {
/// counter: usize,
/// }
Expand Down Expand Up @@ -873,7 +884,7 @@ impl App {
#[cfg(feature = "bevy_reflect")]
pub fn register_type<T: bevy_reflect::GetTypeRegistration>(&mut self) -> &mut Self {
{
let registry = self.world.resource_mut::<bevy_reflect::TypeRegistryArc>();
let registry = self.world.resource_mut::<AppTypeRegistry>();
registry.write().register::<T>();
}
self
Expand Down Expand Up @@ -906,7 +917,7 @@ impl App {
&mut self,
) -> &mut Self {
{
let registry = self.world.resource_mut::<bevy_reflect::TypeRegistryArc>();
let registry = self.world.resource_mut::<AppTypeRegistry>();
registry.write().register_type_data::<T, D>();
}
self
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_app/src/ci_testing.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use crate::{app::AppExit, App};
use serde::Deserialize;

use bevy_ecs::prelude::Resource;
use bevy_utils::tracing::info;

/// A configuration struct for automated CI testing.
///
/// It gets used when the `bevy_ci_testing` feature is enabled to automatically
/// exit a Bevy app when run through the CI. This is needed because otherwise
/// Bevy apps would be stuck in the game loop and wouldn't allow the CI to progress.
#[derive(Deserialize)]
#[derive(Deserialize, Resource)]
pub struct CiTestingConfig {
/// The number of frames after which Bevy should exit.
pub exit_after: Option<u32>,
Expand Down
3 changes: 3 additions & 0 deletions crates/bevy_app/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ pub use schedule_runner::*;

#[allow(missing_docs)]
pub mod prelude {
#[cfg(feature = "bevy_reflect")]
#[doc(hidden)]
pub use crate::AppTypeRegistry;
#[doc(hidden)]
pub use crate::{
app::App, CoreStage, DynamicPlugin, Plugin, PluginGroup, StartupSchedule, StartupStage,
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_app/src/schedule_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::{
plugin::Plugin,
};
use bevy_ecs::event::{Events, ManualEventReader};
use bevy_ecs::prelude::Resource;
use bevy_utils::{Duration, Instant};

#[cfg(target_arch = "wasm32")]
Expand Down Expand Up @@ -34,7 +35,7 @@ impl Default for RunMode {
/// The configuration information for the [`ScheduleRunnerPlugin`].
///
/// It gets added as a [`Resource`](bevy_ecs::system::Resource) inside of the [`ScheduleRunnerPlugin`].
#[derive(Copy, Clone, Default)]
#[derive(Copy, Clone, Default, Resource)]
pub struct ScheduleRunnerSettings {
/// Determines whether the [`Schedule`](bevy_ecs::schedule::Schedule) is run once or repeatedly.
pub run_mode: RunMode,
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_asset/src/asset_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
RefChange, RefChangeChannel, SourceInfo, SourceMeta,
};
use anyhow::Result;
use bevy_ecs::system::{Res, ResMut};
use bevy_ecs::system::{Res, ResMut, Resource};
use bevy_log::warn;
use bevy_tasks::IoTaskPool;
use bevy_utils::{Entry, HashMap, Uuid};
Expand Down Expand Up @@ -102,7 +102,7 @@ pub struct AssetServerInternal {
/// See the [`asset_loading`] example for more information.
///
/// [`asset_loading`]: https://github.com/bevyengine/bevy/tree/latest/examples/asset/asset_loading.rs
#[derive(Clone)]
#[derive(Clone, Resource)]
pub struct AssetServer {
pub(crate) server: Arc<AssetServerInternal>,
}
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_asset/src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
use bevy_app::App;
use bevy_ecs::{
event::{EventWriter, Events},
system::ResMut,
system::{ResMut, Resource},
world::FromWorld,
};
use bevy_utils::HashMap;
Expand Down Expand Up @@ -66,7 +66,7 @@ impl<T: Asset> Debug for AssetEvent<T> {
/// Remember, if there are no Strong handles for an asset (i.e. they have all been dropped), the
/// asset will unload. Make sure you always have a Strong handle when you want to keep an asset
/// loaded!
#[derive(Debug)]
#[derive(Debug, Resource)]
pub struct Assets<T: Asset> {
assets: HashMap<HandleId, T>,
events: Events<AssetEvent<T>>,
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_asset/src/debug_asset_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use bevy_app::{App, Plugin};
use bevy_ecs::{
event::Events,
schedule::SystemLabel,
system::{NonSendMut, Res, ResMut, SystemState},
system::{NonSendMut, Res, ResMut, Resource, SystemState},
};
use bevy_tasks::{IoTaskPool, TaskPoolBuilder};
use bevy_utils::HashMap;
Expand Down Expand Up @@ -52,6 +52,7 @@ pub struct DebugAssetServerPlugin;

/// A collection that maps internal assets in a [`DebugAssetApp`]'s asset server to their mirrors in
/// the main [`App`].
#[derive(Resource)]
pub struct HandleMap<T: Asset> {
/// The collection of asset handles.
pub handles: HashMap<Handle<T>, Handle<T>>,
Expand Down
6 changes: 5 additions & 1 deletion crates/bevy_asset/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ pub use loader::*;
pub use path::*;

use bevy_app::{prelude::Plugin, App};
use bevy_ecs::schedule::{StageLabel, SystemStage};
use bevy_ecs::{
schedule::{StageLabel, SystemStage},
system::Resource,
};

/// The names of asset stages in an [`App`] schedule.
#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)]
Expand All @@ -62,6 +65,7 @@ pub enum AssetStage {
pub struct AssetPlugin;

/// [`AssetServer`] settings.
#[derive(Resource)]
pub struct AssetServerSettings {
/// The base folder where assets are loaded from, relative to the executable.
pub asset_folder: String,
Expand Down
4 changes: 3 additions & 1 deletion crates/bevy_audio/src/audio.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::{AudioSink, AudioSource, Decodable};
use bevy_asset::{Asset, Handle, HandleId};
use bevy_ecs::system::Resource;
use parking_lot::RwLock;
use std::{collections::VecDeque, fmt};

/// Use this resource to play audio
/// Use this [`Resource`] to play audio.
///
/// ```
/// # use bevy_ecs::system::Res;
Expand All @@ -13,6 +14,7 @@ use std::{collections::VecDeque, fmt};
/// audio.play(asset_server.load("my_sound.ogg"));
/// }
/// ```
#[derive(Resource)]
pub struct Audio<Source = AudioSource>
where
Source: Asset + Decodable,
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_core/src/task_pool_options.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use bevy_ecs::prelude::Resource;
use bevy_tasks::{AsyncComputeTaskPool, ComputeTaskPool, IoTaskPool, TaskPoolBuilder};
use bevy_utils::tracing::trace;

Expand Down Expand Up @@ -33,7 +34,7 @@ impl TaskPoolThreadAssignmentPolicy {
/// Helper for configuring and creating the default task pools. For end-users who want full control,
/// insert the default task pools into the resource map manually. If the pools are already inserted,
/// this helper will do nothing.
#[derive(Clone)]
#[derive(Clone, Resource)]
pub struct DefaultTaskPoolOptions {
/// If the number of physical cores is less than min_total_threads, force using
/// min_total_threads
Expand Down
8 changes: 4 additions & 4 deletions crates/bevy_core_pipeline/src/clear_color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ pub enum ClearColorConfig {
None,
}

/// When used as a resource, sets the color that is used to clear the screen between frames.
/// A [`Resource`] that stores the color that is used to clear the screen between frames.
tim-blackbird marked this conversation as resolved.
Show resolved Hide resolved
///
/// This color appears as the "background" color for simple apps, when
/// there are portions of the screen with nothing rendered.
#[derive(Component, Clone, Debug, Deref, DerefMut, ExtractResource, Reflect)]
/// This color appears as the "background" color for simple apps,
/// when there are portions of the screen with nothing rendered.
#[derive(Resource, Clone, Debug, Deref, DerefMut, ExtractResource, Reflect)]
#[reflect(Resource)]
pub struct ClearColor(pub Color);

Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_diagnostic/src/diagnostic.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use bevy_ecs::system::Resource;
use bevy_log::warn;
use bevy_utils::{Duration, Instant, StableHashMap, Uuid};
use std::{borrow::Cow, collections::VecDeque};
Expand Down Expand Up @@ -154,7 +155,7 @@ impl Diagnostic {
}

/// A collection of [Diagnostic]s
#[derive(Debug, Default)]
#[derive(Debug, Default, Resource)]
pub struct Diagnostics {
// This uses a [`StableHashMap`] to ensure that the iteration order is deterministic between
// runs when all diagnostics are inserted in the same order.
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use crate::{Diagnostic, DiagnosticId, Diagnostics};
use bevy_app::prelude::*;
use bevy_ecs::system::{Res, ResMut};
use bevy_ecs::system::{Res, ResMut, Resource};
use bevy_time::Time;

/// Adds "frame time" diagnostic to an App, specifically "frame time", "fps" and "frame count"
#[derive(Default)]
pub struct FrameTimeDiagnosticsPlugin;

#[derive(Resource)]
pub struct FrameTimeDiagnosticsState {
frame_count: u64,
}
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_diagnostic/src/log_diagnostics_plugin.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{Diagnostic, DiagnosticId, Diagnostics};
use bevy_app::prelude::*;
use bevy_ecs::system::{Res, ResMut};
use bevy_ecs::system::{Res, ResMut, Resource};
use bevy_log::{debug, info};
use bevy_time::{Time, Timer};
use bevy_utils::Duration;
Expand All @@ -13,6 +13,7 @@ pub struct LogDiagnosticsPlugin {
}

/// State used by the [`LogDiagnosticsPlugin`]
#[derive(Resource)]
struct LogDiagnosticsState {
timer: Timer,
filter: Option<Vec<DiagnosticId>>,
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_ecs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ Apps often require unique resources, such as asset collections, renderers, audio
```rust
use bevy_ecs::prelude::*;

#[derive(Default)]
#[derive(Resource, Default)]
struct Time {
seconds: f32,
}
Expand Down Expand Up @@ -213,6 +213,7 @@ Resources also expose change state:
```rust
use bevy_ecs::prelude::*;

#[derive(Resource)]
struct Time(f32);

// Prints "time changed!" if the Time resource has changed since the last run of the System
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/examples/change_detection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn main() {
}

// This struct will be used as a Resource keeping track of the total amount of spawned entities
#[derive(Debug)]
#[derive(Debug, Resource)]
struct EntityCounter {
pub value: i32,
}
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/examples/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn main() {
}

// Counter resource to be increased and read by systems
#[derive(Debug)]
#[derive(Debug, Resource)]
struct Counter {
pub value: i32,
}
Expand Down
18 changes: 18 additions & 0 deletions crates/bevy_ecs/macros/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,24 @@ use proc_macro2::{Span, TokenStream as TokenStream2};
use quote::{quote, ToTokens};
use syn::{parse_macro_input, parse_quote, DeriveInput, Error, Ident, Path, Result};

pub fn derive_resource(input: TokenStream) -> TokenStream {
let mut ast = parse_macro_input!(input as DeriveInput);
let bevy_ecs_path: Path = crate::bevy_ecs_path();

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

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

TokenStream::from(quote! {
impl #impl_generics #bevy_ecs_path::component::Resource for #struct_name #type_generics #where_clause {
}
})
}

pub fn derive_component(input: TokenStream) -> TokenStream {
let mut ast = parse_macro_input!(input as DeriveInput);
let bevy_ecs_path: Path = crate::bevy_ecs_path();
Expand Down
5 changes: 5 additions & 0 deletions crates/bevy_ecs/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,11 @@ pub(crate) fn bevy_ecs_path() -> syn::Path {
BevyManifest::default().get_path("bevy_ecs")
}

#[proc_macro_derive(Resource)]
pub fn derive_resource(input: TokenStream) -> TokenStream {
component::derive_resource(input)
}

#[proc_macro_derive(Component, attributes(component))]
pub fn derive_component(input: TokenStream) -> TokenStream {
component::derive_component(input)
Expand Down
Loading