Cleanup, optimization

This commit is contained in:
Anuken
2020-05-01 16:35:18 -04:00
parent 3101fc8056
commit 135b87fdb2
20 changed files with 138 additions and 154 deletions

View File

@@ -2,13 +2,17 @@ package mindustry.async;
import arc.*;
import arc.struct.*;
import mindustry.*;
import mindustry.game.EventType.*;
import java.util.concurrent.*;
public class AsyncLogic{
//all processes to be executed each frame
private Array<AsyncProcess> processes = Array.with(new PhysicsProcess(), new CollisionProcess());
private Array<AsyncProcess> processes = Array.with(
new PhysicsProcess(),
Vars.teamIndex = new TeamIndexProcess()
);
//futures to be awaited
private Array<Future<?>> futures = new Array<>();
@@ -46,7 +50,9 @@ public class AsyncLogic{
//submit all tasks
for(AsyncProcess p : processes){
futures.add(executor.submit(p::process));
if(p.shouldProcess()){
futures.add(executor.submit(p::process));
}
}
}

View File

@@ -3,17 +3,21 @@ package mindustry.async;
public interface AsyncProcess{
/** Sync. Called when the world loads. */
void init();
default void init(){}
/** Sync. Called when the world resets. */
void reset();
default void reset(){}
/** Sync. Called at the beginning of the main loop. */
void begin();
default void begin(){}
/** Async. Called in a separate thread. */
void process();
default void process(){}
/** Sync. Called in the end of the main loop. */
void end();
default void end(){}
default boolean shouldProcess(){
return true;
}
}

View File

@@ -1,35 +1,21 @@
package mindustry.async;
import arc.box2d.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import arc.util.pooling.*;
import arc.util.pooling.Pool.*;
import mindustry.entities.*;
import mindustry.gen.*;
import static mindustry.Vars.*;
/**
* Processes collisions.
*
* Each entity is assigned a final filter layer, then given a body and inserted into a physics world.
*
* Async:
* The body's position is set to its entity position, and the body velocity is set to the entity delta.
* Collisions are resolved and stored in a list, then processed synchronously.
*
*/
//TODO remove
public class CollisionProcess implements AsyncProcess{
private Pool<CollisionRef> pool = Pools.get(CollisionRef.class, CollisionRef::new);
//private Physics physics;
private QuadTree<Collisionc> tree;
private Array<Collisionc> insertEntities = new Array<>();
private Array<Collisionc> checkEntities = new Array<>();
private QuadTree<Hitboxc> tree;
private Array<Hitboxc> insertEntities = new Array<>();
private Array<Hitboxc> checkEntities = new Array<>();
private Array<Collisionc> arrOut = new Array<>();
private Array<Hitboxc> arrOut = new Array<>();
private Vec2 l1 = new Vec2();
private Rect r1 = new Rect();
@@ -38,9 +24,9 @@ public class CollisionProcess implements AsyncProcess{
//private BodyDef def;
//private FixtureDef fdef;
private EntityGroup<? extends Collisionc> inserted = Groups.unit;
private EntityGroup<? extends Collisionc> checked = Groups.bullet;
private Array<Collisionc> collisions = new Array<>(Collisionc.class);
private EntityGroup<? extends Hitboxc> inserted = Groups.unit;
private EntityGroup<? extends Hitboxc> checked = Groups.bullet;
private Array<Hitboxc> collisions = new Array<>(Hitboxc.class);
@Override
public void begin(){
@@ -65,11 +51,11 @@ public class CollisionProcess implements AsyncProcess{
tree.clear();
//insert targets
for(Collisionc ins : insertEntities){
for(Hitboxc ins : insertEntities){
tree.insert(ins);
}
for(Collisionc solid : checked){
for(Hitboxc solid : checked){
solid.hitbox(r1);
r1.x += (solid.lastX() - solid.getX());
r1.y += (solid.lastY() - solid.getY());
@@ -78,9 +64,9 @@ public class CollisionProcess implements AsyncProcess{
r2.merge(r1);
arrOut.clear();
tree.getIntersect(arrOut, r2);
tree.intersect(r2, arrOut);
for(Collisionc sc : arrOut){
for(Hitboxc sc : arrOut){
sc.hitbox(r1);
if(r2.overlaps(r1)){
checkCollide(solid, sc);
@@ -99,8 +85,8 @@ public class CollisionProcess implements AsyncProcess{
//processes anything that happened
for(int i = 0; i < collisions.size; i += 2){
Collisionc a = collisions.items[i];
Collisionc b = collisions.items[i + 1];
Hitboxc a = collisions.items[i];
Hitboxc b = collisions.items[i + 1];
//TODO incorrect
float cx = (a.x() + b.x())/2f, cy = (a.y() + b.y())/2f;
@@ -124,7 +110,7 @@ public class CollisionProcess implements AsyncProcess{
tree = new QuadTree<>(new Rect(-finalWorldBounds, -finalWorldBounds, world.width() * tilesize + finalWorldBounds * 2, world.height() * tilesize + finalWorldBounds * 2));
}
private void checkCollide(Collisionc a, Collisionc b){
private void checkCollide(Hitboxc a, Hitboxc b){
a.hitbox(this.r1);
b.hitbox(this.r2);
@@ -201,27 +187,4 @@ public class CollisionProcess implements AsyncProcess{
return true;
}
}
public static class CollisionRef implements Poolable{
Collisionc entity;
Body body;
Vec2 velocity = new Vec2(), position = new Vec2();
public CollisionRef set(Collisionc entity, Body body){
this.entity = entity;
this.body = body;
position.set(entity);
return this;
}
@Override
public void reset(){
entity = null;
body = null;
velocity.setZero();
position.setZero();
}
}
}

View File

@@ -0,0 +1,50 @@
package mindustry.async;
import arc.math.geom.*;
import arc.struct.*;
import mindustry.*;
import mindustry.game.*;
import mindustry.game.Teams.*;
import mindustry.gen.*;
/** Creates quadtrees per unit team. */
public class TeamIndexProcess implements AsyncProcess{
private QuadTree<Unitc>[] trees = new QuadTree[Team.all().length];
private Array<Team> active = new Array<>();
public QuadTree<Unitc> tree(Team team){
if(trees[team.uid] == null) trees[team.uid] = new QuadTree<>(Vars.world.getQuadBounds(new Rect()));
return trees[team.uid];
}
@Override
public void reset(){
active.clear();
trees = new QuadTree[Team.all().length];
}
@Override
public void begin(){
for(TeamData data : Vars.state.teams.getActive()){
if(!active.contains(data.team)){
active.add(data.team);
}
}
for(Team team : active){
if(trees[team.uid] != null){
trees[team.uid].clear();
}
}
for(Unitc unit : Groups.unit){
tree(unit.team()).insert(unit);
}
}
@Override
public boolean shouldProcess(){
return false;
}
}