These are ONLY proc-macros (no additional traits, structs, fns etc.). This crate is part of [mevy](https://github.com/dekirisu/mevy) (tl;dr: more neat macros) so take a look! 🦆 ## Setup Multiple bevy versions are supported and managed by features: ```toml # bevy 0.17 mevy_ecs = {version="0.2",features=["0.17"]} # bevy 0.16 mevy_ecs = {version="0.2",features=["0.16"]} # bevy 0.15 mevy_ecs = {version="0.2",features=["0.15"]} ``` # Rough Overview ```rust entity!{ <..> // World/Entity Selection Bundle::new(..); // Insert Bundle to Selected .observe(..); // Use a method {..} // Free code block w/ 'this: EntityCommands' > Pointer{..} // Quick Observe w/ 'this: EntityCommands' >> Pointer{..} // Quick Observe w/ 'world: World', 'entity: Entity' [ // Spawn a Child Bundle::new(..); // Insert Bundle to Child .observe(..); // Use method on Childs EnitityCommands/EntityWorldMut {ancestors[0]} // ancestors: Vec // first = parent, last = 'selected root' ] [named_child][ // Spawn a Child with a name // .. ] } ``` # Alternative Syntax ```rust entity!{ <..> Bundle!; // = Bundle::default(); Bundle{a:3,!}; // = Bundle{a:3,..default()}; Bundle: 3; // = Bundle::new(3); bundle_fn: 3; // = bundle_fn(3); macro!: 3, 4; // = macro!{3,4}; .method: 5; // = .macro(5); // any plain Hex-Code = [Color] BorderColor(#ff0000); // css like [Val]s Node{ left: 10px; top: 5%; width: 3vw; height: 6vmax; !}; } ``` # World/Entity Selection The first entry of the macro determines which world access is used and which entity is aimed. ```rust entity!{ // SPAWN an entity using this [Commands] // (no entry) assumes a 'world: Commands' // MODIFY an entity: pass a Commands | Entity <|enty> // assumes a 'world: Commands' // assumes a 'me: Entity' <|> // assumes both <+world> // SPAWN using this [World] <+world|..> // MODIFY using this [World] <+> <+|..> // assumes a 'world: World' <-world> // SPAWN using this [DeferredWorld] <-world|..> // MODIFY using this [DeferredWorld] <-> <-|..> // assumes a 'world: DeferredWorld' <*this> // MODIFY using this [EntityCommands] <*> // assumes a 'world: EntityCommands' <> // assumes a 'this: EntityCommands' <^this> // MODIFY the parent of a [ChildBuilder] <^> // assumes a 'world: ChildBuilder' <+*this> // MODIFY using this [EntityWorldMut] <+*> // assumes a 'world: EntityWorldMut' <|#Comp> // target EVERY entity with this component <|#Comp.get()> // ..or an [Option] of the component <|#*Comp.all()> // ..or any iterator over [Entity]s <|!#Comp> // target THE ONLY (.single()) entity, enables 'leaking' <|!#Comp.0> // ..or an [Entity] on the component <|@Comp.get()> // target an [Option] on a resource <|@*Comp.all()> // ..or any iterator over [Entity]s <|!@Comp.0> // target an [Entity] on a resource, enables 'leaking' } ``` # Redirection After the initial selection of entities, you can redirect it to entities of a component. This expects: `.>` or `.!` (mind the '!'). ```rust entity!{ // select: every Entity with [Marker] // > select: first child, if available // >> select all children Visibility::Hidden; // hide all of them .despawn(); // despawn all of them } ``` # Leaking / Returning If the selector can 'leak' entities, you can use one of those symbold a the END of the macro: - `>` 'leak': every spawned entity is available in this scope - `<` 'return': returns the root entity ```rust let enty = entity!{ Bundle::new(5); <}; entity!{ Bundle::new(5); [] [named][] >} me; // the spawned entity e1; // the unnamed child entity named // the named child entity entity!{ <|!#Comp> [named][] >} named // resource/component selectors only leak children ``` ## Quick Observe A simpler way to use triggers on self, basically means goated event control: ```rust spawn!{ // Using '>' > Pointer { // Provided variables: // 'this' = EnitityCommands // 'event' = e.g. &Pointer this.despawn(); } // Using '>>' >> Pointer { // Provided variables: // 'world' = mut World // 'entity' = Entity // 'event' = e.g. &Pointer } } ``` ```rust fn startup(mut world: Commands){ spawn!{Camera2d::default()} } ``` # Child Names The 'Child Names' are variables containing the child entity. - Inside the macro they can be used anywhere, even 'before' you wrote them - If none is provided - one will be generated: `e{number}`: `e0`, `e1`, ... ```rust spawn!{ Component{ entity: named_child }; [named_child][ // components & methods ] } ``` This is 'token based', which means it preserves LSP greatness. ```rust spawn!{ // typing . will fire LSPs autocomplete .obs // would suggest 'observer' } ``` Easy way to address `ancestors` through a provided array, created within a macro call: - first entry: the direct parent - last entry: root entity of the current macro call ```rust spawn!{ [[[[[[ SpecificEntity(ancestors[3]); ]]]]]] } ``` ## Example Combining the things you could write thing like this: ```rust fn startup(mut world: Commands){ entity!{ Name: "Root"; Node{ padding:10px, !}; BackgroundColor(#ff0000); Marker; [nice_text][ Name: "Some Name"; Text: "Hello World"; > Pointer {this.despawn();}; ] } } ``` And modify it by a marker: ```rust fn update(mut world:Commands){ entity!{ <|#Marker> BackgroundColor(#00ff00); } } ``` ## Synergies with [mevy](https://github.com/dekirisu/mevy) Using `mevy_ui` macro `ui!{}`, it's a bit like html/css: ```rust spawn!{ ui!(( size: 5px; box_shadow: 1px 2px 3px 4px #ff0000; background: cyan; )); [inner_box][ui!(( size: 80%; background: green; ))] } ``` # Experimental Macros I use but are very bare-bone and might change a lot quckly. ## Alternative Macros Macros are split into the base accessors: - `cen![..]`: C(ommand) En(tity) - `den![..]`: D(eferredWorld) En(tity) - `wen![..]`: W(orld) En(tity) The Entity accessors change to: - `cen![..]`: spawn a `me: Entity` - `cen![&..]`: edit a `me: Entity` - `cen![*..]: edit a `world: EntityCommands` - `cen![#Marker|..]: edit all Entities with `Marker` component ## Get Resource Get Resource - required: mutable `world: World|DeferredWorld` - ref: `let time = gere![Time].unwrap();` - mut: `let mut time = gere![mut Time].unwrap();` ## Edit Resource Quickly Edit Resource (if available) - required: mutable `world: World|DeferredWorld` - usage: `gere![Struct.field = 100];` ## Get Component Get Component - required: mutable `world: World|DeferredWorld` - required: `me: Entity` - ref: `let time = geco![Time].unwrap();` - mut: `let mut time = geco![mut Time].unwrap();` - cloned: `let time = geco![Time*].unwrap();` - has?: `if geco![Time?] {}` ## Edit Component Quickly Edit Components (if available) - required: mutable `world: World|DeferredWorld` - usage: `geco![Struct.field = 100];`