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];`