Skip to main content

examples/queries/
query_group_iter.rs

1#![allow(non_camel_case_types)]
2use crate::z_ignore_test_common::*;
3
4use flecs_ecs::prelude::*;
5// A group iterator iterates over a single group of a grouped query (see the
6// group_by example for more details). This can be useful when an application
7// may need to match different entities based on the context of the game, such
8// as editor mode, day/night, inside/outside or location in the world.
9//
10// One example is that of an open game which is divided up into world
11// cells. Even though a world may contain many entities, only the entities in
12// cells close to the player need to be processed.
13//
14// Instead of creating a cached query per world cell, which could be expensive
15// as there are more caches to keep in sync, applications can create a single
16// query grouped by world cell, and use group iterators to only iterate the
17// necessary cells.
18
19// A world cell relationship with four cells
20
21#[derive(Debug, Component)]
22struct WorldCell;
23
24#[derive(Debug, Component)]
25struct Cell_0_0;
26
27#[derive(Debug, Component)]
28struct Cell_0_1;
29
30#[derive(Debug, Component)]
31struct Cell_1_0;
32
33#[derive(Debug, Component)]
34struct Cell_1_1;
35
36// Npc tags
37#[derive(Debug, Component)]
38struct Npc;
39
40#[derive(Debug, Component)]
41struct Merchant;
42
43#[derive(Debug, Component)]
44struct Soldier;
45
46#[derive(Debug, Component)]
47struct Beggar;
48
49#[derive(Debug, Component)]
50struct Mage;
51
52fn main() {
53    let world = World::new();
54
55    // Create npc's in world cell 0_0
56    world
57        .entity()
58        .add((WorldCell, Cell_0_0))
59        .add(Merchant)
60        .add(Npc);
61    world
62        .entity()
63        .add((WorldCell, Cell_0_0))
64        .add(Merchant)
65        .add(Npc);
66
67    // Create npc's in world cell 0_1
68    world
69        .entity()
70        .add((WorldCell, Cell_0_1))
71        .add(Beggar)
72        .add(Npc);
73    world
74        .entity()
75        .add((WorldCell, Cell_0_1))
76        .add(Soldier)
77        .add(Npc);
78
79    // Create npc's in world cell 1_0
80    world.entity().add((WorldCell, Cell_1_0)).add(Mage).add(Npc);
81    world
82        .entity()
83        .add((WorldCell, Cell_1_0))
84        .add(Beggar)
85        .add(Npc);
86
87    // Create npc's in world cell 1_1
88    world
89        .entity()
90        .add((WorldCell, Cell_1_1))
91        .add(Soldier)
92        .add(Npc);
93
94    let mut query = world.query::<()>().with(&Npc).group_by(WorldCell).build();
95
96    // Iterate all tables
97    println!("All tables");
98
99    query.run(|mut iter| {
100        while iter.next() {
101            let group = world.entity_from_id(iter.group_id());
102            println!(
103                "group: {:?} - Table [{}]",
104                group.path().unwrap(),
105                iter.table().unwrap().to_string().unwrap()
106            );
107        }
108    });
109
110    println!();
111
112    println!("Tables for cell 1_0:");
113
114    query.set_group(Cell_1_0).run(|mut iter| {
115        while iter.next() {
116            let world = iter.world();
117            let group = world.entity_from_id(iter.group_id());
118            println!(
119                "group: {:?} - Table [{}]",
120                group.path().unwrap(),
121                iter.table().unwrap().to_string().unwrap()
122            );
123        }
124    });
125
126    // Output:
127    //  All tables
128    //  group: "::Cell_0_0" - Table [Merchant, Npc, (WorldCell,Cell_0_0)]
129    //  group: "::Cell_0_1" - Table [Npc, Beggar, (WorldCell,Cell_0_1)]
130    //  group: "::Cell_0_1" - Table [Npc, Soldier, (WorldCell,Cell_0_1)]
131    //  group: "::Cell_1_0" - Table [Npc, Mage, (WorldCell,Cell_1_0)]
132    //  group: "::Cell_1_0" - Table [Npc, Beggar, (WorldCell,Cell_1_0)]
133    //  group: "::Cell_1_1" - Table [Npc, Soldier, (WorldCell,Cell_1_1)]
134
135    //  Tables for cell 1_0:
136    //  group: "::Cell_1_0" - Table [Npc, Mage, (WorldCell,Cell_1_0)]
137    //  group: "::Cell_1_0" - Table [Npc, Beggar, (WorldCell,Cell_1_0)]
138}
139
140#[cfg(feature = "flecs_nightly_tests")]
141#[test]
142fn test() {
143    let output_capture = OutputCapture::capture().unwrap();
144    main();
145    output_capture.test("query_group_iter".to_string());
146}