#bevy-ecs #macro #bevy

macro mevy_ecs

bevy_ecs macros, simplifying child spawning and picking!

2 releases

new 0.1.1 Mar 9, 2025
0.1.0 Jan 9, 2025

#2433 in Procedural macros

Download history 154/week @ 2025-01-07 9/week @ 2025-01-14 1/week @ 2025-01-21 8/week @ 2025-02-04 11/week @ 2025-02-25 62/week @ 2025-03-04

73 downloads per month
Used in mevy

MIT/Apache

14KB
160 lines

This crate is part of mevy (tl;dr: more neat macros) so take a look! 🦆

A simpler way of spawning

The macro spawn!{..} allows you to spawn hierarchies with this patter:

spawn!{

    // add components:
    Node!; // '!' is short for ::default()
    Outline{
        width: 2px, // 'Val's can be written css-like
        offset: 10%,
    !}; // '!' in a struct is short for ..default()

    // using methods:
    .remove::<Node>();
    .observe(..);
    .queue(..);

    // spawn children
    [optional_child_name]
        // component;
        // .method(..);
    ]
}

A simpler way to use triggers on self, basically means goated event control:

spawn!{
    Node{ width:50px, height:50px, ..default()};
    BackgroundColor(#ff0000); 
    // Using '>'
    > Pointer<Click> {
        // Provided variables:
        // 'this' = EnitityCommands
        // 'event' = e.g. &Pointer<Click>
        this.despawn();
    }
    // Using '>>'
    >> Pointer<Click> {
        // Provided variables:
        // 'world' = mut World
        // 'entity' = Entity
        // 'event' = e.g. &Pointer<Click>
    }
}

This macro expects a mut world: Commands variable (or world: &mut Commands)

fn startup(mut world: Commands){
    spawn!{Camera2d::default()}
}

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, ...
spawn!{
    Component{ entity: named_child };
    [named_child][
        // components & methods
    ]
}

This is 'token based', which means it preserves LSP greatness.

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
spawn!{
    [[[[[[
        SpecificEntity(ancestors[3]);
    ]]]]]]
}

To use the macro on an existing entity: The first thing sould be &your_entity;, which can be anything that returns a nentity:

    let entity = Entity::PLACEHOLDER;
    spawn!{
        &entity; // & -> anything that returns an entity
        // ... further macro usage
    }

Synergies with mevy

Using mevy_core macro code!{}, you can pair it with code!{} to write Colors and Vals neater:

code!{spawn!{
    BackgroundColor(#ff0000);
    Node{ width:50px, height:10%, margin:[>5px], ..default() }
    [
        // child ui
    ]
}}

Using mevy_ui macro ui!{}, it's a bit like html/css:

spawn!{
    ui!((
        size: 5px;
        box_shadow: 1px 2px 3px 4px #ff0000;
        background: cyan;
    ));
    [inner_box][ui!((
        size: 80%;
        background: green;
    ))]
}

Dependencies

~0.8–1.4MB
~24K SLoC