Skip to content

Commit a5ec9c0

Browse files
maniwanijames7132hymm
committed
Add bevy_ecs::schedule_v3 module (#6587)
# Objective Complete the first part of the migration detailed in bevyengine/rfcs#45. ## Solution Add all the new stuff. ### TODO - [x] Impl tuple methods. - [x] Impl chaining. - [x] Port ambiguity detection. - [x] Write docs. - [x] ~~Write more tests.~~(will do later) - [ ] Write changelog and examples here? - [x] ~~Replace `petgraph`.~~ (will do later) Co-authored-by: james7132 <contact@jamessliu.com> Co-authored-by: Michael Hsu <mike.hsu@gmail.com> Co-authored-by: Mike Hsu <mike.hsu@gmail.com>
1 parent 6b4795c commit a5ec9c0

25 files changed

+4053
-7
lines changed

crates/bevy_ecs/macros/src/lib.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ mod component;
44
mod fetch;
55

66
use crate::fetch::derive_world_query_impl;
7-
use bevy_macro_utils::{derive_label, get_named_struct_fields, BevyManifest};
7+
use bevy_macro_utils::{
8+
derive_boxed_label, derive_label, derive_set, get_named_struct_fields, BevyManifest,
9+
};
810
use proc_macro::TokenStream;
911
use proc_macro2::Span;
1012
use quote::{format_ident, quote};
@@ -565,6 +567,32 @@ pub fn derive_run_criteria_label(input: TokenStream) -> TokenStream {
565567
derive_label(input, &trait_path, "run_criteria_label")
566568
}
567569

570+
/// Derive macro generating an impl of the trait `ScheduleLabel`.
571+
#[proc_macro_derive(ScheduleLabel)]
572+
pub fn derive_schedule_label(input: TokenStream) -> TokenStream {
573+
let input = parse_macro_input!(input as DeriveInput);
574+
let mut trait_path = bevy_ecs_path();
575+
trait_path
576+
.segments
577+
.push(format_ident!("schedule_v3").into());
578+
trait_path
579+
.segments
580+
.push(format_ident!("ScheduleLabel").into());
581+
derive_boxed_label(input, &trait_path)
582+
}
583+
584+
/// Derive macro generating an impl of the trait `SystemSet`.
585+
#[proc_macro_derive(SystemSet)]
586+
pub fn derive_system_set(input: TokenStream) -> TokenStream {
587+
let input = parse_macro_input!(input as DeriveInput);
588+
let mut trait_path = bevy_ecs_path();
589+
trait_path
590+
.segments
591+
.push(format_ident!("schedule_v3").into());
592+
trait_path.segments.push(format_ident!("SystemSet").into());
593+
derive_set(input, &trait_path)
594+
}
595+
568596
pub(crate) fn bevy_ecs_path() -> syn::Path {
569597
BevyManifest::default().get_path("bevy_ecs")
570598
}

crates/bevy_ecs/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub mod query;
1414
#[cfg(feature = "bevy_reflect")]
1515
pub mod reflect;
1616
pub mod schedule;
17+
pub mod schedule_v3;
1718
pub mod storage;
1819
pub mod system;
1920
pub mod world;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
pub use common_conditions::*;
2+
3+
use crate::system::BoxedSystem;
4+
5+
pub type BoxedCondition = BoxedSystem<(), bool>;
6+
7+
/// A system that determines if one or more scheduled systems should run.
8+
///
9+
/// Implemented for functions and closures that convert into [`System<In=(), Out=bool>`](crate::system::System)
10+
/// with [read-only](crate::system::ReadOnlySystemParam) parameters.
11+
pub trait Condition<Params>: sealed::Condition<Params> {}
12+
13+
impl<Params, F> Condition<Params> for F where F: sealed::Condition<Params> {}
14+
15+
mod sealed {
16+
use crate::system::{IntoSystem, IsFunctionSystem, ReadOnlySystemParam, SystemParamFunction};
17+
18+
pub trait Condition<Params>: IntoSystem<(), bool, Params> {}
19+
20+
impl<Params, Marker, F> Condition<(IsFunctionSystem, Params, Marker)> for F
21+
where
22+
F: SystemParamFunction<(), bool, Params, Marker> + Send + Sync + 'static,
23+
Params: ReadOnlySystemParam + 'static,
24+
Marker: 'static,
25+
{
26+
}
27+
}
28+
29+
mod common_conditions {
30+
use crate::schedule_v3::{State, States};
31+
use crate::system::{Res, Resource};
32+
33+
/// Generates a [`Condition`](super::Condition)-satisfying closure that returns `true`
34+
/// if the resource exists.
35+
pub fn resource_exists<T>() -> impl FnMut(Option<Res<T>>) -> bool
36+
where
37+
T: Resource,
38+
{
39+
move |res: Option<Res<T>>| res.is_some()
40+
}
41+
42+
/// Generates a [`Condition`](super::Condition)-satisfying closure that returns `true`
43+
/// if the resource is equal to `value`.
44+
///
45+
/// # Panics
46+
///
47+
/// The condition will panic if the resource does not exist.
48+
pub fn resource_equals<T>(value: T) -> impl FnMut(Res<T>) -> bool
49+
where
50+
T: Resource + PartialEq,
51+
{
52+
move |res: Res<T>| *res == value
53+
}
54+
55+
/// Generates a [`Condition`](super::Condition)-satisfying closure that returns `true`
56+
/// if the resource exists and is equal to `value`.
57+
///
58+
/// The condition will return `false` if the resource does not exist.
59+
pub fn resource_exists_and_equals<T>(value: T) -> impl FnMut(Option<Res<T>>) -> bool
60+
where
61+
T: Resource + PartialEq,
62+
{
63+
move |res: Option<Res<T>>| match res {
64+
Some(res) => *res == value,
65+
None => false,
66+
}
67+
}
68+
69+
/// Generates a [`Condition`](super::Condition)-satisfying closure that returns `true`
70+
/// if the state machine exists.
71+
pub fn state_exists<S: States>() -> impl FnMut(Option<Res<State<S>>>) -> bool {
72+
move |current_state: Option<Res<State<S>>>| current_state.is_some()
73+
}
74+
75+
/// Generates a [`Condition`](super::Condition)-satisfying closure that returns `true`
76+
/// if the state machine is currently in `state`.
77+
///
78+
/// # Panics
79+
///
80+
/// The condition will panic if the resource does not exist.
81+
pub fn state_equals<S: States>(state: S) -> impl FnMut(Res<State<S>>) -> bool {
82+
move |current_state: Res<State<S>>| current_state.0 == state
83+
}
84+
85+
/// Generates a [`Condition`](super::Condition)-satisfying closure that returns `true`
86+
/// if the state machine exists and is currently in `state`.
87+
///
88+
/// The condition will return `false` if the state does not exist.
89+
pub fn state_exists_and_equals<S: States>(
90+
state: S,
91+
) -> impl FnMut(Option<Res<State<S>>>) -> bool {
92+
move |current_state: Option<Res<State<S>>>| match current_state {
93+
Some(current_state) => current_state.0 == state,
94+
None => false,
95+
}
96+
}
97+
}

0 commit comments

Comments
 (0)