Skip to content

Commit

Permalink
Make RunOnce a non-manual System impl (bevyengine#3922)
Browse files Browse the repository at this point in the history
# 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`.
  • Loading branch information
DJMcNab authored and exjam committed May 22, 2022
1 parent aaa7e72 commit 06e0b06
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 58 deletions.
4 changes: 2 additions & 2 deletions crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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()),
Expand Down
12 changes: 5 additions & 7 deletions crates/bevy_ecs/src/schedule/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -76,7 +76,7 @@ impl Schedule {
}

#[must_use]
pub fn with_run_criteria<S: System<In = (), Out = ShouldRun>>(mut self, system: S) -> Self {
pub fn with_run_criteria<S: IntoSystem<(), ShouldRun, P>, P>(mut self, system: S) -> Self {
self.set_run_criteria(system);
self
}
Expand All @@ -92,11 +92,9 @@ impl Schedule {
self
}

pub fn set_run_criteria<S: System<In = (), Out = ShouldRun>>(
&mut self,
system: S,
) -> &mut Self {
self.run_criteria.set(Box::new(system));
pub fn set_run_criteria<S: IntoSystem<(), ShouldRun, P>, P>(&mut self, system: S) -> &mut Self {
self.run_criteria
.set(Box::new(IntoSystem::into_system(system)));
self
}

Expand Down
65 changes: 16 additions & 49 deletions crates/bevy_ecs/src/schedule/run_criteria.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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<bool>) -> ShouldRun {
if *ran {
ShouldRun::No
} else {
*ran = true;
ShouldRun::Yes
}
}
}

#[derive(Default)]
pub(crate) struct BoxedRunCriteria {
criteria_system: Option<BoxedSystem<(), ShouldRun>>,
Expand Down Expand Up @@ -324,48 +336,3 @@ impl RunCriteria {
}
}
}

#[derive(Default)]
pub struct RunOnce {
ran: bool,
archetype_component_access: Access<ArchetypeComponentId>,
component_access: Access<ComponentId>,
}

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

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

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

fn archetype_component_access(&self) -> &Access<ArchetypeComponentId> {
&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) {}
}

0 comments on commit 06e0b06

Please sign in to comment.