Closed endison1986 closed 1 year ago
About this issue, I analysis source code, and found that the problem might be here. dev.dominion.ecs.engine.system.ClassIndex.java
public IndexKey getIndexKey(Object[] objects) {
int length = objects.length;
boolean[] checkArray = new boolean[index + length + 1];
int min = Integer.MAX_VALUE, max = 0;
for (int i = 0; i < length; i++) {
int value = getIndex(objects[i].getClass());
value = value == 0 ? getIndexOrAddClass(objects[i].getClass()) : value;
if (checkArray[value]) {
throw new IllegalArgumentException("Duplicate object types are not allowed");
}
checkArray[value] = true;
min = Math.min(value, min);
max = Math.max(value, max);
}
return new IndexKey(checkArray, min, max, length);
}
under lines has concurrency problem.
int value = getIndex(objects[i].getClass());
value = value == 0 ? getIndexOrAddClass(objects[i].getClass()) : value;
If I createEntity in multiple threads, getIndex
method will be called by multiple thread with result in zero. Also the getIndexOrAddClass
method will be called multiple times. So I add a synchronized block to fix this issue temporary, Hope you have better way.
private final Object lock = new Object();
@SuppressWarnings("ForLoopReplaceableByForEach")
public IndexKey getIndexKey(Object[] objects) {
int length = objects.length;
boolean[] checkArray = new boolean[index + length + 1];
int min = Integer.MAX_VALUE, max = 0;
for (int i = 0; i < length; i++) {
var componentClass = objects[i].getClass();
var value = getIndex(componentClass);
if (value == 0) {
synchronized (lock) {
value = getIndex(componentClass);
if (value == 0) {
value = getIndexOrAddClass(componentClass);
}
}
}
if (checkArray[value]) {
throw new IllegalArgumentException("Duplicate object types are not allowed");
}
checkArray[value] = true;
min = Math.min(value, min);
max = Math.max(value, max);
}
return new IndexKey(checkArray, min, max, length);
}
Thanks for reporting, I'll look into this issue after I fix issue #117 (still in progress)
Hi @endison1986, issue fixed by #122
Hi @enricostara I get a new error when I add a second component
B
Originally posted by @endison1986 in https://github.com/dominion-dev/dominion-ecs-java/issues/117#issuecomment-1362534115