Skip to main content

examples/queries/
query_pass_query_to_system.rs

1use crate::z_ignore_test_common::*;
2
3use flecs_ecs::prelude::*;
4
5#[derive(Debug, Component, Default)]
6pub struct Position {
7    pub x: i32,
8    pub y: i32,
9}
10
11#[derive(Debug, Component, Default)]
12pub struct Velocity {
13    pub x: i32,
14    pub y: i32,
15}
16
17fn main() {
18    let world = World::new();
19
20    world
21        .component::<Position>()
22        .add_trait::<flecs::Singleton>();
23
24    world.set(Position { x: 1, y: 2 });
25
26    let query = world
27        .query::<(&Position, &Velocity)>()
28        // setting it cached is important! otherwise the query will go out of scope since it's not associated with an entity
29        // uncached queries are meant to be shortlived, but faster to create in general. More dynamic in nature.
30        .set_cached()
31        .build();
32
33    world.entity().set(Velocity { x: 590, y: 20 });
34
35    // by using move, we can pass the query directly to the system because queries
36    // do not hold a lifetime, instead they are reference counted to give us the ability to pass them around.
37    let sys = world.system::<()>().run(move |it| {
38        let world = it.world();
39        query.run(|mut it| {
40            while it.next() {
41                let pos = &it.field::<&Position>(0)[0]; //singleton
42                let vel = it.field::<&Velocity>(1);
43                for i in it.iter() {
44                    println!("{:?}, {:?}", pos, vel[i]);
45                }
46            }
47        });
48    });
49
50    sys.run();
51
52    // Output:
53    //  Position { x: 1.0, y: 2.0 }, Velocity { x: 590.0, y: 20.0 }
54}
55
56#[cfg(feature = "flecs_nightly_tests")]
57#[test]
58fn test() {
59    let output_capture = OutputCapture::capture().unwrap();
60    main();
61    output_capture.test("query_pass_query_to_system".to_string());
62}