Faster entity removal

This commit is contained in:
Anuken
2022-12-14 16:58:58 -05:00
parent 7f292b14a7
commit 243c50be02
4 changed files with 91 additions and 5 deletions

View File

@@ -20,6 +20,7 @@ public class EntityGroup<T extends Entityc> implements Iterable<T>{
private final Seq<T> intersectArray = new Seq<>();
private final Rect viewport = new Rect();
private final Rect intersectRect = new Rect();
private final EntityIndexer indexer;
private IntMap<T> map;
private QuadTree tree;
private boolean clearing;
@@ -36,6 +37,10 @@ public class EntityGroup<T extends Entityc> implements Iterable<T>{
}
public EntityGroup(Class<T> type, boolean spatial, boolean mapping){
this(type, spatial, mapping, null);
}
public EntityGroup(Class<T> type, boolean spatial, boolean mapping, EntityIndexer indexer){
array = new Seq<>(false, 32, type);
if(spatial){
@@ -45,6 +50,8 @@ public class EntityGroup<T extends Entityc> implements Iterable<T>{
if(mapping){
map = new IntMap<>();
}
this.indexer = indexer;
}
/** @return entities with colliding IDs, or an empty array. */
@@ -107,7 +114,7 @@ public class EntityGroup<T extends Entityc> implements Iterable<T>{
}
public boolean useTree(){
return map != null;
return tree != null;
}
public boolean mappingEnabled(){
@@ -183,12 +190,25 @@ public class EntityGroup<T extends Entityc> implements Iterable<T>{
}
}
public int addIndex(T type){
int index = array.size;
add(type);
return index;
}
public void remove(T type){
if(clearing) return;
if(type == null) throw new RuntimeException("Cannot remove a null entity!");
int idx = array.indexOf(type, true);
if(idx != -1){
array.remove(idx);
//fix incorrect HEAD index since it was swapped
if(array.size > 0 && idx != array.size){
var swapped = array.items[idx];
indexer.change(swapped, idx);
}
if(map != null){
map.remove(type.id());
}
@@ -200,6 +220,32 @@ public class EntityGroup<T extends Entityc> implements Iterable<T>{
}
}
public void removeIndex(T type, int position){
if(clearing) return;
if(type == null) throw new RuntimeException("Cannot remove a null entity!");
if(position != -1 && position < array.size){
//swap head with current
if(array.size > 1){
var head = array.items[array.size - 1];
indexer.change(head, position);
array.items[position] = head;
}
array.size --;
array.items[array.size] = null;
if(map != null){
map.remove(type.id());
}
//fix iteration index when removing
if(index >= position){
index --;
}
}
}
public void clear(){
clearing = true;

View File

@@ -0,0 +1,7 @@
package mindustry.entities;
import mindustry.gen.*;
public interface EntityIndexer{
void change(Entityc t, int index);
}

View File

@@ -137,6 +137,12 @@ public class CanvasBlock extends Block{
@Override
public void draw(){
if(!renderer.drawDisplays){
super.draw();
return;
}
if(blending == 0){
super.draw();
}