examples/queries/
query_group_by_callbacks.rs1use crate::z_ignore_test_common::*;
2
3use core::ffi::c_void;
4use flecs_ecs::prelude::*;
5use flecs_ecs::sys;
6use std::sync::Mutex;
7
8#[derive(Debug, Component)]
9pub struct Position {
10 pub x: f32,
11 pub y: f32,
12}
13
14#[derive(Component)]
15pub struct Tag;
16
17static GROUP_COUNTER: Mutex<i32> = Mutex::new(0);
18
19struct GroupCtx {
20 counter: i32,
21}
22
23#[derive(Component)]
24pub struct First;
25
26#[derive(Component)]
27pub struct Second;
28
29#[derive(Component)]
30pub struct Third;
31
32#[derive(Component)]
33pub struct Group;
34
35#[extern_abi]
36fn callback_group_create(
37 world: *mut sys::ecs_world_t,
38 group_id: u64,
39 _group_by_ctx: *mut c_void,
40) -> *mut c_void {
41 let world_ref = unsafe { WorldRef::from_ptr(world) };
42 println!(
43 "Group created: {:?}",
44 world_ref.world().entity_from_id(group_id).name()
45 );
46
47 println!();
48
49 let mut counter = GROUP_COUNTER.lock().unwrap();
50 *counter += 1;
51
52 let ctx = Box::new(GroupCtx { counter: *counter });
54
55 Box::into_raw(ctx) as *mut core::ffi::c_void }
57
58#[extern_abi]
59fn callback_group_delete(
60 world: *mut sys::ecs_world_t,
61 group_id: u64,
62 _ctx: *mut c_void,
63 _group_by_ctx: *mut c_void,
64) {
65 let world_ref = unsafe { WorldRef::from_ptr(world) };
66 println!(
67 "Group deleted: {:?}",
68 world_ref.world().entity_from_id(group_id).name()
69 );
70
71 }
74
75fn main() {
76 let world = World::new();
77
78 world.component::<First>();
80 world.component::<Second>();
81 world.component::<Third>();
82
83 let query = world
85 .query::<(&Position,)>()
86 .group_by(Group)
87 .on_group_create(Some(callback_group_create))
89 .on_group_delete(Some(callback_group_delete))
91 .build();
92
93 world
95 .entity()
96 .add((Group, Third))
97 .set(Position { x: 1.0, y: 1.0 });
98 world
99 .entity()
100 .add((Group, Second))
101 .set(Position { x: 2.0, y: 2.0 });
102 world
103 .entity()
104 .add((Group, First))
105 .set(Position { x: 3.0, y: 3.0 });
106
107 world
108 .entity()
109 .add((Group, Third))
110 .set(Position { x: 4.0, y: 4.0 })
111 .add(Tag);
112 world
113 .entity()
114 .add((Group, Second))
115 .set(Position { x: 5.0, y: 5.0 })
116 .add(Tag);
117 world
118 .entity()
119 .add((Group, First))
120 .set(Position { x: 6.0, y: 6.0 })
121 .add(Tag);
122
123 println!();
124
125 query.run(|mut it| {
140 while it.next() {
141 let group = world.entity_from_id(it.group_id());
142 let pos = it.field::<Position>(0);
143
144 let ctx = unsafe { &*(query.group_context(group) as *mut GroupCtx) };
145 println!(
146 "Group: {:?} - Table: [{:?}] - Counter: {}",
147 group.path().unwrap(),
148 it.archetype(),
149 ctx.counter
150 );
151
152 for i in it.iter() {
153 println!(" [{:?}]", pos[i]);
154 }
155
156 println!();
157 }
158 });
159
160 query.destruct();
162
163 }
190
191#[cfg(feature = "flecs_nightly_tests")]
192#[test]
193fn test() {
194 let output_capture = OutputCapture::capture().unwrap();
195 main();
196 output_capture.test("query_group_by_callbacks".to_string());
197}