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] - System sets and run criteria v2 #1675

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 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
6 changes: 6 additions & 0 deletions crates/bevy_ecs/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,12 @@ pub fn derive_ambiguity_set_label(input: TokenStream) -> TokenStream {
derive_label(input, Ident::new("AmbiguitySetLabel", Span::call_site())).into()
}

#[proc_macro_derive(RunCriterionLabel)]
pub fn derive_run_criterion_label(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
derive_label(input, Ident::new("RunCriterionLabel", Span::call_site())).into()
}

fn derive_label(input: DeriveInput, label_type: Ident) -> TokenStream2 {
let ident = input.ident;
let ecs_path: Path = bevy_ecs_path();
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_ecs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ pub mod prelude {
query::{Added, Changed, Flags, Mutated, Or, QueryState, With, WithBundle, Without},
schedule::{
AmbiguitySetLabel, ExclusiveSystemDescriptorCoercion, ParallelSystemDescriptorCoercion,
Schedule, Stage, StageLabel, State, SystemLabel, SystemSet, SystemStage,
RunCriteriaChaining, RunCriteriaLabelling, RunCriterionLabel, Schedule, Stage,
StageLabel, State, SystemLabel, SystemSet, SystemStage,
},
system::{
Commands, In, IntoChainSystem, IntoExclusiveSystem, IntoSystem, Local, NonSend,
Expand Down
9 changes: 8 additions & 1 deletion crates/bevy_ecs/src/schedule/label.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub use bevy_ecs_macros::{AmbiguitySetLabel, StageLabel, SystemLabel};
pub use bevy_ecs_macros::{AmbiguitySetLabel, RunCriterionLabel, StageLabel, SystemLabel};

use std::{
any::Any,
Expand Down Expand Up @@ -67,6 +67,12 @@ pub trait AmbiguitySetLabel: DynHash + Debug + Send + Sync + 'static {
}
pub(crate) type BoxedAmbiguitySetLabel = Box<dyn AmbiguitySetLabel>;

pub trait RunCriterionLabel: DynHash + Debug + Send + Sync + 'static {
#[doc(hidden)]
fn dyn_clone(&self) -> Box<dyn RunCriterionLabel>;
}
pub(crate) type BoxedRunCriterionLabel = Box<dyn RunCriterionLabel>;

macro_rules! impl_label {
($trait_name:ident) => {
impl PartialEq for dyn $trait_name {
Expand Down Expand Up @@ -106,3 +112,4 @@ macro_rules! impl_label {
impl_label!(StageLabel);
impl_label!(SystemLabel);
impl_label!(AmbiguitySetLabel);
impl_label!(RunCriterionLabel);
115 changes: 4 additions & 111 deletions crates/bevy_ecs/src/schedule/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod executor;
mod executor_parallel;
mod label;
mod run_criteria;
mod stage;
mod state;
mod system_container;
Expand All @@ -10,27 +11,24 @@ mod system_set;
pub use executor::*;
pub use executor_parallel::*;
pub use label::*;
pub use run_criteria::*;
pub use stage::*;
pub use state::*;
pub use system_container::*;
pub use system_descriptor::*;
pub use system_set::*;

use crate::{
archetype::{Archetype, ArchetypeComponentId},
component::ComponentId,
query::Access,
system::{BoxedSystem, IntoSystem, System, SystemId},
system::{IntoSystem, System},
world::World,
};
use bevy_utils::HashMap;
use std::borrow::Cow;

#[derive(Default)]
pub struct Schedule {
stages: HashMap<BoxedStageLabel, Box<dyn Stage>>,
stage_order: Vec<BoxedStageLabel>,
run_criteria: RunCriteria,
run_criteria: RunCriterion,
}

impl Schedule {
Expand Down Expand Up @@ -229,108 +227,3 @@ impl Stage for Schedule {
}
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ShouldRun {
/// Yes, the system should run.
Yes,
/// No, the system should not run.
No,
/// Yes, the system should run, and afterwards the criteria should be checked again.
YesAndCheckAgain,
/// No, the system should not run right now, but the criteria should be checked again later.
NoAndCheckAgain,
}

pub(crate) struct RunCriteria {
criteria_system: Option<BoxedSystem<(), ShouldRun>>,
initialized: bool,
}

impl Default for RunCriteria {
fn default() -> Self {
Self {
criteria_system: None,
initialized: false,
}
}
}

impl RunCriteria {
pub fn set(&mut self, criteria_system: BoxedSystem<(), ShouldRun>) {
self.criteria_system = Some(criteria_system);
self.initialized = false;
}

pub fn should_run(&mut self, world: &mut World) -> ShouldRun {
if let Some(ref mut run_criteria) = self.criteria_system {
if !self.initialized {
run_criteria.initialize(world);
self.initialized = true;
}
let should_run = run_criteria.run((), world);
run_criteria.apply_buffers(world);
should_run
} else {
ShouldRun::Yes
}
}
}

pub struct RunOnce {
ran: bool,
system_id: SystemId,
archetype_component_access: Access<ArchetypeComponentId>,
component_access: Access<ComponentId>,
}

impl Default for RunOnce {
fn default() -> Self {
Self {
ran: false,
system_id: SystemId::new(),
archetype_component_access: Default::default(),
component_access: Default::default(),
}
}
}

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

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

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

fn new_archetype(&mut self, _archetype: &Archetype) {}

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

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

fn is_send(&self) -> bool {
true
}

unsafe fn run_unsafe(&mut self, _input: Self::In, _world: &World) -> Self::Out {
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) {}
}
Loading