Trait aery::operations::Join

source ·
pub trait Join<Item>
where Item: for<'a> Joinable<'a, 1>,
{ type Out<Edge: EdgeSide>; // Required method fn join<Edge: EdgeSide>(self, item: Item) -> Self::Out<Edge>; }
Expand description

Join multiple queries together via edges.

§Examples

§Simple join

use bevy::prelude::*;
use aery::prelude::*;

#[derive(Component)]
struct Pos(Vec2);

// Instancing geometry from vector graphics
#[derive(Component)]
struct DynamicMesh {
   // ..
}

#[derive(Relation)]
#[aery(Total)]
struct InstanceOf;

fn render_all_instances(
   meshes: Query<(&DynamicMesh, Relations<InstanceOf>)>,
   instances: Query<&Pos>,
) {
   for (mesh, edges) in meshes.iter() {
       edges.join::<InstanceOf>(&instances).for_each(|pos| {
           // Render mesh
       })
   }
}

// or join the other way aroind
fn render_in_view(
   camera: Query<&Camera>,
   meshes: Query<&DynamicMesh>,
   instances: Query<(&Pos, Relations<InstanceOf>)>,

) {
   for (pos, edges) in instances.iter() {
       // The API is still `for_each` but there will only be at most 1 match in this case
       // because edges are exclusive by default
       edges.join::<Up<InstanceOf>>(&meshes).for_each(|mesh| {
           if !in_camera_view() { return }
           // Draw mesh
       });
   }
}

§Multiple joins

use bevy::prelude::*;
use aery::prelude::*;

#[derive(Component)]
struct A(u32);

#[derive(Component)]
struct B(u32);

#[derive(Component)]
struct C(u32);

#[derive(Relation)]
struct R0;

#[derive(Relation)]
struct R1;

fn setup(world: &mut World) {
   let [a0, a1, a2] = std::array::from_fn(|n| world.spawn(A(n as u32)).id());

   world.spawn(B(0))
        .set::<R0>(a0);

   world.spawn_empty()
        .set::<R0>(a1);

   world.spawn(B(1))
        .set::<R0>(a2)
        .set::<R1>(a1);

   world.spawn(C(0))
        .set::<R1>(a0)
        .set::<R1>(a1);

   world.spawn(C(1))
        .set::<R1>(a0);

   world.spawn(C(2));

   world.spawn(C(3))
        .set::<R1>(a2);
}

fn sys(a: Query<(&A, Relations<(R0, R1)>)>, b: Query<&B>, c: Query<&C>) {
   for (a, edges) in a.iter() {
       // Iterates through permutations of matches
       edges.join::<R0>(&b).join::<R1>(&c).for_each(|(b, c)| {
           println!("A({}), B({}), C({})", a.0, b.0, c.0)
           // Prints:
           // A(0), B(0), C(0)
           // A(0), B(0), C(1)
           // A(2), B(1), C(3)
       });
   }
}

§Multiple join illustration:

flowchart BT B0 --R0--> A0 __ --R0--> A1 B1 --R0--> A2 B1 --R1--> A1 C0 --R1--> A0 C0 --R1--> A1 C1 --R1--> A0 C2 C3 --R1--> A2

Required Associated Types§

source

type Out<Edge: EdgeSide>

Required Methods§

source

fn join<Edge: EdgeSide>(self, item: Item) -> Self::Out<Edge>

Object Safety§

This trait is not object safe.

Implementors§

source§

impl<RI, Edges, Items, Item> Join<Item> for JoinWith<RI, Edges, Items>
where Item: for<'a> Joinable<'a, 1>, Edges: Append, Items: Append,

§

type Out<Edge: EdgeSide> = JoinWith<RI, <Edges as Append>::Out<Edge>, <Items as Append>::Out<Item>>

source§

impl<RS, Item> Join<Item> for &RelationsItem<'_, RS>
where RS: RelationSet, Item: for<'a> Joinable<'a, 1>,