diff --git a/crates/bevy_ecs/macros/src/component.rs b/crates/bevy_ecs/macros/src/component.rs index 8a78355a60..1322022581 100644 --- a/crates/bevy_ecs/macros/src/component.rs +++ b/crates/bevy_ecs/macros/src/component.rs @@ -115,6 +115,7 @@ pub fn derive_resource(input: TokenStream) -> TokenStream { }) } +/// Component derive syntax is documented on both the macro and the trait. 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(); @@ -453,7 +454,11 @@ pub const MAP_ENTITIES: &str = "map_entities"; pub const IMMUTABLE: &str = "immutable"; pub const CLONE_BEHAVIOR: &str = "clone_behavior"; -/// All allowed attribute value expression kinds for component hooks +/// All allowed attribute value expression kinds for component hooks. +/// This doesn't simply use general expressions because of conflicting needs: +/// - we want to be able to use `Self` & generic parameters in paths +/// - call expressions producing a closure need to be wrapped in a function +/// to turn them into function pointers, which prevents access to the outer generic params #[derive(Debug)] enum HookAttributeKind { /// expressions like function or struct names diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index 9bc3e5913e..20f7ad4275 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -560,7 +560,17 @@ pub fn derive_event(input: TokenStream) -> TokenStream { component::derive_event(input) } -/// Implement the `EntityEvent` trait. +/// Cheat sheet for derive syntax, +/// see full explanation on `EntityEvent` trait docs. +/// +/// ```ignore +/// #[derive(Event, EntityEvent)] +/// /// Traversal component +/// #[entity_event(traversal = &'static ChildOf)] +/// /// Always propagate +/// #[entity_event(auto_propagate)] +/// struct MyEvent; +/// ``` #[proc_macro_derive(EntityEvent, attributes(entity_event))] pub fn derive_entity_event(input: TokenStream) -> TokenStream { component::derive_entity_event(input) @@ -578,7 +588,89 @@ pub fn derive_resource(input: TokenStream) -> TokenStream { component::derive_resource(input) } -/// Implement the `Component` trait. +/// Cheat sheet for derive syntax, +/// see full explanation and examples on the `Component` trait doc. +/// +/// ## Immutability +/// ```ignore +/// #[derive(Component)] +/// #[component(immutable)] +/// struct MyComponent; +/// ``` +/// +/// ## Sparse instead of table-based storage +/// ```ignore +/// #[derive(Component)] +/// #[component(storage = "SparseSet")] +/// struct MyComponent; +/// ``` +/// +/// ## Required Components +/// +/// ```ignore +/// #[derive(Component)] +/// #[require( +/// // `Default::default()` +/// A, +/// // tuple structs +/// B(1), +/// // named-field structs +/// C { +/// x: 1, +/// ..default() +/// }, +/// // unit structs/variants +/// D::One, +/// // associated consts +/// E::ONE, +/// // constructors +/// F::new(1), +/// // arbitrary expressions +/// G = make(1, 2, 3) +/// )] +/// struct MyComponent; +/// ``` +/// +/// ## Relationships +/// ```ignore +/// #[derive(Component)] +/// #[relationship(relationship_target = Children)] +/// pub struct ChildOf { +/// // Marking the field is not necessary if there is only one. +/// #[relationship] +/// pub parent: Entity, +/// internal: u8, +/// }; +/// +/// #[derive(Component)] +/// #[relationship_target(relationship = ChildOf)] +/// pub struct Children(Vec); +/// ``` +/// +/// On despawn, also despawn all related entities: +/// ```ignore +/// #[derive(Component)] +/// #[relationship_target(relationship_target = Children, linked_spawn)] +/// pub struct Children(Vec); +/// ``` +/// +/// ## Hooks +/// ```ignore +/// #[derive(Component)] +/// #[component(hook_name = function)] +/// struct MyComponent; +/// ``` +/// where `hook_name` is `on_add`, `on_insert`, `on_replace` or `on_remove`; +/// `function` can be either a path, e.g. `some_function::`, +/// or a function call that returns a function that can be turned into +/// a `ComponentHook`, e.g. `get_closure("Hi!")`. +/// +/// ## Ignore this component when cloning an entity +/// ```ignore +/// #[derive(Component)] +/// #[component(clone_behavior = Ignore)] +/// struct MyComponent; +/// ``` #[proc_macro_derive( Component, attributes(component, require, relationship, relationship_target, entities)