Skip to content

Commit 342e41b

Browse files
committed
wip : manuel threading attempt
1 parent 8b79bff commit 342e41b

4 files changed

Lines changed: 62 additions & 42 deletions

File tree

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

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

33
import com.github.elebras1.flecs.Entity;
4+
import com.github.elebras1.flecs.EntityView;
45
import com.github.elebras1.flecs.World;
56
import com.github.elebras1.flecs.examples.components.Health;
7+
import com.github.elebras1.flecs.examples.components.HealthView;
68

79
import java.util.ArrayList;
810
import java.util.List;
@@ -27,14 +29,16 @@ public static void main(String[] args) {
2729
entity.set(new Health(i));
2830
}
2931

32+
world.readonlyBegin();
3033
for (int i = 0; i < THREADS; i++) {
3134
final int stageId = i;
3235
futures.add(executor.submit(() -> {
3336
World stage = world.getStage(stageId);
3437
for(int j = stageId * 250; j < (stageId + 1) * 250; j++) {
35-
long entityId = world.lookup("entity_" + j);
36-
Entity entity = stage.obtainEntity(entityId);
37-
entity.set(new Health(j));
38+
long entityId = stage.lookup("entity_" + j);
39+
EntityView entity = stage.obtainEntityView(entityId);
40+
HealthView health = entity.getMutView(Health.class);
41+
health.value(health.value() + 1);
3842
}
3943
}));
4044
}
@@ -47,7 +51,8 @@ public static void main(String[] args) {
4751
e.printStackTrace();
4852
}
4953

50-
world.merge();
54+
world.readonlyEnd();
55+
5156
executor.shutdown();
5257

5358
world.destroy();

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

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

33
import com.github.elebras1.flecs.callback.RowCallback;
4+
import com.github.elebras1.flecs.util.internal.FlecsAllocator;
45

56
import java.lang.foreign.MemorySegment;
67
import java.lang.foreign.ValueLayout;
@@ -17,8 +18,7 @@ public class Table {
1718
public String str() {
1819
MemorySegment strSeg = flecs_h.ecs_table_str(this.world.worldSeg(), this.tableSeg);
1920
String str = strSeg.reinterpret(Long.MAX_VALUE).getString(0);
20-
MemorySegment freeSeg = ecs_os_api_t.free_(flecs_h.ecs_os_api());
21-
ecs_os_api_free_t.invoke(freeSeg, strSeg);
21+
FlecsAllocator.free(strSeg);
2222
return str;
2323
}
2424

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

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

33
import com.github.elebras1.flecs.callback.*;
44
import com.github.elebras1.flecs.util.FlecsConstants;
5+
import com.github.elebras1.flecs.util.internal.FlecsAllocator;
56
import com.github.elebras1.flecs.util.internal.FlecsLoader;
67

78
import java.lang.foreign.*;
@@ -44,91 +45,81 @@ public void close() {
4445
}
4546

4647
private static final class NameBuffer implements AutoCloseable {
47-
private Arena arena;
4848
private MemorySegment segment;
4949
private long capacity;
5050

5151
NameBuffer(long initialCapacity) {
5252
this.capacity = initialCapacity;
53-
this.arena = Arena.ofConfined();
54-
this.segment = this.arena.allocate(initialCapacity);
53+
this.segment = FlecsAllocator.malloc(initialCapacity);
5554
}
5655

5756
private MemorySegment ensure(long needed) {
58-
if (needed > capacity) {
59-
this.arena.close();
60-
this.arena = Arena.ofConfined();
61-
this.capacity = Math.max(needed, capacity * 2);
62-
this.segment = this.arena.allocate(this.capacity);
57+
if (needed > this.capacity) {
58+
this.capacity = Math.max(needed, this.capacity * 2);
59+
FlecsAllocator.free(this.segment);
60+
this.segment = FlecsAllocator.malloc(this.capacity);
6361
}
6462
return segment;
6563
}
6664

67-
public MemorySegment set(String value) {
68-
byte[] utf8 = value.getBytes(StandardCharsets.UTF_8);
69-
long needed = utf8.length + 1;
70-
MemorySegment segment = ensure(needed);
71-
MemorySegment.copy(utf8, 0, segment, JAVA_BYTE, 0, utf8.length);
72-
segment.set(JAVA_BYTE, utf8.length, (byte) 0);
73-
return segment;
65+
public MemorySegment set(String name) {
66+
byte[] nameBytes = name.getBytes(StandardCharsets.UTF_8);
67+
long needed = nameBytes.length + 1;
68+
MemorySegment nameSeg = ensure(needed);
69+
nameSeg.fill((byte) 0);
70+
nameSeg.setString(0, name);
71+
return nameSeg;
7472
}
7573

7674
@Override
7775
public void close() {
78-
if (this.arena != null) {
79-
this.arena.close();
80-
this.arena = null;
76+
if (this.segment != null && this.segment.address() != 0) {
77+
FlecsAllocator.free(this.segment);
8178
}
8279
}
8380
}
8481

8582
private static final class ComponentBuffer implements AutoCloseable {
86-
private Arena arena;
8783
private MemorySegment segment;
8884
private long capacity;
8985

9086
ComponentBuffer(long initialCapacity) {
9187
this.capacity = initialCapacity;
92-
this.arena = Arena.ofConfined();
93-
this.segment = this.arena.allocate(initialCapacity);
88+
this.segment = FlecsAllocator.malloc(initialCapacity);
9489
}
9590

9691
MemorySegment ensure(long needed) {
97-
if (needed > capacity) {
98-
long newCapacity = Math.max(needed, capacity * 2);
99-
this.arena.close();
100-
this.arena = Arena.ofConfined();
101-
this.segment = this.arena.allocate(newCapacity);
102-
this.capacity = newCapacity;
92+
if (needed > this.capacity) {
93+
this.capacity = Math.max(needed, this.capacity * 2);
94+
FlecsAllocator.free(segment);
95+
this.segment = FlecsAllocator.malloc(this.capacity);
10396
}
104-
return segment.asSlice(0, needed);
97+
return this.segment.fill((byte) 0);
10598
}
10699

107100
@Override
108101
public void close() {
109-
if (this.arena != null) {
110-
this.arena.close();
111-
this.arena = null;
102+
if (this.segment != null && this.segment.address() != 0) {
103+
FlecsAllocator.free(this.segment);
112104
}
113105
}
114106
}
115107

116108
private static final class EntityDescBuffer implements AutoCloseable {
117-
private final Arena arena;
118109
private final MemorySegment segment;
119110

120111
EntityDescBuffer() {
121-
this.arena = Arena.ofConfined();
122-
this.segment = ecs_entity_desc_t.allocate(this.arena);
112+
this.segment = FlecsAllocator.malloc(ecs_entity_desc_t.sizeof());
123113
}
124114

125115
MemorySegment get() {
116+
this.segment.fill((byte) 0);
126117
return this.segment;
127118
}
128119

129120
@Override
130121
public void close() {
131-
this.arena.close();
122+
FlecsAllocator.free(this.segment);
132123
}
133124
}
134125

@@ -154,7 +145,7 @@ private World(MemorySegment stageSeg, ComponentRegistry componentRegistry) {
154145
this.componentRegistry = componentRegistry;
155146
this.systemCallbacks = new HashMap<>();
156147
this.observerCallbacks = new HashMap<>();
157-
this.defaultBuffers = null;
148+
this.defaultBuffers = new FlecsBuffers();
158149
this.contextCache = new FlecsContext(this);
159150
this.destroyed = false;
160151
this.owned = false;
@@ -882,6 +873,8 @@ public void destroy() {
882873
}
883874
}
884875

876+
this.defaultBuffers.close();
877+
885878
if (this.arena != null) {
886879
this.arena.close();
887880
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.github.elebras1.flecs.util.internal;
2+
3+
import com.github.elebras1.flecs.ecs_os_api_free_t;
4+
import com.github.elebras1.flecs.ecs_os_api_malloc_t;
5+
import com.github.elebras1.flecs.ecs_os_api_t;
6+
import com.github.elebras1.flecs.flecs_h;
7+
8+
import java.lang.foreign.MemorySegment;
9+
10+
public final class FlecsAllocator {
11+
12+
public static MemorySegment malloc(long size) {
13+
MemorySegment mallocSeg = ecs_os_api_t.malloc_(flecs_h.ecs_os_api());
14+
return ecs_os_api_malloc_t.invoke(mallocSeg, (int) size).reinterpret(size);
15+
}
16+
17+
public static void free(MemorySegment segment) {
18+
MemorySegment freeSeg = ecs_os_api_t.free_(flecs_h.ecs_os_api());
19+
ecs_os_api_free_t.invoke(freeSeg, segment);
20+
}
21+
22+
}

0 commit comments

Comments
 (0)