11package com .github .elebras1 .flecs ;
22
3- import com .github .elebras1 .flecs .callback .EntityCallback ;
4- import com .github .elebras1 .flecs .callback .IterCallback ;
5- import com .github .elebras1 .flecs .callback .RunCallback ;
3+ import com .github .elebras1 .flecs .callback .*;
64import com .github .elebras1 .flecs .util .FlecsConstants ;
75
86import java .lang .foreign .Arena ;
@@ -87,11 +85,11 @@ public SystemBuilder with(long componentId) {
8785 throw new IllegalStateException ("Maximum number of terms (32) reached" );
8886 }
8987
90- MemorySegment queryDesc = ecs_system_desc_t .query (this .desc );
88+ MemorySegment queryDescSeg = ecs_system_desc_t .query (this .desc );
9189 long termsOffset = ecs_query_desc_t .terms$offset ();
9290 long termOffset = termsOffset + (this .termCount * TERM_SIZE );
9391
94- MemorySegment term = queryDesc .asSlice (termOffset , TERM_SIZE );
92+ MemorySegment term = queryDescSeg .asSlice (termOffset , TERM_SIZE );
9593 long idOffset = ecs_term_t .id$offset ();
9694
9795 term .set (ValueLayout .JAVA_LONG , idOffset , componentId );
@@ -116,14 +114,14 @@ public SystemBuilder with(long relationId, long componentId) {
116114
117115 long pairId = flecs_h .ecs_make_pair (relationId , componentId );
118116
119- MemorySegment queryDesc = ecs_system_desc_t .query (this .desc );
117+ MemorySegment queryDescSeg = ecs_system_desc_t .query (this .desc );
120118 long termsOffset = ecs_query_desc_t .terms$offset ();
121119 long termOffset = termsOffset + (this .termCount * TERM_SIZE );
122120
123- MemorySegment term = queryDesc .asSlice (termOffset , TERM_SIZE );
121+ MemorySegment termSeg = queryDescSeg .asSlice (termOffset , TERM_SIZE );
124122 long idOffset = ecs_term_t .id$offset ();
125123
126- term .set (ValueLayout .JAVA_LONG , idOffset , pairId );
124+ termSeg .set (ValueLayout .JAVA_LONG , idOffset , pairId );
127125
128126 this .termCount ++;
129127 return this ;
@@ -161,14 +159,14 @@ public SystemBuilder in() {
161159 throw new IllegalStateException ("No term to apply 'in' modifier to" );
162160 }
163161
164- MemorySegment queryDesc = ecs_system_desc_t .query (this .desc );
162+ MemorySegment queryDescSeg = ecs_system_desc_t .query (this .desc );
165163 long termsOffset = ecs_query_desc_t .terms$offset ();
166164 long termOffset = termsOffset + ((this .termCount - 1 ) * TERM_SIZE );
167165
168- MemorySegment term = queryDesc .asSlice (termOffset , TERM_SIZE );
166+ MemorySegment termSeg = queryDescSeg .asSlice (termOffset , TERM_SIZE );
169167 long inoutOffset = ecs_term_t .inout$offset ();
170168
171- term .set (ValueLayout .JAVA_INT , inoutOffset , EcsIn );
169+ termSeg .set (ValueLayout .JAVA_INT , inoutOffset , EcsIn );
172170
173171 return this ;
174172 }
@@ -178,14 +176,14 @@ public SystemBuilder out() {
178176 throw new IllegalStateException ("No term to apply 'out' modifier to" );
179177 }
180178
181- MemorySegment queryDesc = ecs_system_desc_t .query (this .desc );
179+ MemorySegment queryDescSeg = ecs_system_desc_t .query (this .desc );
182180 long termsOffset = ecs_query_desc_t .terms$offset ();
183181 long termOffset = termsOffset + ((this .termCount - 1 ) * TERM_SIZE );
184182
185- MemorySegment term = queryDesc .asSlice (termOffset , TERM_SIZE );
183+ MemorySegment termSeg = queryDescSeg .asSlice (termOffset , TERM_SIZE );
186184 long inoutOffset = ecs_term_t .inout$offset ();
187185
188- term .set (ValueLayout .JAVA_INT , inoutOffset , EcsOut );
186+ termSeg .set (ValueLayout .JAVA_INT , inoutOffset , EcsOut );
189187
190188 return this ;
191189 }
@@ -195,14 +193,14 @@ public SystemBuilder inOut() {
195193 throw new IllegalStateException ("No term to apply 'inout' modifier to" );
196194 }
197195
198- MemorySegment queryDesc = ecs_system_desc_t .query (this .desc );
196+ MemorySegment queryDescSeg = ecs_system_desc_t .query (this .desc );
199197 long termsOffset = ecs_query_desc_t .terms$offset ();
200198 long termOffset = termsOffset + ((this .termCount - 1 ) * TERM_SIZE );
201199
202- MemorySegment term = queryDesc .asSlice (termOffset , TERM_SIZE );
200+ MemorySegment termSeg = queryDescSeg .asSlice (termOffset , TERM_SIZE );
203201 long inoutOffset = ecs_term_t .inout$offset ();
204202
205- term .set (ValueLayout .JAVA_INT , inoutOffset , EcsInOut );
203+ termSeg .set (ValueLayout .JAVA_INT , inoutOffset , EcsInOut );
206204
207205 return this ;
208206 }
@@ -212,12 +210,12 @@ public SystemBuilder operator(int operator) {
212210 throw new IllegalStateException ("No term to apply 'operator' modifier to" );
213211 }
214212
215- MemorySegment queryDesc = ecs_system_desc_t .query (this .desc );
213+ MemorySegment queryDescSeg = ecs_system_desc_t .query (this .desc );
216214 long termsOffset = ecs_query_desc_t .terms$offset ();
217215 long termOffset = termsOffset + ((this .termCount - 1 ) * TERM_SIZE );
218216
219- MemorySegment term = queryDesc .asSlice (termOffset , TERM_SIZE );
220- ecs_term_t .oper (term , (short ) operator );
217+ MemorySegment termSeg = queryDescSeg .asSlice (termOffset , TERM_SIZE );
218+ ecs_term_t .oper (termSeg , (short ) operator );
221219 return this ;
222220 }
223221
@@ -259,12 +257,124 @@ public <T> SystemBuilder read(Class<T> componentClass) {
259257 return this .with (componentId ).in ();
260258 }
261259
260+ public SystemBuilder orderBy (long componentId ) {
261+ MemorySegment queryDescSeg = ecs_system_desc_t .query (this .desc );
262+ ecs_query_desc_t .order_by (queryDescSeg , componentId );
263+ return this ;
264+ }
265+
266+ public SystemBuilder orderBy (long componentId , ComparatorId comparator ) {
267+ MemorySegment callbackStub = ecs_order_by_action_t .allocate ((idA , _ , idB , _ ) ->
268+ comparator .compare (idA , idB ), this .world .arena ());
269+
270+ MemorySegment queryDescSeg = ecs_system_desc_t .query (this .desc );
271+ ecs_query_desc_t .order_by_callback (queryDescSeg , callbackStub );
272+
273+ return this .orderBy (componentId );
274+ }
275+
276+ public SystemBuilder orderBy (long componentId , ComparatorComponent comparator ) {
277+ MemorySegment callbackStub = ecs_order_by_action_t .allocate ((idA , componentASeg , idB , componentBSeg ) -> {
278+ Component <?> componentA = this .world .componentRegistry ().getComponentById (idA );
279+ Component <?> componentB = this .world .componentRegistry ().getComponentById (idB );
280+ return comparator .compare (componentA .read (componentASeg , 0 ), componentB .read (componentBSeg , 0 ));
281+ }, this .arena );
282+
283+ MemorySegment queryDescSeg = ecs_system_desc_t .query (this .desc );
284+ ecs_query_desc_t .order_by_callback (queryDescSeg , callbackStub );
285+
286+ return this .orderBy (componentId );
287+ }
288+
289+ public SystemBuilder orderBy (long componentId , ComparatorComponentView comparator ) {
290+ MemorySegment callbackStub = ecs_order_by_action_t .allocate ((idA , componentASeg , idB , componentBSeg ) -> {
291+ Class <?> componentClassA = this .world .componentRegistry ().getComponentClassById (idA );
292+ Class <?> componentClassB = this .world .componentRegistry ().getComponentClassById (idB );
293+ ComponentView componentViewA = this .world .viewCache ().getComponentView (componentClassA );
294+ componentViewA .setBaseAddress (componentASeg .address ());
295+ ComponentView componentViewB = this .world .viewCache ().getComponentView (componentClassB );
296+ componentViewB .setBaseAddress (componentBSeg .address ());
297+ return comparator .compare (componentViewA , componentViewB );
298+ }, this .arena );
299+
300+ MemorySegment queryDescSeg = ecs_system_desc_t .query (this .desc );
301+ ecs_query_desc_t .order_by_callback (queryDescSeg , callbackStub );
302+
303+ return this .orderBy (componentId );
304+ }
305+
306+ public SystemBuilder orderBy (Entity entity ) {
307+ return this .orderBy (entity .id ());
308+ }
309+
310+ public SystemBuilder orderBy (Entity entity , ComparatorId comparator ) {
311+ return this .orderBy (entity .id (), comparator );
312+ }
313+
314+ public SystemBuilder orderBy (Entity entity , ComparatorComponent comparator ) {
315+ return this .orderBy (entity .id (), comparator );
316+ }
317+
318+ public SystemBuilder orderBy (Entity entity , ComparatorComponentView comparator ) {
319+ return this .orderBy (entity .id (), comparator );
320+ }
321+
322+ public SystemBuilder orderBy (Class <?> componentClass ) {
323+ long componentId = this .world .componentRegistry ().getComponentId (componentClass );
324+ return this .orderBy (componentId );
325+ }
326+
327+ public SystemBuilder orderBy (Class <?> componentClass , ComparatorId comparator ) {
328+ long componentId = this .world .componentRegistry ().getComponentId (componentClass );
329+ return this .orderBy (componentId , comparator );
330+ }
331+
332+ public SystemBuilder orderBy (Class <?> componentClass , ComparatorComponent comparator ) {
333+ long componentId = this .world .componentRegistry ().getComponentId (componentClass );
334+ return this .orderBy (componentId , comparator );
335+ }
336+
337+ public SystemBuilder groupBy (long groupId ) {
338+ MemorySegment queryDescSeg = ecs_system_desc_t .query (this .desc );
339+ ecs_query_desc_t .group_by (queryDescSeg , groupId );
340+ return this ;
341+ }
342+
343+ public SystemBuilder groupBy (long groupId , GroupByCallback groupByCallback ) {
344+ MemorySegment callbackStub = ecs_group_by_action_t .allocate ((_ , tableSeg , id , _ ) -> {
345+ Table table = tableSeg .address () == 0 ? null : new Table (this .world , tableSeg );
346+ return groupByCallback .accept (this .world , table , id );
347+ }, this .world .arena ());
348+
349+ MemorySegment queryDescSeg = ecs_system_desc_t .query (this .desc );
350+ ecs_query_desc_t .group_by_callback (queryDescSeg , callbackStub );
351+ return this .groupBy (groupId );
352+ }
353+
354+ public SystemBuilder groupBy (Class <?> componentClass ) {
355+ long groupId = this .world .componentRegistry ().getComponentId (componentClass );
356+ return this .groupBy (groupId );
357+ }
358+
359+ public SystemBuilder groupBy (Class <?> componentClass , GroupByCallback groupByCallback ) {
360+ long groupId = this .world .componentRegistry ().getComponentId (componentClass );
361+ return this .groupBy (groupId , groupByCallback );
362+ }
363+
364+ public SystemBuilder groupBy (Entity entity ) {
365+ return this .groupBy (entity .id ());
366+ }
367+
368+ public SystemBuilder groupBy (Entity entity , GroupByCallback groupByCallback ) {
369+ return this .groupBy (entity .id (), groupByCallback );
370+ }
371+
262372 public FlecsSystem iter (IterCallback callback ) {
263373 this .iterCallback = callback ;
264374
265375 MemorySegment callbackStub = ecs_iter_action_t .allocate (iterSegment -> {
266- MemorySegment stageWorld = ecs_iter_t .world (iterSegment );
267- int stageId = flecs_h .ecs_stage_get_id (stageWorld );
376+ MemorySegment stageSeg = ecs_iter_t .world (iterSegment );
377+ int stageId = flecs_h .ecs_stage_get_id (stageSeg );
268378 Iter iter = this .iters [stageId ];
269379 iter .setIterSeg (iterSegment );
270380 iter .world ().viewCache ().resetCursors ();
@@ -280,8 +390,8 @@ public FlecsSystem run(RunCallback callback) {
280390 this .runCallback = callback ;
281391
282392 MemorySegment callbackStub = ecs_run_action_t .allocate (iterSegment -> {
283- MemorySegment stageWorld = ecs_iter_t .world (iterSegment );
284- int stageId = flecs_h .ecs_stage_get_id (stageWorld );
393+ MemorySegment stageSeg = ecs_iter_t .world (iterSegment );
394+ int stageId = flecs_h .ecs_stage_get_id (stageSeg );
285395 Iter iter = this .iters [stageId ];
286396 iter .setIterSeg (iterSegment );
287397 iter .world ().viewCache ().resetCursors ();
@@ -298,10 +408,10 @@ public FlecsSystem each(EntityCallback callback) {
298408
299409 MemorySegment callbackStub = ecs_iter_action_t .allocate (iterSegment -> {
300410 int count = ecs_iter_t .count (iterSegment );
301- MemorySegment entities = ecs_iter_t .entities (iterSegment );
411+ MemorySegment entitiesSeg = ecs_iter_t .entities (iterSegment );
302412
303413 for (int i = 0 ; i < count ; i ++) {
304- long entityId = entities .getAtIndex (ValueLayout .JAVA_LONG , i );
414+ long entityId = entitiesSeg .getAtIndex (ValueLayout .JAVA_LONG , i );
305415 callback .accept (entityId );
306416 }
307417 }, this .world .arena ());
0 commit comments