Skip to content

Commit 145bb49

Browse files
committed
new collection, improve get component methods)
1 parent 22a6b32 commit 145bb49

14 files changed

Lines changed: 400 additions & 73 deletions

File tree

examples/src/main/java/com/github/elebras1/flecs/examples/BulkExample.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.github.elebras1.flecs.examples;
22

33
import com.github.elebras1.flecs.World;
4-
import com.github.elebras1.flecs.collection.EcsLongList;
4+
import com.github.elebras1.flecs.collection.LongList;
55
import com.github.elebras1.flecs.examples.components.Health;
66
import com.github.elebras1.flecs.examples.components.Position;
77
import com.github.elebras1.flecs.examples.components.Velocity;
@@ -19,7 +19,7 @@ public static void main(String[] args) {
1919

2020
long startCreate = System.nanoTime();
2121

22-
EcsLongList entityIds = world.entityBulk(totalEntities, Position.class, Velocity.class, Health.class);
22+
LongList entityIds = world.entityBulk(totalEntities, Position.class, Velocity.class, Health.class);
2323

2424
long endCreate = System.nanoTime();
2525
System.out.printf("Entity creation time: %.3f ms%n", (endCreate - startCreate) / 1_000_000.0);

examples/src/main/java/com/github/elebras1/flecs/examples/ComplexComponentExample.java

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

33
import com.github.elebras1.flecs.Entity;
44
import com.github.elebras1.flecs.World;
5-
import com.github.elebras1.flecs.collection.EcsLongList;
5+
import com.github.elebras1.flecs.collection.LongList;
66
import com.github.elebras1.flecs.examples.components.Ideology;
77
import com.github.elebras1.flecs.examples.components.Minister;
88

@@ -21,7 +21,7 @@ public static void main(String[] args) {
2121
world.component(Ideology.class);
2222

2323
long start = System.currentTimeMillis();
24-
EcsLongList entityIds = new EcsLongList();
24+
LongList entityIds = new LongList();
2525

2626
for (int i = 0; i < N; i++) {
2727
long id = world.entity();

examples/src/main/java/com/github/elebras1/flecs/examples/QueryFeaturesExample.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.github.elebras1.flecs.examples;
22

33
import com.github.elebras1.flecs.*;
4-
import com.github.elebras1.flecs.collection.EcsLongList;
4+
import com.github.elebras1.flecs.collection.LongList;
55
import com.github.elebras1.flecs.examples.components.*;
66

77
public class QueryFeaturesExample {
@@ -154,7 +154,7 @@ public static void main(String[] args) {
154154
// --- Feature 10: entities() list ---
155155
System.out.println("\n--- 10. Get all entities as list ---");
156156
try (Query q10 = world.query().with(enemyTag).build()) {
157-
EcsLongList entities = q10.entities();
157+
LongList entities = q10.entities();
158158
System.out.println("Enemies: " + entities.size());
159159
for (int i = 0; i < entities.size(); i++) {
160160
Entity e = world.obtainEntity(entities.get(i));

examples/src/main/java/com/github/elebras1/flecs/examples/TableExample.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.github.elebras1.flecs.examples;
22

33
import com.github.elebras1.flecs.*;
4-
import com.github.elebras1.flecs.collection.EcsLongList;
4+
import com.github.elebras1.flecs.collection.LongList;
55
import com.github.elebras1.flecs.examples.components.*;
66

77
public class TableExample {
@@ -29,7 +29,7 @@ public static void main(String[] args) {
2929
System.out.println("Column count: " + table.columnCount());
3030

3131
System.out.println("\nComponent IDs in table:");
32-
EcsLongList typeIds = table.type();
32+
LongList typeIds = table.type();
3333
for (int i = 0; i < typeIds.size(); i++) {
3434
long id = typeIds.get(i);
3535
Entity component = world.obtainEntity(id);
@@ -48,7 +48,7 @@ public static void main(String[] args) {
4848
Position pos = table.get(Position.class, row);
4949
Velocity vel = table.get(Velocity.class, row);
5050

51-
EcsLongList entities = table.entities();
51+
LongList entities = table.entities();
5252
Entity e = world.obtainEntity(entities.get(row));
5353
System.out.printf(" %s: pos=(%.1f, %.1f), vel=(%.1f, %.1f)%n",
5454
e.getName(), pos.x(), pos.y(), vel.dx(), vel.dy());

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

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
11
package com.github.elebras1.flecs;
22

33

4+
import com.github.elebras1.flecs.collection.ClassLongMap;
5+
import com.github.elebras1.flecs.collection.LongClassMap;
6+
import com.github.elebras1.flecs.collection.LongObjectMap;
7+
48
import java.lang.foreign.Arena;
59
import java.lang.foreign.MemorySegment;
6-
import java.util.Map;
7-
import java.util.concurrent.ConcurrentHashMap;
810

911
public class ComponentRegistry {
1012

1113
private final World world;
12-
private final Map<Class<?>, Long> componentIds;
13-
private final Map<Long, Class<?>> componentClasses;
14+
private final ClassLongMap componentIds;
15+
private final LongClassMap componentClasses;
16+
private final LongObjectMap<Component<?>> components;
1417

1518
protected ComponentRegistry(World world) {
1619
this.world = world;
17-
this.componentIds = new ConcurrentHashMap<>();
18-
this.componentClasses = new ConcurrentHashMap<>();
20+
this.componentIds = new ClassLongMap();
21+
this.componentClasses = new LongClassMap();
22+
this.components = new LongObjectMap<>();
1923
}
2024

2125
protected <T> long register(Class<T> componentClass) {
22-
if (this.componentIds.containsKey(componentClass)) {
23-
return this.componentIds.get(componentClass);
26+
long existingId = this.componentIds.get(componentClass);
27+
if(existingId != -1) {
28+
return existingId;
2429
}
2530

2631
Component<T> component = this.getComponentInstance(componentClass);
@@ -56,36 +61,38 @@ protected <T> long register(Class<T> componentClass) {
5661
}
5762

5863
protected <T> long getComponentId(Class<T> componentClass) {
59-
Long componentId = this.componentIds.get(componentClass);
60-
if (componentId == null) {
61-
throw new IllegalStateException("Component " + componentClass.getName() + " is not registered.");
62-
}
63-
return componentId;
64+
return this.componentIds.get(componentClass);
6465
}
6566

6667
protected <T> Component<T> getComponent(Class<T> componentClass) {
67-
if (!this.componentIds.containsKey(componentClass)) {
68-
throw new IllegalStateException("Component " + componentClass.getName() + " is not registered.");
69-
}
7068
return ComponentMap.getInstance(componentClass);
7169
}
7270

7371
@SuppressWarnings("unchecked")
7472
protected <T> Component<T> getComponentById(long componentId) {
75-
Class<?> componentClass = this.componentClasses.get(componentId);
76-
if (componentClass == null) {
77-
throw new IllegalStateException("Component with ID " + componentId + " is not registered.");
73+
Component<T> component = (Component<T>) this.components.get(componentId);
74+
if(component == null) {
75+
return this.getAndCacheComponentInstance(componentId);
7876
}
79-
return ComponentMap.getInstance((Class<T>) componentClass);
80-
}
8177

82-
private <T> Component<T> getComponentInstance(Class<T> componentClass) {
83-
Component<T> component = ComponentMap.getInstance(componentClass);
78+
return component;
79+
}
8480

85-
if (component == null) {
86-
throw new IllegalStateException("Component not found for " + componentClass.getName() + ". Make sure the record is annotated with @Component and annotation processing is enabled.");
81+
@SuppressWarnings("unchecked")
82+
private <T> Component<T> getAndCacheComponentInstance(long componentId) {
83+
Class<?> rawClass = this.componentClasses.get(componentId);
84+
if (rawClass == null) {
85+
throw new IllegalArgumentException("Unknown component ID: " + componentId);
8786
}
8887

88+
Class<T> componentClass = (Class<T>) rawClass;
89+
Component<T> component = this.getComponentInstance(componentClass);
90+
91+
this.components.put(componentId, component);
8992
return component;
9093
}
94+
95+
private <T> Component<T> getComponentInstance(Class<T> componentClass) {
96+
return ComponentMap.getInstance(componentClass);
97+
}
9198
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.github.elebras1.flecs;
22

3-
import com.github.elebras1.flecs.collection.EcsLongList;
3+
import com.github.elebras1.flecs.collection.LongList;
44
import java.lang.foreign.Arena;
55
import java.lang.foreign.MemorySegment;
66
import java.lang.foreign.ValueLayout;
@@ -94,9 +94,9 @@ public int count() {
9494
return total;
9595
}
9696

97-
public EcsLongList entities() {
97+
public LongList entities() {
9898
this.checkClosed();
99-
EcsLongList result = new EcsLongList();
99+
LongList result = new LongList();
100100
this.each(result::add);
101101
return result;
102102
}

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.github.elebras1.flecs;
22

3-
import com.github.elebras1.flecs.collection.EcsLongList;
3+
import com.github.elebras1.flecs.collection.LongList;
44

55
import java.lang.foreign.MemorySegment;
66
import java.lang.foreign.ValueLayout;
@@ -30,20 +30,20 @@ public String str() {
3030
return strPtr.reinterpret(Long.MAX_VALUE).getString(0);
3131
}
3232

33-
public EcsLongList type() {
33+
public LongList type() {
3434
if (!this.isValid()) {
35-
return new EcsLongList();
35+
return new LongList();
3636
}
3737
MemorySegment typePtr = flecs_h.ecs_table_get_type(this.nativeTable);
3838
if (typePtr == null || typePtr.address() == 0) {
39-
return new EcsLongList();
39+
return new LongList();
4040
}
4141
MemorySegment arrayPtr = ecs_type_t.array(typePtr);
4242
int count = ecs_type_t.count(typePtr);
4343
if (arrayPtr == null || arrayPtr.address() == 0 || count == 0) {
44-
return new EcsLongList();
44+
return new LongList();
4545
}
46-
EcsLongList ids = new EcsLongList(count);
46+
LongList ids = new LongList(count);
4747
MemorySegment idsArray = arrayPtr.reinterpret((long) count * Long.BYTES);
4848
ids.addAll(idsArray.toArray(ValueLayout.JAVA_LONG));
4949
return ids;
@@ -159,22 +159,22 @@ public <T> T tryGet(Class<T> componentClass, int row) {
159159
return component.read(elementSegment);
160160
}
161161

162-
public EcsLongList entities() {
162+
public LongList entities() {
163163
if (!this.isValid()) {
164-
return new EcsLongList();
164+
return new LongList();
165165
}
166166

167167
int count = this.count();
168168
if (count == 0) {
169-
return new EcsLongList();
169+
return new LongList();
170170
}
171171

172172
MemorySegment entitiesPtr = flecs_h.ecs_table_entities(this.nativeTable);
173173
if (entitiesPtr == null || entitiesPtr.address() == 0) {
174-
return new EcsLongList();
174+
return new LongList();
175175
}
176176

177-
EcsLongList entities = new EcsLongList(count);
177+
LongList entities = new LongList(count);
178178
MemorySegment entitiesArray = entitiesPtr.reinterpret((long) count * Long.BYTES);
179179
entities.addAll(entitiesArray.toArray(ValueLayout.JAVA_LONG));
180180

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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package com.github.elebras1.flecs;
22

3-
import com.github.elebras1.flecs.collection.EcsLongList;
3+
import com.github.elebras1.flecs.collection.LongList;
44
import com.github.elebras1.flecs.util.FlecsConstants;
55
import com.github.elebras1.flecs.util.internal.FlecsLoader;
66

77
import java.lang.foreign.*;
88
import java.nio.charset.StandardCharsets;
9+
import java.util.HashMap;
910
import java.util.Map;
10-
import java.util.concurrent.ConcurrentHashMap;
1111
import java.util.function.Consumer;
1212

1313
import static java.lang.foreign.ValueLayout.*;
@@ -143,8 +143,8 @@ public World() {
143143
}
144144

145145
this.componentRegistry = new ComponentRegistry(this);
146-
this.systemCallbacks = new ConcurrentHashMap<>();
147-
this.observerCallbacks = new ConcurrentHashMap<>();
146+
this.systemCallbacks = new HashMap<>();
147+
this.observerCallbacks = new HashMap<>();
148148
this.defaultBuffers = new FlecsBuffers();
149149
this.closed = false;
150150
this.owned = true;
@@ -154,8 +154,8 @@ private World(MemorySegment stagePtr, ComponentRegistry sharedRegistry) {
154154
this.arena = Arena.ofConfined();
155155
this.nativeWorld = stagePtr;
156156
this.componentRegistry = sharedRegistry;
157-
this.systemCallbacks = new ConcurrentHashMap<>();
158-
this.observerCallbacks = new ConcurrentHashMap<>();
157+
this.systemCallbacks = new HashMap<>();
158+
this.observerCallbacks = new HashMap<>();
159159
this.defaultBuffers = null;
160160
this.closed = false;
161161
this.owned = false;
@@ -188,7 +188,7 @@ MemorySegment getComponentBuffer(long size) {
188188
return this.defaultBuffers.componentBuffer().ensure(size);
189189
}
190190

191-
public EcsLongList entityBulk(int count) {
191+
public LongList entityBulk(int count) {
192192
this.checkClosed();
193193
try(Arena tempArena = Arena.ofConfined()) {
194194
MemorySegment desc = ecs_bulk_desc_t.allocate(tempArena);
@@ -197,13 +197,13 @@ public EcsLongList entityBulk(int count) {
197197

198198
MemorySegment idsSegment = flecs_h.ecs_bulk_init(this.nativeWorld, desc);
199199

200-
EcsLongList ids = new EcsLongList(count);
200+
LongList ids = new LongList(count);
201201
ids.addAll(idsSegment.asSlice(0, (long) count * Long.BYTES).toArray(JAVA_LONG));
202202
return ids;
203203
}
204204
}
205205

206-
public final EcsLongList entityBulk(int count, Class<?>... componentClasses) {
206+
public final LongList entityBulk(int count, Class<?>... componentClasses) {
207207
this.checkClosed();
208208

209209
if (count <= 0) {
@@ -244,7 +244,7 @@ public final EcsLongList entityBulk(int count, Class<?>... componentClasses) {
244244

245245
MemorySegment entitiesPtr = flecs_h.ecs_bulk_init(this.nativeWorld, desc);
246246

247-
EcsLongList entities = new EcsLongList(count);
247+
LongList entities = new LongList(count);
248248
entities.addAll(entitiesPtr.asSlice(0, (long) count * Long.BYTES).toArray(JAVA_LONG));
249249

250250
return entities;
@@ -408,14 +408,14 @@ public long getMaxId() {
408408
return flecs_h.ecs_get_max_id(this.nativeWorld);
409409
}
410410

411-
public EcsLongList getEntities() {
411+
public LongList getEntities() {
412412
this.checkClosed();
413413
try (Arena tempArena = Arena.ofConfined()) {
414414
MemorySegment entitiesStruct = flecs_h.ecs_get_entities(tempArena, this.nativeWorld);
415415
MemorySegment idsPointer = entitiesStruct.get(ValueLayout.ADDRESS, 0);
416416
int count = entitiesStruct.get(ValueLayout.JAVA_INT, ValueLayout.ADDRESS.byteSize());
417417

418-
EcsLongList entities = new EcsLongList(count);
418+
LongList entities = new LongList(count);
419419
if (count > 0 && !idsPointer.equals(MemorySegment.NULL)) {
420420
MemorySegment idsArray = idsPointer.reinterpret((long) count * Long.BYTES);
421421
entities.addAll(idsArray.toArray(ValueLayout.JAVA_LONG));

0 commit comments

Comments
 (0)