Skip to content

Commit 54452cf

Browse files
committed
table and pipeline exemples
1 parent 090e6f9 commit 54452cf

4 files changed

Lines changed: 208 additions & 9 deletions

File tree

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.github.elebras1.flecs.examples;
2+
3+
import com.github.elebras1.flecs.*;
4+
import com.github.elebras1.flecs.examples.components.*;
5+
6+
public class PipelineExample {
7+
8+
public static void main(String[] args) {
9+
try (Flecs world = new Flecs()) {
10+
System.out.println("=== Pipeline Example ===\n");
11+
12+
world.component(Position.class);
13+
14+
Entity e = world.obtainEntity(world.entity("Entity"));
15+
e.set(new Position(0, 0));
16+
17+
System.out.println("--- Creating custom phases ---");
18+
long physics = world.entity("Physics");
19+
long render = world.entity("Render");
20+
21+
System.out.println("Physics phase ID: " + physics);
22+
System.out.println("Render phase ID: " + render);
23+
24+
System.out.println("\n--- Creating custom pipeline ---");
25+
Pipeline customPipeline = world.pipeline("CustomPipeline")
26+
.with(physics)
27+
.with(render)
28+
.build();
29+
30+
System.out.println("Pipeline ID: " + customPipeline.id());
31+
System.out.println("Pipeline entity: " + customPipeline.entity());
32+
33+
System.out.println("\n--- Creating systems for phases ---");
34+
world.system("PhysicsSystem")
35+
.kind(physics)
36+
.with(Position.class)
37+
.iter(it -> System.out.println(" [Physics] Processing " + it.count() + " entities"));
38+
39+
world.system("RenderSystem")
40+
.kind(render)
41+
.with(Position.class)
42+
.iter(it -> System.out.println(" [Render] Drawing " + it.count() + " entities"));
43+
44+
System.out.println("\n--- Running with custom pipeline ---");
45+
world.setPipeline(customPipeline.id());
46+
47+
for (int i = 0; i < 3; i++) {
48+
System.out.println("Frame " + (i + 1) + ":");
49+
world.progress(0.016f);
50+
}
51+
52+
System.out.println("\n=== Example completed! ===");
53+
}
54+
}
55+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.github.elebras1.flecs.examples;
2+
3+
import com.github.elebras1.flecs.*;
4+
import com.github.elebras1.flecs.collection.EcsLongList;
5+
import com.github.elebras1.flecs.examples.components.*;
6+
7+
public class TableExample {
8+
9+
public static void main(String[] args) {
10+
try (Flecs world = new Flecs()) {
11+
System.out.println("=== Table Example ===\n");
12+
13+
world.component(Position.class);
14+
world.component(Velocity.class);
15+
world.component(Health.class);
16+
17+
world.obtainEntity(world.entity()).set(new Position(0, 0)).set(new Velocity(1, 1));
18+
world.obtainEntity(world.entity()).set(new Position(10, 10)).set(new Velocity(2, 2));
19+
world.obtainEntity(world.entity()).set(new Position(20, 20)).set(new Health(100));
20+
world.obtainEntity(world.entity()).set(new Position(30, 30));
21+
22+
System.out.println("--- Table info and type ---");
23+
try (Query q = world.query().with(Position.class).with(Velocity.class).build()) {
24+
q.iter(it -> {
25+
Table table = it.table();
26+
27+
System.out.println("Table type: " + table.str());
28+
System.out.println("Entity count: " + table.count());
29+
System.out.println("Column count: " + table.columnCount());
30+
31+
System.out.println("\nComponent IDs in table:");
32+
EcsLongList typeIds = table.type();
33+
for (int i = 0; i < typeIds.size(); i++) {
34+
long id = typeIds.get(i);
35+
Entity component = world.obtainEntity(id);
36+
System.out.println(" - " + component.getName() + " (ID: " + id + ")");
37+
}
38+
});
39+
}
40+
41+
System.out.println("\n--- Direct component access via Table ---");
42+
try (Query q = world.query().with(Position.class).with(Velocity.class).build()) {
43+
q.iter(it -> {
44+
Table table = it.table();
45+
46+
System.out.println("Reading components directly from table:");
47+
for (int row = 0; row < table.count(); row++) {
48+
Position pos = table.get(Position.class, row);
49+
Velocity vel = table.get(Velocity.class, row);
50+
51+
EcsLongList entities = table.entities();
52+
Entity e = world.obtainEntity(entities.get(row));
53+
System.out.printf(" %s: pos=(%.1f, %.1f), vel=(%.1f, %.1f)%n",
54+
e.getName(), pos.x(), pos.y(), vel.dx(), vel.dy());
55+
}
56+
});
57+
}
58+
59+
System.out.println("\n--- Different archetypes = Different tables ---");
60+
try (Query q = world.query().with(Position.class).build()) {
61+
q.iter(it -> {
62+
Table table = it.table();
63+
System.out.println("Table [" + table.str() + "] - " + table.count() + " entities");
64+
});
65+
}
66+
67+
System.out.println("\n=== Example completed! ===");
68+
}
69+
}
70+
}
71+

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

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import java.lang.foreign.Arena;
44
import java.lang.foreign.MemorySegment;
5-
import java.lang.foreign.ValueLayout;
65

76
public class PipelineBuilder {
87

@@ -37,18 +36,18 @@ public PipelineBuilder with(long phaseId) {
3736

3837
MemorySegment queryDesc = ecs_pipeline_desc_t.query(this.desc);
3938
long termsOffset = ecs_query_desc_t.terms$offset();
40-
long termOffset = termsOffset + (this.termCount * TERM_SIZE);
41-
42-
MemorySegment term = queryDesc.asSlice(termOffset, TERM_SIZE);
43-
long idOffset = ecs_term_t.id$offset();
44-
long operOffset = ecs_term_t.oper$offset();
45-
46-
term.set(ValueLayout.JAVA_LONG, idOffset, phaseId);
4739

4840
if (this.termCount > 0) {
49-
term.set(ValueLayout.JAVA_INT, operOffset, FlecsConstants.EcsOr);
41+
long prevTermOffset = termsOffset + ((this.termCount - 1) * TERM_SIZE);
42+
MemorySegment prevTerm = queryDesc.asSlice(prevTermOffset, TERM_SIZE);
43+
ecs_term_t.oper(prevTerm, (short) FlecsConstants.EcsOr);
5044
}
5145

46+
long termOffset = termsOffset + (this.termCount * TERM_SIZE);
47+
MemorySegment term = queryDesc.asSlice(termOffset, TERM_SIZE);
48+
ecs_term_t.id(term, phaseId);
49+
50+
5251
this.termCount++;
5352
return this;
5453
}

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

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,36 @@ public boolean isValid() {
1919
return this.nativeTable != null && this.nativeTable.address() != 0;
2020
}
2121

22+
public String str() {
23+
if (!this.isValid()) {
24+
return "";
25+
}
26+
MemorySegment strPtr = flecs_h.ecs_table_str(this.world.nativeHandle(), this.nativeTable);
27+
if (strPtr == null || strPtr.address() == 0) {
28+
return "";
29+
}
30+
return strPtr.reinterpret(Long.MAX_VALUE).getString(0);
31+
}
32+
33+
public EcsLongList type() {
34+
if (!this.isValid()) {
35+
return new EcsLongList();
36+
}
37+
MemorySegment typePtr = flecs_h.ecs_table_get_type(this.nativeTable);
38+
if (typePtr == null || typePtr.address() == 0) {
39+
return new EcsLongList();
40+
}
41+
MemorySegment arrayPtr = ecs_type_t.array(typePtr);
42+
int count = ecs_type_t.count(typePtr);
43+
if (arrayPtr == null || arrayPtr.address() == 0 || count == 0) {
44+
return new EcsLongList();
45+
}
46+
EcsLongList ids = new EcsLongList(count);
47+
MemorySegment idsArray = arrayPtr.reinterpret((long) count * Long.BYTES);
48+
ids.addAll(idsArray.toArray(ValueLayout.JAVA_LONG));
49+
return ids;
50+
}
51+
2252
public int count() {
2353
if (!this.isValid()) {
2454
return 0;
@@ -85,6 +115,50 @@ public long getColumnSize(int columnIndex) {
85115
return flecs_h.ecs_table_get_column_size(this.nativeTable, columnIndex);
86116
}
87117

118+
public MemorySegment getColumn(int columnIndex) {
119+
if (!this.isValid()) {
120+
return MemorySegment.NULL;
121+
}
122+
return flecs_h.ecs_table_get_column(this.nativeTable, columnIndex, 0);
123+
}
124+
125+
public MemorySegment getColumn(int columnIndex, int offset) {
126+
if (!this.isValid()) {
127+
return MemorySegment.NULL;
128+
}
129+
return flecs_h.ecs_table_get_column(this.nativeTable, columnIndex, offset);
130+
}
131+
132+
public <T> T get(Class<T> componentClass, int row) {
133+
int colIndex = this.columnIndex(componentClass);
134+
if (colIndex == -1) {
135+
throw new IllegalArgumentException("Component " + componentClass.getSimpleName() + " not found in table");
136+
}
137+
Component<T> component = this.world.componentRegistry().getComponent(componentClass);
138+
MemorySegment columnPtr = this.getColumn(colIndex);
139+
if (columnPtr == null || columnPtr.address() == 0) {
140+
throw new IllegalStateException("Failed to get column data");
141+
}
142+
long elementOffset = (long) row * component.size();
143+
MemorySegment elementSegment = columnPtr.reinterpret(component.size() * this.count()).asSlice(elementOffset, component.size());
144+
return component.read(elementSegment);
145+
}
146+
147+
public <T> T tryGet(Class<T> componentClass, int row) {
148+
int colIndex = this.columnIndex(componentClass);
149+
if (colIndex == -1) {
150+
return null;
151+
}
152+
Component<T> component = this.world.componentRegistry().getComponent(componentClass);
153+
MemorySegment columnPtr = this.getColumn(colIndex);
154+
if (columnPtr == null || columnPtr.address() == 0) {
155+
return null;
156+
}
157+
long elementOffset = (long) row * component.size();
158+
MemorySegment elementSegment = columnPtr.reinterpret(component.size() * this.count()).asSlice(elementOffset, component.size());
159+
return component.read(elementSegment);
160+
}
161+
88162
public EcsLongList entities() {
89163
if (!this.isValid()) {
90164
return new EcsLongList();

0 commit comments

Comments
 (0)