SteamWar/BauSystem2.0
Archiviert
12
0

Optimize Laufbau performance
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Signed-off-by: yoyosource <yoyosource@nidido.de>
Dieser Commit ist enthalten in:
yoyosource 2023-09-02 15:30:48 +02:00
Ursprung 6400e20bbb
Commit db349c2a05
5 geänderte Dateien mit 48 neuen und 37 gelöschten Zeilen

Datei anzeigen

@ -49,11 +49,19 @@ public class Laufbau {
@Getter @Getter
private EditSession editSession; private EditSession editSession;
private int factor;
public Laufbau(Player player, Location pos1, Location pos2, boolean preferingBlastResistance) { public Laufbau(Player player, Location pos1, Location pos2, boolean preferingBlastResistance) {
this.world = pos1.getWorld(); this.world = pos1.getWorld();
this.pos1 = new Location(world, Math.min(pos1.getBlockX(), pos2.getBlockX()), Math.min(pos1.getBlockY(), pos2.getBlockY()), Math.min(pos1.getBlockZ(), pos2.getBlockZ())); this.pos1 = new Location(world, Math.min(pos1.getBlockX(), pos2.getBlockX()), Math.min(pos1.getBlockY(), pos2.getBlockY()), Math.min(pos1.getBlockZ(), pos2.getBlockZ()));
this.pos2 = new Location(world, Math.max(pos1.getBlockX(), pos2.getBlockX()), Math.max(pos1.getBlockY(), pos2.getBlockY()), Math.max(pos1.getBlockZ(), pos2.getBlockZ())); this.pos2 = new Location(world, Math.max(pos1.getBlockX(), pos2.getBlockX()), Math.max(pos1.getBlockY(), pos2.getBlockY()), Math.max(pos1.getBlockZ(), pos2.getBlockZ()));
Vector selectionSize = pos2.toVector().subtract(pos1.toVector());
int xFactor = (int) (Math.abs(selectionSize.getX()) / 12.375);
int yFactor = (int) (Math.abs(selectionSize.getY()) / 7.125);
int zFactor = (int) (Math.abs(selectionSize.getZ()) / 9.875);
factor = Math.max(Math.max(xFactor, Math.max(yFactor, zFactor)), 8);
filteringTracesState = new FilteringTracesState(world, this::inRegion); filteringTracesState = new FilteringTracesState(world, this::inRegion);
editSession = WorldEditUtils.getEditSession(player); editSession = WorldEditUtils.getEditSession(player);
@ -95,10 +103,10 @@ public class Laufbau {
return; return;
} }
if (processingTracesState != null) { if (processingTracesState != null) {
creatingLaufState = new CreatingLaufState(processingTracesState.getBlocks(), processingTracesState.getCuboidList(), world, editSession, elements); creatingLaufState = new CreatingLaufState(processingTracesState.getBlocks(), processingTracesState.getCuboidIntersectionCache(), world, editSession, elements, factor);
return; return;
} }
processingTracesState = new ProcessingTracesState(filteringTracesState.getTntPositions(), world, this::inRegion); processingTracesState = new ProcessingTracesState(filteringTracesState.getTntPositions(), this::inRegion, factor);
} }
public String actionBarMessage(Player p) { public String actionBarMessage(Player p) {

Datei anzeigen

@ -46,6 +46,7 @@ public class LaufbauCommand extends SWCommand {
BauSystem.MESSAGE.send("LAUFBAU_NO_WORLDEDIT", player); BauSystem.MESSAGE.send("LAUFBAU_NO_WORLDEDIT", player);
return; return;
} }
Laufbau laufbau = new Laufbau(player, selection.getKey(), selection.getValue(), preferingBlastResistance); Laufbau laufbau = new Laufbau(player, selection.getKey(), selection.getValue(), preferingBlastResistance);
new BukkitRunnable() { new BukkitRunnable() {
@Override @Override

Datei anzeigen

@ -32,11 +32,7 @@ import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.ArrayList; import java.util.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class CreatingLaufState implements LaufbauState { public class CreatingLaufState implements LaufbauState {
@ -51,22 +47,24 @@ public class CreatingLaufState implements LaufbauState {
private long start = System.currentTimeMillis(); private long start = System.currentTimeMillis();
private List<Point> blocks; private List<Point> blocks;
private List<Cuboid> cuboids; private Map<Point, Set<Cuboid>> cuboidIntersectionCache;
private List<Point> outerPoints = new ArrayList<>(); private List<Point> outerPoints = new ArrayList<>();
private Set<Point> innerPoints = new HashSet<>(); private Set<Point> innerPoints = new HashSet<>();
private World world; private World world;
private EditSession editSession; private EditSession editSession;
private List<BlockBoundingBox> elements; private List<BlockBoundingBox> elements;
private int factor;
private int operations = 0; private int operations = 0;
private int totalOperations; private int totalOperations;
public CreatingLaufState(Set<Point> blocks, List<Cuboid> cuboids, World world, EditSession editSession, List<BlockBoundingBox> elements) { public CreatingLaufState(Set<Point> blocks, Map<Point, Set<Cuboid>> cuboidIntersectionCache, World world, EditSession editSession, List<BlockBoundingBox> elements, int factor) {
this.blocks = new ArrayList<>(blocks); this.blocks = new ArrayList<>(blocks);
this.cuboids = cuboids; this.cuboidIntersectionCache = cuboidIntersectionCache;
this.world = world; this.world = world;
this.editSession = editSession; this.editSession = editSession;
this.elements = elements; this.elements = elements;
this.factor = factor;
totalOperations = blocks.size() * 2; totalOperations = blocks.size() * 2;
} }
@ -90,7 +88,7 @@ public class CreatingLaufState implements LaufbauState {
Cuboid tempCuboid = ONE.add(point); Cuboid tempCuboid = ONE.add(point);
Cuboid aboveHalfTempCuboid = ABOVE_HALF.add(point); Cuboid aboveHalfTempCuboid = ABOVE_HALF.add(point);
List<Cuboid> intersectedCuboids = new ArrayList<>(); List<Cuboid> intersectedCuboids = new ArrayList<>();
for (Cuboid cuboid : cuboids) { for (Cuboid cuboid : cuboidIntersectionCache.get(point.divide(factor))) {
if (cuboid.intersects(tempCuboid)) { if (cuboid.intersects(tempCuboid)) {
isInCuboid = true; isInCuboid = true;
intersectedCuboids.add(cuboid); intersectedCuboids.add(cuboid);
@ -118,34 +116,36 @@ public class CreatingLaufState implements LaufbauState {
} }
private void calcInnerBlock(Point point, List<Cuboid> neededCuboids) { private void calcInnerBlock(Point point, List<Cuboid> neededCuboids) {
List<BlockBoundingBox> blockDataWithBoundingBoxList = new ArrayList<>(); BlockBoundingBox highestBlockBoundingBox = null;
for (BlockBoundingBox blockDataWithBoundingBox : elements) { for (BlockBoundingBox blockDataWithBoundingBox : elements) {
List<Cuboid> cuboids = blockDataWithBoundingBox.getCuboidList().stream().map(c -> c.add(point)).collect(Collectors.toList());
boolean isInCuboid = false; boolean isInCuboid = false;
for (Cuboid cuboid : neededCuboids) { for (Cuboid cuboid : neededCuboids) {
if (cuboids.stream().anyMatch(cuboid::intersects)) { for (Cuboid currentCuboid : blockDataWithBoundingBox.getCuboidList()) {
if (cuboid.intersects(currentCuboid.add(point))) {
isInCuboid = true; isInCuboid = true;
break; break;
} }
} }
if (!isInCuboid) { if (isInCuboid) {
blockDataWithBoundingBoxList.add(blockDataWithBoundingBox);
break; break;
} }
} }
if (blockDataWithBoundingBoxList.isEmpty()) { if (!isInCuboid) {
highestBlockBoundingBox = blockDataWithBoundingBox;
break;
}
}
if (highestBlockBoundingBox == null) {
return; return;
} }
BlockBoundingBox highest = blockDataWithBoundingBoxList.get(0);
Location location = new Location(world, point.getX(), point.getY(), point.getZ()); Location location = new Location(world, point.getX(), point.getY(), point.getZ());
if (!location.getBlock().getType().isAir()) { if (!location.getBlock().getType().isAir()) {
return; return;
} }
try { try {
BaseBlock block = BukkitAdapter.adapt(highest.blockData).toBaseBlock(); BaseBlock block = BukkitAdapter.adapt(highestBlockBoundingBox.blockData).toBaseBlock();
if (highest.blockConsumer != null) highest.blockConsumer.accept(block); if (highestBlockBoundingBox.blockConsumer != null) highestBlockBoundingBox.blockConsumer.accept(block);
editSession.setBlock(BukkitAdapter.asBlockVector(location), block); editSession.setBlock(BukkitAdapter.asBlockVector(location), block);
} catch (MaxChangedBlocksException e) { } catch (MaxChangedBlocksException e) {
e.printStackTrace(); e.printStackTrace();

Datei anzeigen

@ -24,15 +24,10 @@ import de.steamwar.bausystem.features.slaves.laufbau.Cuboid;
import de.steamwar.bausystem.features.tracer.TNTPosition; import de.steamwar.bausystem.features.tracer.TNTPosition;
import de.steamwar.bausystem.region.Point; import de.steamwar.bausystem.region.Point;
import lombok.Getter; import lombok.Getter;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.util.ArrayList; import java.util.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiPredicate; import java.util.function.BiPredicate;
public class ProcessingTracesState implements LaufbauState { public class ProcessingTracesState implements LaufbauState {
@ -41,28 +36,29 @@ public class ProcessingTracesState implements LaufbauState {
private int totalCuboids; private int totalCuboids;
private List<TNTPosition> tntPositionList; private List<TNTPosition> tntPositionList;
private World world;
private BiPredicate<Vector, Integer> inRegionCheck; private BiPredicate<Vector, Integer> inRegionCheck;
private int factor;
private List<Cuboid> toExpand = new ArrayList<>(); private List<Cuboid> toExpand = new ArrayList<>();
@Getter private int cuboidsDone = 0;
private List<Cuboid> cuboidList = new ArrayList<>();
@Getter @Getter
private Set<Point> blocks = new HashSet<>(); private Set<Point> blocks = new HashSet<>();
public ProcessingTracesState(List<TNTPosition> tntPositionList, World world, BiPredicate<Vector, Integer> inRegionCheck) { @Getter
private Map<Point, Set<Cuboid>> cuboidIntersectionCache = new HashMap<>();
public ProcessingTracesState(List<TNTPosition> tntPositionList, BiPredicate<Vector, Integer> inRegionCheck, int factor) {
this.tntPositionList = tntPositionList; this.tntPositionList = tntPositionList;
this.totalCuboids = tntPositionList.stream().mapToInt(tntPosition -> tntPosition.getPreviousLocation() == null ? 1 : 3).sum(); this.totalCuboids = tntPositionList.stream().mapToInt(tntPosition -> tntPosition.getPreviousLocation() == null ? 1 : 3).sum();
this.world = world;
this.inRegionCheck = inRegionCheck; this.inRegionCheck = inRegionCheck;
this.factor = factor;
} }
@Override @Override
public String actionBarMessage(Player p) { public String actionBarMessage(Player p) {
return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_PROCESSING_TRACES", p), totalCuboids - cuboidList.size(), totalCuboids, eta(p, start, totalCuboids - cuboidList.size(), totalCuboids)); return BauSystem.MESSAGE.parse("LAUFBAU_SIMPLE_PROGRESS", p, BauSystem.MESSAGE.parse("LAUFBAU_STATE_PROCESSING_TRACES", p), cuboidsDone, totalCuboids, eta(p, start, cuboidsDone, totalCuboids));
} }
@Override @Override
@ -101,14 +97,16 @@ public class ProcessingTracesState implements LaufbauState {
} }
private void expandCuboid(Cuboid cuboid) { private void expandCuboid(Cuboid cuboid) {
cuboidList.add(cuboid); cuboidsDone++;
for (double x = cuboid.getX() - 2; x < cuboid.getX() + cuboid.getDx() + 2; x++) { for (double x = cuboid.getX() - 2; x < cuboid.getX() + cuboid.getDx() + 2; x++) {
for (double y = cuboid.getY() - 2; y < cuboid.getY() + cuboid.getDy() + 2; y++) { for (double y = cuboid.getY() - 2; y < cuboid.getY() + cuboid.getDy() + 2; y++) {
for (double z = cuboid.getZ() - 2; z < cuboid.getZ() + cuboid.getDz() + 2; z++) { for (double z = cuboid.getZ() - 2; z < cuboid.getZ() + cuboid.getDz() + 2; z++) {
Location location = new Location(world, x, y, z); Vector location = new Vector(x, y, z);
if (inRegionCheck.test(new Vector(location.getBlockX(), location.getBlockY(), location.getBlockZ()), 0)) { if (inRegionCheck.test(location, 0)) {
Point point = new Point(location.getBlockX(), location.getBlockY(), location.getBlockZ()); Point point = new Point(location.getBlockX(), location.getBlockY(), location.getBlockZ());
blocks.add(point); blocks.add(point);
cuboidIntersectionCache.computeIfAbsent(point.divide(factor), __ -> new HashSet<>())
.add(cuboid);
} }
} }
} }

Datei anzeigen

@ -49,6 +49,10 @@ public class Point {
return new Point(this.x - x, this.y - y, this.z - z); return new Point(this.x - x, this.y - y, this.z - z);
} }
public Point divide(int factor) {
return new Point(x / factor, y / factor, z / factor);
}
public Location toLocation(World world) { public Location toLocation(World world) {
return new Location(world, x, y, z); return new Location(world, x, y, z);
} }