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

System Lifecycle Rework: all Systems are initialized by definition #2777

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 11 additions & 8 deletions crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::{CoreStage, Events, Plugin, PluginGroup, PluginGroupBuilder, StartupStage};
use bevy_ecs::{
component::{Component, ComponentDescriptor},
prelude::{FromWorld, IntoExclusiveSystem},
prelude::FromWorld,
schedule::{
IntoSystemDescriptor, RunOnce, Schedule, Stage, StageLabel, State, SystemSet, SystemStage,
IntoExclusiveSystemWrapper, IntoSystemDescriptor, RunOnce, Schedule, Stage, StageLabel,
State, SystemSet, SystemStage,
},
world::World,
};
Expand Down Expand Up @@ -47,10 +48,9 @@ impl Default for App {
let mut app = App::empty();
#[cfg(feature = "bevy_reflect")]
app.init_resource::<bevy_reflect::TypeRegistryArc>();

app.add_default_stages()
.add_event::<AppExit>()
.add_system_to_stage(CoreStage::Last, World::clear_trackers.exclusive_system());
.add_system_to_stage(CoreStage::Last, World::clear_trackers.exclusive());

#[cfg(feature = "bevy_ci_testing")]
{
Expand Down Expand Up @@ -216,7 +216,8 @@ impl App {
stage_label: impl StageLabel,
system: impl IntoSystemDescriptor<Params>,
) -> &mut Self {
self.schedule.add_system_to_stage(stage_label, system);
self.schedule
.add_system_to_stage(&mut self.world, stage_label, system);
self
}

Expand All @@ -226,7 +227,7 @@ impl App {
system_set: SystemSet,
) -> &mut Self {
self.schedule
.add_system_set_to_stage(stage_label, system_set);
.add_system_set_to_stage(&mut self.world, stage_label, system_set);
self
}

Expand Down Expand Up @@ -266,9 +267,10 @@ impl App {
stage_label: impl StageLabel,
system: impl IntoSystemDescriptor<Params>,
) -> &mut Self {
let world = &mut self.world;
self.schedule
.stage(CoreStage::Startup, |schedule: &mut Schedule| {
schedule.add_system_to_stage(stage_label, system)
schedule.add_system_to_stage(world, stage_label, system)
});
self
}
Expand All @@ -278,9 +280,10 @@ impl App {
stage_label: impl StageLabel,
system_set: SystemSet,
) -> &mut Self {
let world = &mut self.world;
self.schedule
.stage(CoreStage::Startup, |schedule: &mut Schedule| {
schedule.add_system_set_to_stage(stage_label, system_set)
schedule.add_system_set_to_stage(world, stage_label, system_set)
});
self
}
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_audio/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub use audio_source::*;

use bevy_app::prelude::*;
use bevy_asset::AddAsset;
use bevy_ecs::system::IntoExclusiveSystem;
use bevy_ecs::{schedule::IntoExclusiveSystemWrapper, system::IntoExclusiveSystem};

/// Adds support for audio playback to an App
#[derive(Default)]
Expand All @@ -26,7 +26,7 @@ impl Plugin for AudioPlugin {
.init_resource::<Audio<AudioSource>>()
.add_system_to_stage(
CoreStage::PostUpdate,
play_queued_audio_system::<AudioSource>.exclusive_system(),
play_queued_audio_system::<AudioSource>.exclusive(),
);

#[cfg(any(feature = "mp3", feature = "flac", feature = "wav", feature = "vorbis"))]
Expand Down
8 changes: 2 additions & 6 deletions crates/bevy_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ pub mod prelude {
}

use bevy_app::prelude::*;
use bevy_ecs::{
entity::Entity,
schedule::{ExclusiveSystemDescriptorCoercion, SystemLabel},
system::IntoExclusiveSystem,
};
use bevy_ecs::{entity::Entity, schedule::{ExclusiveSystemDescriptorCoercion, IntoExclusiveSystemWrapper, ParallelSystemDescriptorCoercion, SystemLabel}, system::IntoExclusiveSystem};
use bevy_utils::HashSet;
use std::ops::Range;

Expand Down Expand Up @@ -60,7 +56,7 @@ impl Plugin for CorePlugin {
// in CoreStage::First
.add_system_to_stage(
CoreStage::First,
time_system.exclusive_system().label(CoreSystem::Time),
time_system.exclusive().label(CoreSystem::Time),
)
.add_startup_system_to_stage(StartupStage::PostStartup, entity_labels_system)
.add_system_to_stage(CoreStage::PostUpdate, entity_labels_system);
Expand Down
91 changes: 23 additions & 68 deletions crates/bevy_core/src/time/fixed_timestep.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
use crate::Time;
use bevy_ecs::{
archetype::{Archetype, ArchetypeComponentId},
component::ComponentId,
query::Access,
prelude::ConfigSystemParamFunction,
schedule::ShouldRun,
system::{ConfigurableSystem, IntoSystem, Local, Res, ResMut, System, SystemId},
system::{IntoSystem, Local, Res, ResMut, System},
world::World,
};
use bevy_utils::HashMap;
use std::borrow::Cow;

pub struct FixedTimestepState {
pub step: f64,
Expand Down Expand Up @@ -50,14 +47,12 @@ impl FixedTimesteps {

pub struct FixedTimestep {
state: State,
internal_system: Box<dyn System<In = (), Out = ShouldRun>>,
}

impl Default for FixedTimestep {
fn default() -> Self {
Self {
state: State::default(),
internal_system: Box::new(Self::prepare_system.system()),
}
}
}
Expand All @@ -69,7 +64,6 @@ impl FixedTimestep {
step,
..Default::default()
},
..Default::default()
}
}

Expand All @@ -79,7 +73,6 @@ impl FixedTimestep {
step: 1.0 / rate,
..Default::default()
},
..Default::default()
}
}

Expand All @@ -104,6 +97,27 @@ impl FixedTimestep {
}
}

impl IntoSystem<(), ShouldRun, ()> for FixedTimestep {
Copy link
Member

Choose a reason for hiding this comment

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

I love the reduced boilerplate needed here.

type System = Box<dyn System<In = (), Out = ShouldRun>>;

fn system(self, world: &mut World) -> Self::System {
if let Some(ref label) = self.state.label {
let mut fixed_timesteps = world.get_resource_mut::<FixedTimesteps>().unwrap();
fixed_timesteps.fixed_timesteps.insert(
label.clone(),
FixedTimestepState {
accumulator: 0.0,
step: self.state.step,
},
);
}
let prepare_system = Self::prepare_system
.config(|c| c.0 = Some(self.state))
.system(world);
Box::new(prepare_system)
}
}

#[derive(Clone)]
pub struct State {
label: Option<String>, // TODO: consider making this a TypedLabel
Expand Down Expand Up @@ -139,62 +153,3 @@ impl State {
}
}
}

impl System for FixedTimestep {
type In = ();
type Out = ShouldRun;

fn name(&self) -> Cow<'static, str> {
Cow::Borrowed(std::any::type_name::<FixedTimestep>())
}

fn id(&self) -> SystemId {
self.internal_system.id()
}

fn new_archetype(&mut self, archetype: &Archetype) {
self.internal_system.new_archetype(archetype);
}

fn archetype_component_access(&self) -> &Access<ArchetypeComponentId> {
self.internal_system.archetype_component_access()
}

fn component_access(&self) -> &Access<ComponentId> {
self.internal_system.component_access()
}

fn is_send(&self) -> bool {
self.internal_system.is_send()
}

unsafe fn run_unsafe(&mut self, _input: (), world: &World) -> ShouldRun {
// SAFE: this system inherits the internal system's component access and archetype component
// access, which means the caller has ensured running the internal system is safe
self.internal_system.run_unsafe((), world)
}

fn apply_buffers(&mut self, world: &mut World) {
self.internal_system.apply_buffers(world)
}

fn initialize(&mut self, world: &mut World) {
self.internal_system =
Box::new(Self::prepare_system.config(|c| c.0 = Some(self.state.clone())));
self.internal_system.initialize(world);
if let Some(ref label) = self.state.label {
let mut fixed_timesteps = world.get_resource_mut::<FixedTimesteps>().unwrap();
fixed_timesteps.fixed_timesteps.insert(
label.clone(),
FixedTimestepState {
accumulator: 0.0,
step: self.state.step,
},
);
}
}

fn check_change_tick(&mut self, change_tick: u32) {
self.internal_system.check_change_tick(change_tick);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use bevy_app::{App, Plugin};
use bevy_ecs::{
schedule::IntoExclusiveSystemWrapper,
system::{IntoExclusiveSystem, ResMut},
world::World,
};
Expand All @@ -13,7 +14,7 @@ pub struct EntityCountDiagnosticsPlugin;
impl Plugin for EntityCountDiagnosticsPlugin {
fn build(&self, app: &mut App) {
app.add_startup_system(Self::setup_system)
.add_system(Self::diagnostic_system.exclusive_system());
.add_system(Self::diagnostic_system.exclusive());
}
}

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 @@ -29,8 +29,9 @@ pub mod prelude {
Schedule, Stage, StageLabel, State, SystemLabel, SystemSet, SystemStage,
},
system::{
Commands, ConfigurableSystem, In, IntoChainSystem, IntoExclusiveSystem, IntoSystem,
Local, NonSend, NonSendMut, Query, QuerySet, RemovedComponents, Res, ResMut, System,
Commands, ConfigSystemParamFunction, In, IntoChainSystem, IntoExclusiveSystem,
IntoSystem, Local, NonSend, NonSendMut, Query, QuerySet, RemovedComponents, Res,
ResMut, System,
},
world::{FromWorld, Mut, World},
};
Expand Down
Loading