Skip to content

Commit b5227ba

Browse files
committed
feat : system order by group by
1 parent 911b34d commit b5227ba

1 file changed

Lines changed: 136 additions & 26 deletions

File tree

src/main/java/com/github/elebras1/flecs/SystemBuilder.java

Lines changed: 136 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package 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.*;
64
import com.github.elebras1.flecs.util.FlecsConstants;
75

86
import 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

Comments
 (0)