Giter VIP home page Giter VIP logo

bevy-trait-query's Introduction

bevy-trait-query

An implementation of trait queries for the bevy game engine.

Before using this crate, you should be familiar with bevy: https://bevyengine.org/.

Bevy Version Crate Version
0.13 0.5
0.12 0.4
0.11 0.3
0.10 0.2
0.9 0.1
0.8 0.0.3
Preview Main branch

Note on reliability

While this crate has seen some use in the world with no issues yet, it is still quite new and experimental. Use with caution (and miri!).

If you find a bug, please open an issue.

Overview

Let's say you have a trait that you want to implement for some of your components.

/// Components that display a message when hovered.
pub trait Tooltip {
    /// Text displayed when hovering over an entity with this trait.
    fn tooltip(&self) -> &str;
}

In order to be useful within bevy, you'll want to be able to query for this trait.

// Just add this attribute...
#[bevy_trait_query::queryable]
pub trait Tooltip {
    fn tooltip(&self) -> &str;
}

// ...and now you can use your trait in queries.
fn show_tooltips_system(
    tooltips: Query<&dyn Tooltip>,
    // ...
) {
    // ...
}

Since Rust unfortunately lacks any kind of reflection, it is necessary to register each component with the trait when the app gets built.

#[derive(Component)]
struct Player(String);

#[derive(Component)]
enum Villager {
    Farmer,
    // ...
}

#[derive(Component)]
struct Monster;

/* ...trait implementations omitted for brevity... */

struct TooltipPlugin;

impl Plugin for TooltipPlugin {
    fn build(&self, app: &mut App) {
        // We must import this trait in order to register our components.
        // If we don't register them, they will be invisible to the game engine.
        use bevy_trait_query::RegisterExt;

        app
            .register_component_as::<dyn Tooltip, Player>()
            .register_component_as::<dyn Tooltip, Villager>()
            .register_component_as::<dyn Tooltip, Monster>()
            .add_systems(Update, show_tooltips);
    }
}

Unlike queries for concrete types, it's possible for an entity to have multiple components that match a trait query.

fn show_tooltips(
    tooltips: Query<&dyn Tooltip>,
    // ...
) {
    // Iterate over each entity that has tooltips.
    for entity_tooltips in &tooltips {
        // Iterate over each component implementing `Tooltip` for the current entity.
        for tooltip in entity_tooltips {
            println!("Tooltip: {}", tooltip.tooltip());
        }
    }

    // If you instead just want to iterate over all tooltips, you can do:
    for tooltip in tooltips.iter().flatten() {
        println!("Tooltip: {}", tooltip.tooltip());
    }
}

Alternatively, if you expect to only have component implementing the trait for each entity, you can use the filter One. This has significantly better performance than iterating over all trait impls.

use bevy_trait_query::One;

fn show_tooltips(
    tooltips: Query<One<&dyn Tooltip>>,
    // ...
) {
    for tooltip in &tooltips {
        println!("Tooltip: {}", tooltip.tooltip());
    }
}

Performance

The performance of trait queries is quite competitive. Here are some benchmarks for simple cases:

Concrete type One All
1 match 16.135 µs 31.441 µs 63.273 µs
2 matches 17.501 µs - 102.83 µs
1-2 matches - 16.959 µs 82.179 µs

License

MIT or APACHE-2.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.