forked from SteamWar/SteamWar
Fix lag from PistonCalculator at high TPS
Bundle piston order recalculations into one run every 200ms (wall clock, independent of TPS) instead of one full recalculation and entity rebuild per piston/place/break event. Tracked pistons that get moved are removed from the visualization instead of being moved along. Fixes #227
This commit is contained in:
+30
-25
@@ -94,41 +94,48 @@ public class PistonCalculator implements Listener {
|
||||
@EventHandler
|
||||
public void onBlockPistonExtend(BlockPistonExtendEvent event) {
|
||||
if (pistOrders.isEmpty()) return;
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
movePistOrders(event.getDirection(), event.getBlocks());
|
||||
pistOrders.values().forEach(PistOrder::calculate);
|
||||
}, 3);
|
||||
removeMovedPistOrders(event.getBlocks());
|
||||
scheduleRecalculate();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockPistonRetract(BlockPistonRetractEvent event) {
|
||||
if (pistOrders.isEmpty()) return;
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
movePistOrders(event.getDirection(), event.getBlocks());
|
||||
pistOrders.values().forEach(PistOrder::calculate);
|
||||
}, 3);
|
||||
removeMovedPistOrders(event.getBlocks());
|
||||
scheduleRecalculate();
|
||||
}
|
||||
|
||||
private void movePistOrders(BlockFace direction, List<Block> blocks) {
|
||||
Set<PistOrder> orders = new HashSet<>();
|
||||
private void removeMovedPistOrders(List<Block> blocks) {
|
||||
blocks.forEach(block -> {
|
||||
PistOrder pistOrder = pistOrders.get(block.getLocation());
|
||||
if (pistOrder == null) return;
|
||||
pistOrders.remove(block.getLocation());
|
||||
pistOrder.piston = pistOrder.piston.getRelative(direction);
|
||||
orders.add(pistOrder);
|
||||
});
|
||||
orders.forEach(pistOrder -> {
|
||||
pistOrders.put(pistOrder.piston.getLocation(), pistOrder);
|
||||
PistOrder pistOrder = pistOrders.remove(block.getLocation());
|
||||
if (pistOrder != null) pistOrder.server.close();
|
||||
});
|
||||
}
|
||||
|
||||
private static final long RECALCULATE_INTERVAL_MS = 200;
|
||||
private boolean recalculationScheduled = false;
|
||||
private long lastRecalculation = 0;
|
||||
|
||||
private void scheduleRecalculate() {
|
||||
if (recalculationScheduled) return;
|
||||
recalculationScheduled = true;
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::recalculateIfDue, 1);
|
||||
}
|
||||
|
||||
private void recalculateIfDue() {
|
||||
if (System.currentTimeMillis() - lastRecalculation < RECALCULATE_INTERVAL_MS) {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::recalculateIfDue, 1);
|
||||
return;
|
||||
}
|
||||
recalculationScheduled = false;
|
||||
lastRecalculation = System.currentTimeMillis();
|
||||
pistOrders.values().forEach(PistOrder::calculate);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockPlace(BlockPlaceEvent event) {
|
||||
if (pistOrders.isEmpty()) return;
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
pistOrders.values().forEach(PistOrder::calculate);
|
||||
}, 1);
|
||||
scheduleRecalculate();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@@ -138,9 +145,7 @@ public class PistonCalculator implements Listener {
|
||||
PistOrder pistOrder = pistOrders.remove(event.getBlock().getLocation());
|
||||
pistOrder.server.close();
|
||||
}
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
pistOrders.values().forEach(PistOrder::calculate);
|
||||
}, 1);
|
||||
scheduleRecalculate();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@@ -166,7 +171,7 @@ public class PistonCalculator implements Listener {
|
||||
private final Map<Location, PistOrder> pistOrders = new HashMap<>();
|
||||
|
||||
private final class PistOrder {
|
||||
private Block piston;
|
||||
private final Block piston;
|
||||
private REntityServer server = new REntityServer();
|
||||
|
||||
private boolean pulling = false;
|
||||
|
||||
Reference in New Issue
Block a user