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] - Add upstream bevy_ecs and prepare for custom-shaders merge #2815

Closed
wants to merge 7 commits 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 0 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -365,10 +365,6 @@ path = "examples/ecs/system_sets.rs"
name = "timers"
path = "examples/ecs/timers.rs"

[[example]]
name = "query_bundle"
path = "examples/ecs/query_bundle.rs"

# Games
[[example]]
name = "alien_cake_addict"
Expand Down
4 changes: 0 additions & 4 deletions crates/bevy_ecs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
name = "bevy_ecs"
version = "0.5.0"
edition = "2018"
authors = [
"Bevy Contributors <bevyengine@gmail.com>",
"Carter Anderson <mcanders1@gmail.com>",
]
description = "Bevy Engine's entity component system"
homepage = "https://bevyengine.org"
repository = "https://github.com/bevyengine/bevy"
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ fn main() {
// Add a Stage to our schedule. Each Stage in a schedule runs all of its systems
// before moving on to the next Stage
schedule.add_stage("update", SystemStage::parallel()
.with_system(movement.system())
.with_system(movement)
);

// Run the schedule once. If your app has a "loop", you would run this once per loop
Expand Down
14 changes: 5 additions & 9 deletions crates/bevy_ecs/examples/change_detection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,11 @@ fn main() {

// Add systems to the Stage to execute our app logic
// We can label our systems to force a specific run-order between some of them
update.add_system(spawn_entities.system().label(SimulationSystem::Spawn));
update.add_system(
print_counter_when_changed
.system()
.after(SimulationSystem::Spawn),
);
update.add_system(age_all_entities.system().label(SimulationSystem::Age));
update.add_system(remove_old_entities.system().after(SimulationSystem::Age));
update.add_system(print_changed_entities.system().after(SimulationSystem::Age));
update.add_system(spawn_entities.label(SimulationSystem::Spawn));
update.add_system(print_counter_when_changed.after(SimulationSystem::Spawn));
update.add_system(age_all_entities.label(SimulationSystem::Age));
update.add_system(remove_old_entities.after(SimulationSystem::Age));
update.add_system(print_changed_entities.after(SimulationSystem::Age));
// Add the Stage with our systems to the Schedule
schedule.add_stage("update", update);

Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/examples/component_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ fn main() {
// Setup a schedule and stage to add a system querying for the just spawned entities
let mut schedule = Schedule::default();
let mut update = SystemStage::parallel();
update.add_system(query_entities.system());
update.add_system(query_entities);
schedule.add_stage("update", update);

schedule.run(&mut world);
Expand Down
12 changes: 7 additions & 5 deletions crates/bevy_ecs/examples/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ fn main() {
// called "second". In "first" we update the events and in "second" we run our systems
// sending and receiving events.
let mut first = SystemStage::parallel();
first.add_system(Events::<MyEvent>::update_system.system());
first.add_system(Events::<MyEvent>::update_system);
schedule.add_stage("first", first);

// Add systems sending and receiving events to a "second" Stage
let mut second = SystemStage::parallel();
second.add_system(sending_system.system().label(EventSystem::Sending));
second.add_system(receiving_system.system().after(EventSystem::Sending));
second.add_system(sending_system.label(EventSystem::Sending));
second.add_system(receiving_system.after(EventSystem::Sending));

// Run the "second" Stage after the "first" Stage, so our Events always get updated before we use them
schedule.add_stage_after("first", "second", second);
Expand All @@ -41,7 +41,6 @@ enum EventSystem {
}

// This is our event that we will send and receive in systems
#[derive(Debug)]
struct MyEvent {
pub message: String,
pub random_value: f32,
Expand All @@ -62,6 +61,9 @@ fn sending_system(mut event_writer: EventWriter<MyEvent>) {
// If an event is received it will be printed to the console
fn receiving_system(mut event_reader: EventReader<MyEvent>) {
for my_event in event_reader.iter() {
println!(" Received: {:?}", *my_event);
println!(
" Received message {:?}, with random value of {}",
my_event.message, my_event.random_value
);
}
}
4 changes: 2 additions & 2 deletions crates/bevy_ecs/examples/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ fn main() {
let mut update = SystemStage::parallel();

// Add systems to increase the counter and to print out the current value
update.add_system(increase_counter.system().label(CounterSystem::Increase));
update.add_system(print_counter.system().after(CounterSystem::Increase));
update.add_system(increase_counter.label(CounterSystem::Increase));
update.add_system(print_counter.after(CounterSystem::Increase));
schedule.add_stage("update", update);

for iteration in 1..=10 {
Expand Down
127 changes: 60 additions & 67 deletions crates/bevy_ecs/macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
extern crate proc_macro;

use bevy_macro_utils::{derive_label, BevyManifest};
use bevy_macro_utils::BevyManifest;
use proc_macro::TokenStream;
use proc_macro2::Span;
use proc_macro2::{Span, TokenStream as TokenStream2};
use quote::{format_ident, quote};
use syn::{
parse::{Parse, ParseStream},
parse_macro_input,
punctuated::Punctuated,
token::Comma,
Data, DataStruct, DeriveInput, Field, Fields, GenericParam, Ident, Index, Lifetime, LitInt,
Result, Token,
Data, DataStruct, DeriveInput, Field, Fields, GenericParam, Ident, Index, LitInt, Path, Result,
Token,
};

struct AllTuples {
Expand Down Expand Up @@ -110,15 +110,15 @@ pub fn derive_bundle(input: TokenStream) -> TokenStream {
.map(|field| &field.ty)
.collect::<Vec<_>>();

let mut field_type_infos = Vec::new();
let mut field_component_ids = Vec::new();
let mut field_get_components = Vec::new();
let mut field_from_components = Vec::new();
for ((field_type, is_bundle), field) in
field_type.iter().zip(is_bundle.iter()).zip(field.iter())
{
if *is_bundle {
field_type_infos.push(quote! {
type_info.extend(<#field_type as #ecs_path::bundle::Bundle>::type_info());
field_component_ids.push(quote! {
component_ids.extend(<#field_type as #ecs_path::bundle::Bundle>::component_ids(components));
});
field_get_components.push(quote! {
self.#field.get_components(&mut func);
Expand All @@ -127,8 +127,8 @@ pub fn derive_bundle(input: TokenStream) -> TokenStream {
#field: <#field_type as #ecs_path::bundle::Bundle>::from_components(&mut func),
});
} else {
field_type_infos.push(quote! {
type_info.push(#ecs_path::component::TypeInfo::of::<#field_type>());
field_component_ids.push(quote! {
component_ids.push(components.get_or_insert_id::<#field_type>());
});
field_get_components.push(quote! {
func((&mut self.#field as *mut #field_type).cast::<u8>());
Expand All @@ -147,10 +147,12 @@ pub fn derive_bundle(input: TokenStream) -> TokenStream {
TokenStream::from(quote! {
/// SAFE: TypeInfo is returned in field-definition-order. [from_components] and [get_components] use field-definition-order
unsafe impl #impl_generics #ecs_path::bundle::Bundle for #struct_name#ty_generics #where_clause {
fn type_info() -> Vec<#ecs_path::component::TypeInfo> {
let mut type_info = Vec::with_capacity(#field_len);
#(#field_type_infos)*
type_info
fn component_ids(
components: &mut #ecs_path::component::Components,
) -> Vec<#ecs_path::component::ComponentId> {
let mut component_ids = Vec::with_capacity(#field_len);
#(#field_component_ids)*
component_ids
}

#[allow(unused_variables, unused_mut, non_snake_case)]
Expand All @@ -174,51 +176,36 @@ fn get_idents(fmt_string: fn(usize) -> String, count: usize) -> Vec<Ident> {
.collect::<Vec<Ident>>()
}

fn get_lifetimes(fmt_string: fn(usize) -> String, count: usize) -> Vec<Lifetime> {
(0..count)
.map(|i| Lifetime::new(&fmt_string(i), Span::call_site()))
.collect::<Vec<Lifetime>>()
}

#[proc_macro]
pub fn impl_query_set(_input: TokenStream) -> TokenStream {
let mut tokens = TokenStream::new();
let max_queries = 4;
let queries = get_idents(|i| format!("Q{}", i), max_queries);
let filters = get_idents(|i| format!("F{}", i), max_queries);
let lifetimes = get_lifetimes(|i| format!("'q{}", i), max_queries);
let state_lifetimes = get_lifetimes(|i| format!("'qs{}", i), max_queries);
let mut query_fns = Vec::new();
let mut query_fn_muts = Vec::new();
for i in 0..max_queries {
let query = &queries[i];
let filter = &filters[i];
let lifetime = &lifetimes[i];
let state_lifetime = &state_lifetimes[i];
let fn_name = Ident::new(&format!("q{}", i), Span::call_site());
let fn_name_mut = Ident::new(&format!("q{}_mut", i), Span::call_site());
let index = Index::from(i);
query_fns.push(quote! {
pub fn #fn_name(&self) -> &Query<#lifetime, #state_lifetime, #query, #filter> {
&self.0.#index
}
});
query_fn_muts.push(quote! {
pub fn #fn_name_mut(&mut self) -> &mut Query<#lifetime, #state_lifetime, #query, #filter> {
&mut self.0.#index
pub fn #fn_name(&mut self) -> Query<'_, '_, #query, #filter> {
// SAFE: systems run without conflicts with other systems.
// Conflicting queries in QuerySet are not accessible at the same time
// QuerySets are guaranteed to not conflict with other SystemParams
unsafe {
Query::new(self.world, &self.query_states.#index, self.last_change_tick, self.change_tick)
}
}
});
}

for query_count in 1..=max_queries {
let query = &queries[0..query_count];
let filter = &filters[0..query_count];
let lifetime = &lifetimes[0..query_count];
let state_lifetime = &state_lifetimes[0..query_count];
let query_fn = &query_fns[0..query_count];
let query_fn_mut = &query_fn_muts[0..query_count];
tokens.extend(TokenStream::from(quote! {
impl<'s, #(#lifetime,)* #(#query: WorldQuery + 'static,)* #(#filter: WorldQuery + 'static,)*> SystemParam for QuerySet<(#(Query<#lifetime, 's, #query, #filter>,)*)>
impl<'w, 's, #(#query: WorldQuery + 'static,)* #(#filter: WorldQuery + 'static,)*> SystemParam for QuerySet<'w, 's, (#(QueryState<#query, #filter>,)*)>
where #(#filter::Fetch: FilterFetch,)*
{
type Fetch = QuerySetState<(#(QueryState<#query, #filter>,)*)>;
Expand Down Expand Up @@ -271,10 +258,10 @@ pub fn impl_query_set(_input: TokenStream) -> TokenStream {
fn default_config() {}
}

impl<'s, 'w, #(#query: WorldQuery + 'static,)* #(#filter: WorldQuery + 'static,)*> SystemParamFetch<'s, 'w> for QuerySetState<(#(QueryState<#query, #filter>,)*)>
impl<'w, 's, #(#query: WorldQuery + 'static,)* #(#filter: WorldQuery + 'static,)*> SystemParamFetch<'w, 's> for QuerySetState<(#(QueryState<#query, #filter>,)*)>
where #(#filter::Fetch: FilterFetch,)*
{
type Item = QuerySet<(#(Query<'w, 's, #query, #filter>,)*)>;
type Item = QuerySet<'w, 's, (#(QueryState<#query, #filter>,)*)>;

#[inline]
unsafe fn get_param(
Expand All @@ -283,15 +270,18 @@ pub fn impl_query_set(_input: TokenStream) -> TokenStream {
world: &'w World,
change_tick: u32,
) -> Self::Item {
let (#(#query,)*) = &state.0;
QuerySet((#(Query::new(world, #query, system_meta.last_change_tick, change_tick),)*))
QuerySet {
query_states: &state.0,
world,
last_change_tick: system_meta.last_change_tick,
change_tick,
}
}
}

impl<#(#state_lifetime,)* #(#lifetime,)* #(#query: WorldQuery,)* #(#filter: WorldQuery,)*> QuerySet<(#(Query<#lifetime, #state_lifetime, #query, #filter>,)*)>
impl<'w, 's, #(#query: WorldQuery,)* #(#filter: WorldQuery,)*> QuerySet<'w, 's, (#(QueryState<#query, #filter>,)*)>
where #(#filter::Fetch: FilterFetch,)*
{
#(#query_fn)*
#(#query_fn_mut)*
}
}));
Expand Down Expand Up @@ -385,7 +375,7 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {

TokenStream::from(quote! {
impl #impl_generics #path::system::SystemParam for #struct_name#ty_generics #where_clause {
type Fetch = #fetch_struct_name <(#(<#field_types as SystemParam>::Fetch,)*), #punctuated_generic_idents>;
type Fetch = #fetch_struct_name <(#(<#field_types as #path::system::SystemParam>::Fetch,)*), #punctuated_generic_idents>;
}

#[doc(hidden)]
Expand Down Expand Up @@ -416,7 +406,7 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
}
}

impl #impl_generics #path::system::SystemParamFetch<'s, 'w> for #fetch_struct_name <(#(<#field_types as SystemParam>::Fetch,)*), #punctuated_generic_idents> {
impl #impl_generics #path::system::SystemParamFetch<'w, 's> for #fetch_struct_name <(#(<#field_types as #path::system::SystemParam>::Fetch,)*), #punctuated_generic_idents> {
type Item = #struct_name#ty_generics;
unsafe fn get_param(
state: &'s mut Self,
Expand All @@ -425,7 +415,7 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
change_tick: u32,
) -> Self::Item {
#struct_name {
#(#fields: <<#field_types as SystemParam>::Fetch as #path::system::SystemParamFetch>::get_param(&mut state.state.#field_indices, system_meta, world, change_tick),)*
#(#fields: <<#field_types as #path::system::SystemParam>::Fetch as #path::system::SystemParamFetch>::get_param(&mut state.state.#field_indices, system_meta, world, change_tick),)*
#(#ignored_fields: <#ignored_field_types>::default(),)*
}
}
Expand All @@ -436,43 +426,46 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
#[proc_macro_derive(SystemLabel)]
pub fn derive_system_label(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let mut trait_path = bevy_ecs_path();
trait_path.segments.push(format_ident!("schedule").into());
trait_path
.segments
.push(format_ident!("SystemLabel").into());
derive_label(input, trait_path)

derive_label(input, Ident::new("SystemLabel", Span::call_site())).into()
}

#[proc_macro_derive(StageLabel)]
pub fn derive_stage_label(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let mut trait_path = bevy_ecs_path();
trait_path.segments.push(format_ident!("schedule").into());
trait_path.segments.push(format_ident!("StageLabel").into());
derive_label(input, trait_path)
derive_label(input, Ident::new("StageLabel", Span::call_site())).into()
}

#[proc_macro_derive(AmbiguitySetLabel)]
pub fn derive_ambiguity_set_label(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let mut trait_path = bevy_ecs_path();
trait_path.segments.push(format_ident!("schedule").into());
trait_path
.segments
.push(format_ident!("AmbiguitySetLabel").into());
derive_label(input, trait_path)
derive_label(input, Ident::new("AmbiguitySetLabel", Span::call_site())).into()
}

#[proc_macro_derive(RunCriteriaLabel)]
pub fn derive_run_criteria_label(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let mut trait_path = bevy_ecs_path();
trait_path.segments.push(format_ident!("schedule").into());
trait_path
.segments
.push(format_ident!("RunCriteriaLabel").into());
derive_label(input, trait_path)
derive_label(input, Ident::new("RunCriteriaLabel", Span::call_site())).into()
}

fn derive_label(input: DeriveInput, label_type: Ident) -> TokenStream2 {
let ident = input.ident;
let ecs_path: Path = bevy_ecs_path();

let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let mut where_clause = where_clause.cloned().unwrap_or_else(|| syn::WhereClause {
where_token: Default::default(),
predicates: Default::default(),
});
where_clause.predicates.push(syn::parse2(quote! { Self: Eq + ::std::fmt::Debug + ::std::hash::Hash + Clone + Send + Sync + 'static }).unwrap());

quote! {
impl #impl_generics #ecs_path::schedule::#label_type for #ident #ty_generics #where_clause {
fn dyn_clone(&self) -> Box<dyn #ecs_path::schedule::#label_type> {
Box::new(Clone::clone(self))
}
}
}
}

fn bevy_ecs_path() -> syn::Path {
Expand Down