Lambda memory allocation optimizations
This commit is contained in:
@@ -356,30 +356,23 @@ public class World{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void raycastEach(int x0f, int y0f, int x1, int y1, Raycaster cons){
|
public void raycastEach(int x0f, int y0f, int x1, int y1, Raycaster cons){
|
||||||
int x0 = x0f;
|
int x0 = x0f, dx = Math.abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
|
||||||
int y0 = y0f;
|
int y0 = y0f, dy = Math.abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
|
||||||
int dx = Math.abs(x1 - x0);
|
int e2, err = dx - dy;
|
||||||
int dy = Math.abs(y1 - y0);
|
|
||||||
|
|
||||||
int sx = x0 < x1 ? 1 : -1;
|
|
||||||
int sy = y0 < y1 ? 1 : -1;
|
|
||||||
|
|
||||||
int err = dx - dy;
|
|
||||||
int e2;
|
|
||||||
while(true){
|
while(true){
|
||||||
|
|
||||||
if(cons.accept(x0, y0)) break;
|
if(cons.accept(x0, y0)) break;
|
||||||
if(x0 == x1 && y0 == y1) break;
|
if(x0 == x1 && y0 == y1) break;
|
||||||
|
|
||||||
e2 = 2 * err;
|
e2 = 2 * err;
|
||||||
if(e2 > -dy){
|
if(e2 > -dy){
|
||||||
err = err - dy;
|
err -= dy;
|
||||||
x0 = x0 + sx;
|
x0 += sx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(e2 < dx){
|
if(e2 < dx){
|
||||||
err = err + dx;
|
err += dx;
|
||||||
y0 = y0 + sy;
|
y0 += sy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.entities;
|
package mindustry.entities;
|
||||||
|
|
||||||
|
import arc.func.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
@@ -23,7 +24,9 @@ public class EntityCollisions{
|
|||||||
private Rect r2 = new Rect();
|
private Rect r2 = new Rect();
|
||||||
|
|
||||||
//entity collisions
|
//entity collisions
|
||||||
private Seq<Hitboxc> arrOut = new Seq<>();
|
private Seq<Hitboxc> arrOut = new Seq<>(Hitboxc.class);
|
||||||
|
private Cons<Hitboxc> hitCons = this::updateCollision;
|
||||||
|
private Cons<QuadTree> treeCons = tree -> tree.intersect(r2, arrOut);
|
||||||
|
|
||||||
public void moveCheck(Hitboxc entity, float deltax, float deltay, SolidPred solidCheck){
|
public void moveCheck(Hitboxc entity, float deltax, float deltay, SolidPred solidCheck){
|
||||||
if(!solidCheck.solid(entity.tileX(), entity.tileY())){
|
if(!solidCheck.solid(entity.tileX(), entity.tileY())){
|
||||||
@@ -36,7 +39,7 @@ public class EntityCollisions{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void move(Hitboxc entity, float deltax, float deltay, SolidPred solidCheck){
|
public void move(Hitboxc entity, float deltax, float deltay, SolidPred solidCheck){
|
||||||
if(Math.abs(deltax) < 0.0001f & Math.abs(deltay) < 0.0001f) return;
|
if(Math.abs(deltax) < 0.0001f & Math.abs(deltay) < 0.0001f) return;
|
||||||
|
|
||||||
boolean movedx = false;
|
boolean movedx = false;
|
||||||
|
|
||||||
@@ -213,28 +216,34 @@ public class EntityCollisions{
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends Hitboxc> void collide(EntityGroup<T> groupa){
|
public <T extends Hitboxc> void collide(EntityGroup<T> groupa){
|
||||||
groupa.each(solid -> {
|
groupa.each((Cons<T>)hitCons);
|
||||||
solid.hitbox(r1);
|
}
|
||||||
r1.x += (solid.lastX() - solid.getX());
|
|
||||||
r1.y += (solid.lastY() - solid.getY());
|
|
||||||
|
|
||||||
solid.hitbox(r2);
|
private void updateCollision(Hitboxc solid){
|
||||||
r2.merge(r1);
|
solid.hitbox(r1);
|
||||||
|
r1.x += (solid.lastX() - solid.getX());
|
||||||
|
r1.y += (solid.lastY() - solid.getY());
|
||||||
|
|
||||||
arrOut.clear();
|
solid.hitbox(r2);
|
||||||
|
r2.merge(r1);
|
||||||
|
|
||||||
//get all targets based on what entity wants to collide with
|
arrOut.clear();
|
||||||
solid.getCollisions(tree -> tree.intersect(r2, arrOut));
|
|
||||||
|
|
||||||
for(Hitboxc sc : arrOut){
|
//get all targets based on what entity wants to collide with
|
||||||
sc.hitbox(r1);
|
solid.getCollisions(treeCons);
|
||||||
if(r2.overlaps(r1)){
|
|
||||||
checkCollide(solid, sc);
|
var items = arrOut.items;
|
||||||
//break out of loop when this object hits something
|
int size = arrOut.size;
|
||||||
if(!solid.isAdded()) return;
|
|
||||||
}
|
for(int i = 0; i < size; i++){
|
||||||
|
Hitboxc sc = items[i];
|
||||||
|
sc.hitbox(r1);
|
||||||
|
if(r2.overlaps(r1)){
|
||||||
|
checkCollide(solid, sc);
|
||||||
|
//break out of loop when this object hits something
|
||||||
|
if(!solid.isAdded()) return;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface SolidPred{
|
public interface SolidPred{
|
||||||
|
|||||||
@@ -118,36 +118,7 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
|
|||||||
type.update(self());
|
type.update(self());
|
||||||
|
|
||||||
if(type.collidesTiles && type.collides && type.collidesGround){
|
if(type.collidesTiles && type.collides && type.collidesGround){
|
||||||
world.raycastEach(World.toTile(lastX()), World.toTile(lastY()), tileX(), tileY(), (x, y) -> {
|
tileRaycast(World.toTile(lastX()), World.toTile(lastY()), tileX(), tileY());
|
||||||
|
|
||||||
Building build = world.build(x, y);
|
|
||||||
if(build == null || !isAdded()) return false;
|
|
||||||
|
|
||||||
if(build.collide(self()) && type.testCollision(self(), build) && !build.dead() && (type.collidesTeam || build.team != team) && !(type.pierceBuilding && hasCollided(build.id))){
|
|
||||||
boolean remove = false;
|
|
||||||
|
|
||||||
float health = build.health;
|
|
||||||
|
|
||||||
if(build.team != team){
|
|
||||||
remove = build.collision(self());
|
|
||||||
}
|
|
||||||
|
|
||||||
if(remove || type.collidesTeam){
|
|
||||||
if(!type.pierceBuilding){
|
|
||||||
hit = true;
|
|
||||||
remove();
|
|
||||||
}else{
|
|
||||||
collided.add(build.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type.hitTile(self(), build, health, true);
|
|
||||||
|
|
||||||
return !type.pierceBuilding;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type.pierceCap != -1 && collided.size >= type.pierceCap){
|
if(type.pierceCap != -1 && collided.size >= type.pierceCap){
|
||||||
@@ -156,6 +127,55 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//copy-paste of World#raycastEach, inlined for lambda capture performance.
|
||||||
|
@Override
|
||||||
|
public void tileRaycast(int x0f, int y0f, int x1, int y1){
|
||||||
|
int x = x0f, dx = Math.abs(x1 - x), sx = x < x1 ? 1 : -1;
|
||||||
|
int y = y0f, dy = Math.abs(y1 - y), sy = y < y1 ? 1 : -1;
|
||||||
|
int e2, err = dx - dy;
|
||||||
|
|
||||||
|
while(true){
|
||||||
|
Building build = world.build(x, y);
|
||||||
|
if(build != null && isAdded() && build.collide(self()) && type.testCollision(self(), build)
|
||||||
|
&& !build.dead() && (type.collidesTeam || build.team != team) && !(type.pierceBuilding && hasCollided(build.id))){
|
||||||
|
|
||||||
|
boolean remove = false;
|
||||||
|
float health = build.health;
|
||||||
|
|
||||||
|
if(build.team != team){
|
||||||
|
remove = build.collision(self());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(remove || type.collidesTeam){
|
||||||
|
if(!type.pierceBuilding){
|
||||||
|
hit = true;
|
||||||
|
remove();
|
||||||
|
}else{
|
||||||
|
collided.add(build.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type.hitTile(self(), build, health, true);
|
||||||
|
|
||||||
|
//stop raycasting when building is hit
|
||||||
|
if(type.pierceBuilding) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(x == x1 && y == y1) break;
|
||||||
|
|
||||||
|
e2 = 2 * err;
|
||||||
|
if(e2 > -dy){
|
||||||
|
err -= dy;
|
||||||
|
x += sx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(e2 < dx){
|
||||||
|
err += dx;
|
||||||
|
y += sy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void draw(){
|
||||||
Draw.z(type.layer);
|
Draw.z(type.layer);
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ abstract class PuddleComp implements Posc, Puddlec, Drawc{
|
|||||||
|
|
||||||
@Import int id;
|
@Import int id;
|
||||||
@Import float x, y;
|
@Import float x, y;
|
||||||
|
@Import boolean added;
|
||||||
|
|
||||||
transient private boolean mismatch = false;
|
|
||||||
transient float accepting, updateTime, lastRipple = Time.time + Mathf.random(40f);
|
transient float accepting, updateTime, lastRipple = Time.time + Mathf.random(40f);
|
||||||
float amount;
|
float amount;
|
||||||
Tile tile;
|
Tile tile;
|
||||||
@@ -79,9 +79,12 @@ abstract class PuddleComp implements Posc, Puddlec, Drawc{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Puddles.get(tile) != self()){
|
if(Puddles.get(tile) != self() && added){
|
||||||
mismatch = true;
|
//force removal without pool free
|
||||||
remove();
|
Groups.all.remove(self());
|
||||||
|
Groups.draw.remove(self());
|
||||||
|
Groups.puddle.remove(self());
|
||||||
|
added = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,9 +137,7 @@ abstract class PuddleComp implements Posc, Puddlec, Drawc{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(){
|
public void remove(){
|
||||||
if(!mismatch){
|
Puddles.remove(tile);
|
||||||
Puddles.remove(tile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -48,11 +48,11 @@ public class Teams{
|
|||||||
return Geometry.findClosest(x, y, get(team).cores);
|
return Geometry.findClosest(x, y, get(team).cores);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean eachEnemyCore(Team team, Boolf<CoreBuild> ret){
|
public boolean anyEnemyCoresWithin(Team team, float x, float y, float radius){
|
||||||
for(TeamData data : active){
|
for(TeamData data : active){
|
||||||
if(team != data.team){
|
if(team != data.team){
|
||||||
for(CoreBuild tile : data.cores){
|
for(CoreBuild tile : data.cores){
|
||||||
if(ret.get(tile)){
|
if(tile.within(x, y, radius)){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ public class Build{
|
|||||||
if(closest != null && closest.team != team){
|
if(closest != null && closest.team != team){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}else if(state.teams.eachEnemyCore(team, core -> Mathf.dst(x * tilesize + type.offset, y * tilesize + type.offset, core.x, core.y) < state.rules.enemyCoreBuildRadius + type.size * tilesize / 2f)){
|
}else if(state.teams.anyEnemyCoresWithin(team, x * tilesize + type.offset, y * tilesize + type.offset, state.rules.enemyCoreBuildRadius + tilesize)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,4 +11,4 @@ android.useAndroidX=true
|
|||||||
#used for slow jitpack builds; TODO see if this actually works
|
#used for slow jitpack builds; TODO see if this actually works
|
||||||
http.socketTimeout=80000
|
http.socketTimeout=80000
|
||||||
http.connectionTimeout=80000
|
http.connectionTimeout=80000
|
||||||
archash=6b77c7f375e42e3049ab60b47bd0654becb5eab4
|
archash=f4e8a35c46e28dc68bb2cab17e42ef6db15ae72f
|
||||||
|
|||||||
Reference in New Issue
Block a user