From 06e0b06b2e39a1e33f25ec65ccf743975e88ed1f Mon Sep 17 00:00:00 2001 From: Daniel McNab <36049421+DJMcNab@users.noreply.github.com> Date: Wed, 4 May 2022 18:41:37 +0000 Subject: [PATCH] Make `RunOnce` a non-manual `System` impl (#3922) # Objective - `RunOnce` was a manual `System` implementation. - Adding run criteria to stages was yet to be systemyoten ## Solution - Make it a normal function - yeet ## Changelog - Replaced `RunOnce` with `ShouldRun::once` ## Migration guide The run criterion `RunOnce`, which would make the controlled systems run only once, has been replaced with a new run criterion function `ShouldRun::once`. Replace all instances of `RunOnce` with `ShouldRun::once`. --- crates/bevy_app/src/app.rs | 4 +- crates/bevy_ecs/src/schedule/mod.rs | 12 ++-- crates/bevy_ecs/src/schedule/run_criteria.rs | 65 +++++--------------- 3 files changed, 23 insertions(+), 58 deletions(-) diff --git a/crates/bevy_app/src/app.rs b/crates/bevy_app/src/app.rs index fe48094497f5a..265d0b391e7c0 100644 --- a/crates/bevy_app/src/app.rs +++ b/crates/bevy_app/src/app.rs @@ -4,7 +4,7 @@ use bevy_ecs::{ event::Events, prelude::{FromWorld, IntoExclusiveSystem}, schedule::{ - IntoSystemDescriptor, RunOnce, Schedule, Stage, StageLabel, State, StateData, SystemSet, + IntoSystemDescriptor, Schedule, ShouldRun, Stage, StageLabel, State, StateData, SystemSet, SystemStage, }, system::Resource, @@ -591,7 +591,7 @@ impl App { .add_stage( StartupSchedule, Schedule::default() - .with_run_criteria(RunOnce::default()) + .with_run_criteria(ShouldRun::once) .with_stage(StartupStage::PreStartup, SystemStage::parallel()) .with_stage(StartupStage::Startup, SystemStage::parallel()) .with_stage(StartupStage::PostStartup, SystemStage::parallel()), diff --git a/crates/bevy_ecs/src/schedule/mod.rs b/crates/bevy_ecs/src/schedule/mod.rs index dc228f4265de3..1aab0f0f4414d 100644 --- a/crates/bevy_ecs/src/schedule/mod.rs +++ b/crates/bevy_ecs/src/schedule/mod.rs @@ -27,7 +27,7 @@ pub use system_set::*; use std::fmt::Debug; -use crate::{system::System, world::World}; +use crate::{system::IntoSystem, world::World}; use bevy_utils::HashMap; /// A container of [`Stage`]s set to be run in a linear order. @@ -76,7 +76,7 @@ impl Schedule { } #[must_use] - pub fn with_run_criteria>(mut self, system: S) -> Self { + pub fn with_run_criteria, P>(mut self, system: S) -> Self { self.set_run_criteria(system); self } @@ -92,11 +92,9 @@ impl Schedule { self } - pub fn set_run_criteria>( - &mut self, - system: S, - ) -> &mut Self { - self.run_criteria.set(Box::new(system)); + pub fn set_run_criteria, P>(&mut self, system: S) -> &mut Self { + self.run_criteria + .set(Box::new(IntoSystem::into_system(system))); self } diff --git a/crates/bevy_ecs/src/schedule/run_criteria.rs b/crates/bevy_ecs/src/schedule/run_criteria.rs index f3b42500b6919..6bc7320c357a0 100644 --- a/crates/bevy_ecs/src/schedule/run_criteria.rs +++ b/crates/bevy_ecs/src/schedule/run_criteria.rs @@ -1,9 +1,6 @@ use crate::{ - archetype::ArchetypeComponentId, - component::ComponentId, - query::Access, schedule::{BoxedRunCriteriaLabel, GraphNode, RunCriteriaLabel}, - system::{BoxedSystem, IntoSystem, System}, + system::{BoxedSystem, IntoSystem, Local}, world::World, }; use std::borrow::Cow; @@ -44,6 +41,21 @@ pub enum ShouldRun { NoAndCheckAgain, } +impl ShouldRun { + /// A run criterion which returns [`ShouldRun::Yes`] exactly once. + /// + /// This leads to the systems controlled by it only being + /// executed one time only. + pub fn once(mut ran: Local) -> ShouldRun { + if *ran { + ShouldRun::No + } else { + *ran = true; + ShouldRun::Yes + } + } +} + #[derive(Default)] pub(crate) struct BoxedRunCriteria { criteria_system: Option>, @@ -324,48 +336,3 @@ impl RunCriteria { } } } - -#[derive(Default)] -pub struct RunOnce { - ran: bool, - archetype_component_access: Access, - component_access: Access, -} - -impl System for RunOnce { - type In = (); - type Out = ShouldRun; - - fn name(&self) -> Cow<'static, str> { - Cow::Borrowed(std::any::type_name::()) - } - - fn component_access(&self) -> &Access { - &self.component_access - } - - fn archetype_component_access(&self) -> &Access { - &self.archetype_component_access - } - - fn is_send(&self) -> bool { - true - } - - unsafe fn run_unsafe(&mut self, _input: (), _world: &World) -> ShouldRun { - if self.ran { - ShouldRun::No - } else { - self.ran = true; - ShouldRun::Yes - } - } - - fn apply_buffers(&mut self, _world: &mut World) {} - - fn initialize(&mut self, _world: &mut World) {} - - fn update_archetype_component_access(&mut self, _world: &World) {} - - fn check_change_tick(&mut self, _change_tick: u32) {} -}