Skip to content

Commit bf6f36b

Browse files
committed
fix : memory 'leak' in query iteration
1 parent a6b4c9b commit bf6f36b

1 file changed

Lines changed: 48 additions & 40 deletions

File tree

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

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -35,68 +35,76 @@ public interface RunCallback {
3535

3636
public void each(EntityCallback callback) {
3737
this.checkClosed();
38-
var cache = new FlecsContext.ViewCache();
39-
ScopedValue.where(FlecsContext.CURRENT_CACHE, cache).run(() -> {
40-
MemorySegment iter = flecs_h.ecs_query_iter(this.arena, this.world.nativeHandle(), this.nativeQuery);
41-
if (iter == null || iter.address() == 0) {
42-
throw new IllegalStateException("ecs_query_iter returned a null iterator");
43-
}
38+
try (Arena tmpArena = Arena.ofConfined()) {
39+
var cache = new FlecsContext.ViewCache();
40+
ScopedValue.where(FlecsContext.CURRENT_CACHE, cache).run(() -> {
41+
MemorySegment iter = flecs_h.ecs_query_iter(tmpArena, this.world.nativeHandle(), this.nativeQuery);
42+
if (iter == null || iter.address() == 0) {
43+
throw new IllegalStateException("ecs_query_iter returned a null iterator");
44+
}
4445

45-
while (flecs_h.ecs_iter_next(iter)) {
46-
int count = ecs_iter_t.count(iter);
47-
MemorySegment entities = ecs_iter_t.entities(iter);
46+
while (flecs_h.ecs_iter_next(iter)) {
47+
int count = ecs_iter_t.count(iter);
48+
MemorySegment entities = ecs_iter_t.entities(iter);
4849

49-
for (int i = 0; i < count; i++) {
50-
long entityId = entities.getAtIndex(ValueLayout.JAVA_LONG, i);
51-
callback.accept(entityId);
50+
for (int i = 0; i < count; i++) {
51+
long entityId = entities.getAtIndex(ValueLayout.JAVA_LONG, i);
52+
callback.accept(entityId);
53+
}
5254
}
53-
}
54-
});
55+
});
56+
}
5557
}
5658

5759
public void iter(IterCallback callback) {
5860
this.checkClosed();
59-
var cache = new FlecsContext.ViewCache();
60-
ScopedValue.where(FlecsContext.CURRENT_CACHE, cache).run(() -> {
61-
MemorySegment iter = flecs_h.ecs_query_iter(this.arena, this.world.nativeHandle(), this.nativeQuery);
62-
if (iter == null || iter.address() == 0) {
63-
throw new IllegalStateException("ecs_query_iter returned a null iterator");
64-
}
61+
try (Arena tmpArena = Arena.ofConfined()) {
62+
var cache = new FlecsContext.ViewCache();
63+
ScopedValue.where(FlecsContext.CURRENT_CACHE, cache).run(() -> {
64+
MemorySegment iter = flecs_h.ecs_query_iter(tmpArena, this.world.nativeHandle(), this.nativeQuery);
65+
if (iter == null || iter.address() == 0) {
66+
throw new IllegalStateException("ecs_query_iter returned a null iterator");
67+
}
6568

66-
Iter it = new Iter(iter, this.world);
69+
Iter it = new Iter(iter, this.world);
6770

68-
while (flecs_h.ecs_iter_next(iter)) {
69-
it.setNativeIter(iter);
70-
callback.accept(it);
71-
}
72-
});
71+
while (flecs_h.ecs_iter_next(iter)) {
72+
it.setNativeIter(iter);
73+
callback.accept(it);
74+
}
75+
});
76+
}
7377
}
7478

7579
public void run(RunCallback callback) {
7680
this.checkClosed();
77-
var cache = new FlecsContext.ViewCache();
78-
ScopedValue.where(FlecsContext.CURRENT_CACHE, cache).run(() -> {
79-
MemorySegment iter = flecs_h.ecs_query_iter(this.arena, this.world.nativeHandle(), this.nativeQuery);
81+
try (Arena tmpArena = Arena.ofConfined()) {
82+
var cache = new FlecsContext.ViewCache();
83+
ScopedValue.where(FlecsContext.CURRENT_CACHE, cache).run(() -> {
84+
MemorySegment iter = flecs_h.ecs_query_iter(tmpArena, this.world.nativeHandle(), this.nativeQuery);
8085

81-
if (iter == null || iter.address() == 0) {
82-
throw new IllegalStateException("ecs_query_iter returned a null iterator");
83-
}
86+
if (iter == null || iter.address() == 0) {
87+
throw new IllegalStateException("ecs_query_iter returned a null iterator");
88+
}
8489

85-
Iter it = new Iter(iter, this.world);
86-
callback.accept(it);
87-
});
90+
Iter it = new Iter(iter, this.world);
91+
callback.accept(it);
92+
});
93+
}
8894
}
8995

9096
public int count() {
9197
this.checkClosed();
98+
try (Arena tmpArena = Arena.ofConfined()) {
99+
MemorySegment iter = flecs_h.ecs_query_iter(tmpArena, this.world.nativeHandle(), this.nativeQuery);
92100

93-
MemorySegment iter = flecs_h.ecs_query_iter(this.arena, this.world.nativeHandle(), this.nativeQuery);
101+
int total = 0;
102+
while (flecs_h.ecs_iter_next(iter)) {
103+
total += ecs_iter_t.count(iter);
104+
}
94105

95-
int total = 0;
96-
while (flecs_h.ecs_iter_next(iter)) {
97-
total += ecs_iter_t.count(iter);
106+
return total;
98107
}
99-
return total;
100108
}
101109

102110
public LongList entities() {

0 commit comments

Comments
 (0)