-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Opt out change detection #6659
Closed
Closed
Opt out change detection #6659
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
e272d94
Add Component::CHANGE_DETECTION_ENABLED
james7132 c7b2d7f
Extend Component derive macro
james7132 c7e2c2d
Update Component docs
james7132 fa32533
Add test for the macro changes
james7132 dc52dfd
Move ZST size check
james7132 9c3e2d7
Update docs
james7132 fa4cba4
Fix test
james7132 8043968
Fix CI
james7132 cc88d5d
Updated Added and Changed filters
james7132 51e5bc5
Add the same changes to Resource
james7132 971024c
Move test to change_detection.rs
james7132 df3c6db
Add (and fix) ZST change detection test
james7132 7c50c46
Cleanup
james7132 f777a9e
Merge branch 'main' into opt-out-change-detection
james7132 ce6fec7
Merge branch 'main' into opt-out-change-detection
james7132 55fab07
Split Mut impl
james7132 c485338
Use associated types instead of associated constants
james7132 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -2,22 +2,30 @@ use bevy_macro_utils::{get_lit_str, Symbol}; | |||||
use proc_macro::TokenStream; | ||||||
use proc_macro2::{Span, TokenStream as TokenStream2}; | ||||||
use quote::{quote, ToTokens}; | ||||||
use syn::{parse_macro_input, parse_quote, DeriveInput, Error, Ident, Path, Result}; | ||||||
use syn::{parse_macro_input, parse_quote, DeriveInput, Error, Ident, LitBool, Path, Result}; | ||||||
|
||||||
pub fn derive_resource(input: TokenStream) -> TokenStream { | ||||||
let mut ast = parse_macro_input!(input as DeriveInput); | ||||||
let bevy_ecs_path: Path = crate::bevy_ecs_path(); | ||||||
|
||||||
let attrs = match parse_resource_attrs(&ast) { | ||||||
Ok(attrs) => attrs, | ||||||
Err(e) => return e.into_compile_error().into(), | ||||||
}; | ||||||
|
||||||
ast.generics | ||||||
.make_where_clause() | ||||||
.predicates | ||||||
.push(parse_quote! { Self: Send + Sync + 'static }); | ||||||
|
||||||
let change_detection_enabled = LitBool::new(attrs.change_detection_enabled, Span::call_site()); | ||||||
|
||||||
let struct_name = &ast.ident; | ||||||
let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl(); | ||||||
|
||||||
TokenStream::from(quote! { | ||||||
impl #impl_generics #bevy_ecs_path::system::Resource for #struct_name #type_generics #where_clause { | ||||||
const CHANGE_DETECTION_ENABLED: bool = #change_detection_enabled; | ||||||
} | ||||||
}) | ||||||
} | ||||||
|
@@ -26,11 +34,16 @@ pub fn derive_component(input: TokenStream) -> TokenStream { | |||||
let mut ast = parse_macro_input!(input as DeriveInput); | ||||||
let bevy_ecs_path: Path = crate::bevy_ecs_path(); | ||||||
|
||||||
let attrs = match parse_component_attr(&ast) { | ||||||
let attrs = match parse_component_attrs(&ast) { | ||||||
Ok(attrs) => attrs, | ||||||
Err(e) => return e.into_compile_error().into(), | ||||||
}; | ||||||
|
||||||
let component_mut = if attrs.change_detection_enabled { | ||||||
quote! { #bevy_ecs_path::change_detection::Mut<'a, Self> } | ||||||
} else { | ||||||
quote! { &'a mut Self } | ||||||
}; | ||||||
let storage = storage_path(&bevy_ecs_path, attrs.storage); | ||||||
|
||||||
ast.generics | ||||||
|
@@ -43,18 +56,29 @@ pub fn derive_component(input: TokenStream) -> TokenStream { | |||||
|
||||||
TokenStream::from(quote! { | ||||||
impl #impl_generics #bevy_ecs_path::component::Component for #struct_name #type_generics #where_clause { | ||||||
type WriteFetch<'a> = #component_mut; | ||||||
type Storage = #storage; | ||||||
fn shrink<'wlong: 'wshort, 'wshort>(item: Self::WriteFetch<'wlong>) -> Self::WriteFetch<'wshort> { | ||||||
item | ||||||
} | ||||||
} | ||||||
}) | ||||||
} | ||||||
|
||||||
pub const COMPONENT: Symbol = Symbol("component"); | ||||||
pub const RESOURCE: Symbol = Symbol("resource"); | ||||||
pub const CHANGED_DETECTION: Symbol = Symbol("change_detection"); | ||||||
pub const STORAGE: Symbol = Symbol("storage"); | ||||||
|
||||||
struct Attrs { | ||||||
struct ComponentAttrs { | ||||||
change_detection_enabled: bool, | ||||||
storage: StorageTy, | ||||||
} | ||||||
|
||||||
struct ResourceAttrs { | ||||||
change_detection_enabled: bool, | ||||||
} | ||||||
|
||||||
#[derive(Clone, Copy)] | ||||||
enum StorageTy { | ||||||
Table, | ||||||
|
@@ -65,10 +89,11 @@ enum StorageTy { | |||||
const TABLE: &str = "Table"; | ||||||
const SPARSE_SET: &str = "SparseSet"; | ||||||
|
||||||
fn parse_component_attr(ast: &DeriveInput) -> Result<Attrs> { | ||||||
fn parse_component_attrs(ast: &DeriveInput) -> Result<ComponentAttrs> { | ||||||
let meta_items = bevy_macro_utils::parse_attrs(ast, COMPONENT)?; | ||||||
|
||||||
let mut attrs = Attrs { | ||||||
let mut attrs = ComponentAttrs { | ||||||
change_detection_enabled: true, | ||||||
storage: StorageTy::Table, | ||||||
}; | ||||||
|
||||||
|
@@ -93,6 +118,17 @@ fn parse_component_attr(ast: &DeriveInput) -> Result<Attrs> { | |||||
} | ||||||
}; | ||||||
} | ||||||
Meta(NameValue(m)) if m.path == CHANGED_DETECTION => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
attrs.change_detection_enabled = match m.lit { | ||||||
syn::Lit::Bool(value) => value.value, | ||||||
s => { | ||||||
return Err(Error::new_spanned( | ||||||
s, | ||||||
"Change detection must be a bool, expected 'true' or 'false'.", | ||||||
)) | ||||||
} | ||||||
}; | ||||||
} | ||||||
Meta(meta_item) => { | ||||||
return Err(Error::new_spanned( | ||||||
meta_item.path(), | ||||||
|
@@ -114,6 +150,51 @@ fn parse_component_attr(ast: &DeriveInput) -> Result<Attrs> { | |||||
Ok(attrs) | ||||||
} | ||||||
|
||||||
fn parse_resource_attrs(ast: &DeriveInput) -> Result<ResourceAttrs> { | ||||||
let meta_items = bevy_macro_utils::parse_attrs(ast, RESOURCE)?; | ||||||
|
||||||
let mut attrs = ResourceAttrs { | ||||||
change_detection_enabled: true, | ||||||
}; | ||||||
|
||||||
for meta in meta_items { | ||||||
use syn::{ | ||||||
Meta::NameValue, | ||||||
NestedMeta::{Lit, Meta}, | ||||||
}; | ||||||
match meta { | ||||||
Meta(NameValue(m)) if m.path == CHANGED_DETECTION => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
attrs.change_detection_enabled = match m.lit { | ||||||
syn::Lit::Bool(value) => value.value, | ||||||
s => { | ||||||
return Err(Error::new_spanned( | ||||||
s, | ||||||
"Change detection must be a bool, expected 'true' or 'false'.", | ||||||
)) | ||||||
} | ||||||
}; | ||||||
} | ||||||
Meta(meta_item) => { | ||||||
return Err(Error::new_spanned( | ||||||
meta_item.path(), | ||||||
format!( | ||||||
"unknown resource attribute `{}`", | ||||||
meta_item.path().into_token_stream() | ||||||
), | ||||||
)); | ||||||
} | ||||||
Lit(lit) => { | ||||||
return Err(Error::new_spanned( | ||||||
lit, | ||||||
"unexpected literal in resource attribute", | ||||||
)) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
Ok(attrs) | ||||||
} | ||||||
|
||||||
fn storage_path(bevy_ecs_path: &Path, ty: StorageTy) -> TokenStream2 { | ||||||
let typename = match ty { | ||||||
StorageTy::Table => Ident::new("TableStorage", Span::call_site()), | ||||||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.