Entity cleanup

This commit is contained in:
Anuken
2019-08-30 16:00:09 -04:00
parent f8f140090f
commit 39e0977231
10 changed files with 80 additions and 97 deletions

View File

@ -206,21 +206,21 @@ public class Vars implements Loadable{
pathfinder = new Pathfinder(); pathfinder = new Pathfinder();
entities = new Entities(); entities = new Entities();
playerGroup = entities.addGroup(Player.class).enableMapping(); playerGroup = entities.add(Player.class).enableMapping();
tileGroup = entities.addGroup(TileEntity.class, false); tileGroup = entities.add(TileEntity.class, false);
bulletGroup = entities.addGroup(Bullet.class).enableMapping(); bulletGroup = entities.add(Bullet.class).enableMapping();
effectGroup = entities.addGroup(EffectEntity.class, false); effectGroup = entities.add(EffectEntity.class, false);
groundEffectGroup = entities.addGroup(DrawTrait.class, false); groundEffectGroup = entities.add(DrawTrait.class, false);
puddleGroup = entities.addGroup(Puddle.class).enableMapping(); puddleGroup = entities.add(Puddle.class).enableMapping();
shieldGroup = entities.addGroup(ShieldEntity.class, false); shieldGroup = entities.add(ShieldEntity.class, false);
fireGroup = entities.addGroup(Fire.class).enableMapping(); fireGroup = entities.add(Fire.class).enableMapping();
unitGroups = new EntityGroup[Team.all.length]; unitGroups = new EntityGroup[Team.all.length];
for(Team team : Team.all){ for(Team team : Team.all){
unitGroups[team.ordinal()] = entities.addGroup(BaseUnit.class).enableMapping(); unitGroups[team.ordinal()] = entities.add(BaseUnit.class).enableMapping();
} }
for(EntityGroup<?> group : entities.getAllGroups()){ for(EntityGroup<?> group : entities.all()){
group.setRemoveListener(entity -> { group.setRemoveListener(entity -> {
if(entity instanceof SyncTrait && Net.client()){ if(entity instanceof SyncTrait && Net.client()){
netClient.addRemovedEntity((entity).getID()); netClient.addRemovedEntity((entity).getID());

View File

@ -12,7 +12,6 @@ import io.anuke.arc.util.io.ReusableByteInStream;
import io.anuke.arc.util.serialization.Base64Coder; import io.anuke.arc.util.serialization.Base64Coder;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Entities;
import io.anuke.mindustry.entities.EntityGroup; import io.anuke.mindustry.entities.EntityGroup;
import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest;
import io.anuke.mindustry.entities.traits.SyncTrait; import io.anuke.mindustry.entities.traits.SyncTrait;
@ -253,7 +252,7 @@ public class NetClient implements ApplicationListener{
netClient.byteStream.setBytes(Net.decompressSnapshot(data, dataLen)); netClient.byteStream.setBytes(Net.decompressSnapshot(data, dataLen));
DataInputStream input = netClient.dataStream; DataInputStream input = netClient.dataStream;
EntityGroup group = entities.getGroup(groupID); EntityGroup group = entities.get(groupID);
//go through each entity //go through each entity
for(int j = 0; j < amount; j++){ for(int j = 0; j < amount; j++){

View File

@ -15,7 +15,6 @@ import io.anuke.arc.util.CommandHandler.*;
import io.anuke.arc.util.io.*; import io.anuke.arc.util.io.*;
import io.anuke.mindustry.content.Blocks; import io.anuke.mindustry.content.Blocks;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Entities;
import io.anuke.mindustry.entities.EntityGroup; import io.anuke.mindustry.entities.EntityGroup;
import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest;
import io.anuke.mindustry.entities.traits.Entity; import io.anuke.mindustry.entities.traits.Entity;
@ -589,7 +588,7 @@ public class NetServer implements ApplicationListener{
viewport.setSize(player.con.viewWidth, player.con.viewHeight).setCenter(player.con.viewX, player.con.viewY); viewport.setSize(player.con.viewWidth, player.con.viewHeight).setCenter(player.con.viewX, player.con.viewY);
//check for syncable groups //check for syncable groups
for(EntityGroup<?> group : entities.getAllGroups()){ for(EntityGroup<?> group : entities.all()){
if(group.isEmpty() || !(group.all().get(0) instanceof SyncTrait)) continue; if(group.isEmpty() || !(group.all().get(0) instanceof SyncTrait)) continue;
//make sure mapping is enabled for this group //make sure mapping is enabled for this group

View File

@ -209,9 +209,9 @@ public class Renderer implements ApplicationListener{
blocks.floor.drawFloor(); blocks.floor.drawFloor();
draw(groundEffectGroup, e -> e instanceof BelowLiquidTrait); groundEffectGroup.draw(e -> e instanceof BelowLiquidTrait);
draw(puddleGroup); puddleGroup.draw();
draw(groundEffectGroup, e -> !(e instanceof BelowLiquidTrait)); groundEffectGroup.draw(e -> !(e instanceof BelowLiquidTrait));
blocks.processBlocks(); blocks.processBlocks();
@ -248,8 +248,8 @@ public class Renderer implements ApplicationListener{
bloom.capture(); bloom.capture();
} }
draw(bulletGroup); bulletGroup.draw();
draw(effectGroup); effectGroup.draw();
Draw.flush(); Draw.flush();
if(bloom != null && !pixelator.enabled()){ if(bloom != null && !pixelator.enabled()){
@ -257,15 +257,15 @@ public class Renderer implements ApplicationListener{
} }
overlays.drawBottom(); overlays.drawBottom();
draw(playerGroup, p -> true, Player::drawBuildRequests); playerGroup.draw(p -> true, Player::drawBuildRequests);
if(entities.countInBounds(shieldGroup) > 0){ if(shieldGroup.countInBounds() > 0){
if(settings.getBool("animatedshields") && Shaders.shield != null){ if(settings.getBool("animatedshields") && Shaders.shield != null){
Draw.flush(); Draw.flush();
shieldBuffer.begin(); shieldBuffer.begin();
graphics.clear(Color.CLEAR); graphics.clear(Color.CLEAR);
entities.draw(shieldGroup); shieldGroup.draw();
entities.draw(shieldGroup, shield -> true, shield -> ((ShieldEntity)shield).drawOver()); shieldGroup.draw(shield -> true, ShieldEntity::drawOver);
Draw.flush(); Draw.flush();
shieldBuffer.end(); shieldBuffer.end();
Draw.shader(Shaders.shield); Draw.shader(Shaders.shield);
@ -274,13 +274,13 @@ public class Renderer implements ApplicationListener{
Draw.color(); Draw.color();
Draw.shader(); Draw.shader();
}else{ }else{
entities.draw(shieldGroup, shield -> true, shield -> ((ShieldEntity)shield).drawSimple()); shieldGroup.draw(shield -> true, ShieldEntity::drawSimple);
} }
} }
overlays.drawTop(); overlays.drawTop();
draw(playerGroup, p -> !p.isDead() && !p.isLocal, Player::drawName); playerGroup.draw(p -> !p.isDead() && !p.isLocal, Player::drawName);
Draw.color(); Draw.color();
Draw.flush(); Draw.flush();
@ -297,12 +297,12 @@ public class Renderer implements ApplicationListener{
for(EntityGroup<? extends BaseUnit> group : unitGroups){ for(EntityGroup<? extends BaseUnit> group : unitGroups){
if(!group.isEmpty()){ if(!group.isEmpty()){
draw(group, unit -> !unit.isDead(), draw::accept); group.draw(unit -> !unit.isDead(), draw::accept);
} }
} }
if(!playerGroup.isEmpty()){ if(!playerGroup.isEmpty()){
draw(playerGroup, unit -> !unit.isDead(), draw::accept); playerGroup.draw(unit -> !unit.isDead(), draw::accept);
} }
Draw.color(); Draw.color();
@ -314,12 +314,12 @@ public class Renderer implements ApplicationListener{
for(EntityGroup<? extends BaseUnit> group : unitGroups){ for(EntityGroup<? extends BaseUnit> group : unitGroups){
if(!group.isEmpty()){ if(!group.isEmpty()){
draw(group, unit -> unit.isFlying() && !unit.isDead(), baseUnit -> baseUnit.drawShadow(trnsX, trnsY)); group.draw(unit -> unit.isFlying() && !unit.isDead(), baseUnit -> baseUnit.drawShadow(trnsX, trnsY));
} }
} }
if(!playerGroup.isEmpty()){ if(!playerGroup.isEmpty()){
draw(playerGroup, unit -> unit.isFlying() && !unit.isDead(), player -> player.drawShadow(trnsX, trnsY)); playerGroup.draw(unit -> unit.isFlying() && !unit.isDead(), player -> player.drawShadow(trnsX, trnsY));
} }
Draw.color(); Draw.color();
@ -331,29 +331,17 @@ public class Renderer implements ApplicationListener{
if(group.count(p -> p.isFlying() == flying) + playerGroup.count(p -> p.isFlying() == flying && p.getTeam() == team) == 0 && flying) continue; if(group.count(p -> p.isFlying() == flying) + playerGroup.count(p -> p.isFlying() == flying && p.getTeam() == team) == 0 && flying) continue;
draw(unitGroups[team.ordinal()], u -> u.isFlying() == flying && !u.isDead(), Unit::drawUnder); unitGroups[team.ordinal()].draw(u -> u.isFlying() == flying && !u.isDead(), Unit::drawUnder);
draw(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team && !p.isDead(), Unit::drawUnder); playerGroup.draw(p -> p.isFlying() == flying && p.getTeam() == team && !p.isDead(), Unit::drawUnder);
draw(unitGroups[team.ordinal()], u -> u.isFlying() == flying && !u.isDead(), Unit::drawAll); unitGroups[team.ordinal()].draw(u -> u.isFlying() == flying && !u.isDead(), Unit::drawAll);
draw(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team, Unit::drawAll); playerGroup.draw(p -> p.isFlying() == flying && p.getTeam() == team, Unit::drawAll);
draw(unitGroups[team.ordinal()], u -> u.isFlying() == flying && !u.isDead(), Unit::drawOver); unitGroups[team.ordinal()].draw(u -> u.isFlying() == flying && !u.isDead(), Unit::drawOver);
draw(playerGroup, p -> p.isFlying() == flying && p.getTeam() == team, Unit::drawOver); playerGroup.draw(p -> p.isFlying() == flying && p.getTeam() == team, Unit::drawOver);
} }
} }
public <T extends DrawTrait> void draw(EntityGroup<T> group){
draw(group, t -> true, DrawTrait::draw);
}
public <T extends DrawTrait> void draw(EntityGroup<T> group, Predicate<T> toDraw){
draw(group, toDraw, DrawTrait::draw);
}
public <T extends DrawTrait> void draw(EntityGroup<T> group, Predicate<T> toDraw, Consumer<T> drawer){
entities.draw(group, toDraw, drawer);
}
public void scaleCamera(float amount){ public void scaleCamera(float amount){
targetscale += amount; targetscale += amount;
clampScale(); clampScale();

View File

@ -178,7 +178,7 @@ public class World{
addDarkness(tiles); addDarkness(tiles);
} }
entities.getAllGroups().each(group -> group.resize(-finalWorldBounds, -finalWorldBounds, tiles.length * tilesize + finalWorldBounds * 2, tiles[0].length * tilesize + finalWorldBounds * 2)); entities.all().each(group -> group.resize(-finalWorldBounds, -finalWorldBounds, tiles.length * tilesize + finalWorldBounds * 2, tiles[0].length * tilesize + finalWorldBounds * 2));
generating = false; generating = false;
Events.fire(new WorldLoadEvent()); Events.fire(new WorldLoadEvent());

View File

@ -1,17 +1,11 @@
package io.anuke.mindustry.entities; package io.anuke.mindustry.entities;
import io.anuke.arc.*;
import io.anuke.arc.collection.*; import io.anuke.arc.collection.*;
import io.anuke.arc.function.*;
import io.anuke.arc.graphics.*;
import io.anuke.arc.math.geom.*;
import io.anuke.mindustry.entities.traits.*; import io.anuke.mindustry.entities.traits.*;
/** Simple container for managing entity groups.*/
public class Entities{ public class Entities{
private final Array<EntityGroup<?>> groupArray = new Array<>(); private final Array<EntityGroup<?>> groupArray = new Array<>();
private final Rectangle viewport = new Rectangle();
private final boolean clip = true;
private int count = 0;
public void clear(){ public void clear(){
for(EntityGroup group : groupArray){ for(EntityGroup group : groupArray){
@ -19,52 +13,21 @@ public class Entities{
} }
} }
public EntityGroup<?> getGroup(int id){ public EntityGroup<?> get(int id){
return groupArray.get(id); return groupArray.get(id);
} }
public Array<EntityGroup<?>> getAllGroups(){ public Array<EntityGroup<?>> all(){
return groupArray; return groupArray;
} }
public <T extends Entity> EntityGroup<T> addGroup(Class<T> type){ public <T extends Entity> EntityGroup<T> add(Class<T> type){
return addGroup(type, true); return add(type, true);
} }
public <T extends Entity> EntityGroup<T> addGroup(Class<T> type, boolean useTree){ public <T extends Entity> EntityGroup<T> add(Class<T> type, boolean useTree){
EntityGroup<T> group = new EntityGroup<>(groupArray.size, type, useTree); EntityGroup<T> group = new EntityGroup<>(groupArray.size, type, useTree);
groupArray.add(group); groupArray.add(group);
return group; return group;
} }
public int countInBounds(EntityGroup<?> group){
count = 0;
draw(group, e -> true, e -> count++);
return count;
}
public void draw(EntityGroup<?> group){
draw(group, e -> true);
}
public <T extends DrawTrait> void draw(EntityGroup<?> group, Predicate<T> toDraw){
draw(group, toDraw, DrawTrait::draw);
}
@SuppressWarnings("unchecked")
public <T extends DrawTrait> void draw(EntityGroup<?> group, Predicate<T> toDraw, Consumer<T> cons){
if(clip){
Camera cam = Core.camera;
viewport.set(cam.position.x - cam.width / 2, cam.position.y - cam.height / 2, cam.width, cam.height);
}
for(Entity e : group.all()){
if(!(e instanceof DrawTrait) || !toDraw.test((T)e) || !e.isAdded()) continue;
DrawTrait draw = (DrawTrait)e;
if(!clip || viewport.overlaps(draw.getX() - draw.drawSize()/2f, draw.getY() - draw.drawSize()/2f, draw.drawSize(), draw.drawSize())){
cons.accept((T)e);
}
}
}
} }

View File

@ -1,12 +1,15 @@
package io.anuke.mindustry.entities; package io.anuke.mindustry.entities;
import io.anuke.arc.*;
import io.anuke.arc.collection.*; import io.anuke.arc.collection.*;
import io.anuke.arc.function.*; import io.anuke.arc.function.*;
import io.anuke.arc.graphics.*;
import io.anuke.arc.math.geom.*; import io.anuke.arc.math.geom.*;
import io.anuke.mindustry.entities.traits.*; import io.anuke.mindustry.entities.traits.*;
import static io.anuke.mindustry.Vars.collisions; import static io.anuke.mindustry.Vars.collisions;
@SuppressWarnings("unchecked")
public class EntityGroup<T extends Entity>{ public class EntityGroup<T extends Entity>{
private final boolean useTree; private final boolean useTree;
private final int id; private final int id;
@ -19,6 +22,10 @@ public class EntityGroup<T extends Entity>{
private Consumer<T> removeListener; private Consumer<T> removeListener;
private Consumer<T> addListener; private Consumer<T> addListener;
private final Rectangle viewport = new Rectangle();
private final boolean clip = true;
private int count = 0;
public EntityGroup(int id, Class<T> type, boolean useTree){ public EntityGroup(int id, Class<T> type, boolean useTree){
this.useTree = useTree; this.useTree = useTree;
this.id = id; this.id = id;
@ -41,6 +48,34 @@ public class EntityGroup<T extends Entity>{
} }
} }
public int countInBounds(){
count = 0;
draw(e -> true, e -> count++);
return count;
}
public void draw(){
draw(e -> true);
}
public void draw(Predicate<T> toDraw){
draw(toDraw, t -> ((DrawTrait)t).draw());
}
public void draw(Predicate<T> toDraw, Consumer<T> cons){
Camera cam = Core.camera;
viewport.set(cam.position.x - cam.width / 2, cam.position.y - cam.height / 2, cam.width, cam.height);
for(Entity e : all()){
if(!(e instanceof DrawTrait) || !toDraw.test((T)e) || !e.isAdded()) continue;
DrawTrait draw = (DrawTrait)e;
if(viewport.overlaps(draw.getX() - draw.drawSize()/2f, draw.getY() - draw.drawSize()/2f, draw.drawSize(), draw.drawSize())){
cons.accept((T)e);
}
}
}
public boolean useTree(){ public boolean useTree(){
return useTree; return useTree;
} }

View File

@ -55,7 +55,7 @@ public class Pixelator implements Disposable{
Draw.rect(Draw.wrap(buffer.getTexture()), Core.camera.position.x, Core.camera.position.y, Core.camera.width, -Core.camera.height); Draw.rect(Draw.wrap(buffer.getTexture()), Core.camera.position.x, Core.camera.position.y, Core.camera.width, -Core.camera.height);
Draw.blend(); Draw.blend();
renderer.draw(playerGroup, p -> !p.isDead() && !p.isLocal, Player::drawName); playerGroup.draw(p -> !p.isDead() && !p.isLocal, Player::drawName);
Core.camera.position.set(px, py); Core.camera.position.set(px, py);
Core.settings.put("animatedwater", hadWater); Core.settings.put("animatedwater", hadWater);

View File

@ -209,7 +209,7 @@ public abstract class SaveVersion extends SaveFileReader{
//write entity chunk //write entity chunk
int groups = 0; int groups = 0;
for(EntityGroup<?> group : entities.getAllGroups()){ for(EntityGroup<?> group : entities.all()){
if(!group.isEmpty() && group.all().get(0) instanceof SaveTrait){ if(!group.isEmpty() && group.all().get(0) instanceof SaveTrait){
groups++; groups++;
} }
@ -217,7 +217,7 @@ public abstract class SaveVersion extends SaveFileReader{
stream.writeByte(groups); stream.writeByte(groups);
for(EntityGroup<?> group : entities.getAllGroups()){ for(EntityGroup<?> group : entities.all()){
if(!group.isEmpty() && group.all().get(0) instanceof SaveTrait){ if(!group.isEmpty() && group.all().get(0) instanceof SaveTrait){
stream.writeInt(group.size()); stream.writeInt(group.size());
for(Entity entity : group.all()){ for(Entity entity : group.all()){

View File

@ -5,7 +5,6 @@ import io.anuke.annotations.Annotations.WriteClass;
import io.anuke.arc.graphics.Color; import io.anuke.arc.graphics.Color;
import io.anuke.mindustry.entities.Effects; import io.anuke.mindustry.entities.Effects;
import io.anuke.mindustry.entities.Effects.Effect; import io.anuke.mindustry.entities.Effects.Effect;
import io.anuke.mindustry.entities.Entities;
import io.anuke.mindustry.entities.bullet.Bullet; import io.anuke.mindustry.entities.bullet.Bullet;
import io.anuke.mindustry.entities.bullet.BulletType; import io.anuke.mindustry.entities.bullet.BulletType;
import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest; import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest;
@ -58,7 +57,7 @@ public class TypeIO{
byte gid = buffer.get(); byte gid = buffer.get();
if(gid == -1) return null; if(gid == -1) return null;
int id = buffer.getInt(); int id = buffer.getInt();
return (Unit)entities.getGroup(gid).getByID(id); return (Unit)entities.get(gid).getByID(id);
} }
@WriteClass(ShooterTrait.class) @WriteClass(ShooterTrait.class)
@ -71,7 +70,7 @@ public class TypeIO{
public static ShooterTrait readShooter(ByteBuffer buffer){ public static ShooterTrait readShooter(ByteBuffer buffer){
byte gid = buffer.get(); byte gid = buffer.get();
int id = buffer.getInt(); int id = buffer.getInt();
return (ShooterTrait)entities.getGroup(gid).getByID(id); return (ShooterTrait)entities.get(gid).getByID(id);
} }
@WriteClass(Bullet.class) @WriteClass(Bullet.class)