Improve update propagation performance

This commit is contained in:
2026-03-06 18:35:34 +01:00
parent b08f764a17
commit aaa8a9d122
11 changed files with 231 additions and 102 deletions
@@ -20,12 +20,11 @@
package de.steamwar.bausystem.region;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.region.dynamic.DynamicRegion;
import de.steamwar.bausystem.region.dynamic.DynamicRegionRepository;
import de.steamwar.bausystem.region.dynamic.RegionConstructorData;
import de.steamwar.bausystem.region.dynamic.Tile;
import de.steamwar.bausystem.region.dynamic.*;
import de.steamwar.bausystem.region.dynamic.global.GlobalRegion;
import de.steamwar.bausystem.shared.Pair;
import lombok.NonNull;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import javax.annotation.Nullable;
@@ -92,7 +91,7 @@ public class DynamicRegionSystem implements RegionSystem {
@Override
public @NonNull Location getWorldSpawn() {
return null;
return Bukkit.getWorlds().get(0).getSpawnLocation(); // TODO: Temporary
}
@Override
@@ -139,29 +138,40 @@ public class DynamicRegionSystem implements RegionSystem {
return regionMap.values().stream();
}
private Stream<Region> getNeighbours(Region region, boolean noCorners, boolean fastCache, Collection<Region> regions) {
private Stream<Pair<Region, NeighbourDirection>> getNeighbours(Region region, boolean noCorners, boolean fastCache, Collection<Region> regions) {
Point minPoint = region.getArea().getMinPoint(false).subtract(TILE_SIZE_ADJUSTED, 0, TILE_SIZE_ADJUSTED);
Point maxPoint = region.getArea().getMaxPoint(false).add(Tile.tileSize, 0, Tile.tileSize);
Set<Region> neighbours = new HashSet<>();
Set<Pair<Region, NeighbourDirection>> neighbours = new HashSet<>();
for (int x = minPoint.getX() + (noCorners ? TILE_SIZE_ADJUSTED : 0); x <= maxPoint.getX() - (noCorners ? Tile.tileSize : 0); x += Tile.tileSize) {
neighbours.add(get(x, minPoint.getZ(), fastCache, regions));
neighbours.add(get(x, maxPoint.getZ(), fastCache, regions));
NeighbourDirection minZ = NeighbourDirection.North;
if (!noCorners) {
if (x == minPoint.getX()) minZ = NeighbourDirection.NorthWest;
if (x > maxPoint.getX() - TILE_SIZE_ADJUSTED) minZ = NeighbourDirection.NorthEast;
}
neighbours.add(new Pair<>(get(x, minPoint.getZ(), fastCache, regions), minZ));
NeighbourDirection maxZ = NeighbourDirection.South;
if (!noCorners) {
if (x == minPoint.getX()) maxZ = NeighbourDirection.SouthWest;
if (x > maxPoint.getX() - TILE_SIZE_ADJUSTED) maxZ = NeighbourDirection.SouthEast;
}
neighbours.add(new Pair<>(get(x, maxPoint.getZ(), fastCache, regions), maxZ));
}
for (int z = minPoint.getZ() + TILE_SIZE_ADJUSTED; z <= maxPoint.getZ() - Tile.tileSize; z += Tile.tileSize) {
neighbours.add(get(minPoint.getX(), z, fastCache, regions));
neighbours.add(get(maxPoint.getX(), z, fastCache, regions));
neighbours.add(new Pair<>(get(minPoint.getX(), z, fastCache, regions), NeighbourDirection.West));
neighbours.add(new Pair<>(get(maxPoint.getX(), z, fastCache, regions), NeighbourDirection.East));
}
neighbours.remove(getGlobalRegion());
neighbours.removeIf(data -> data.getKey().getType().isGlobal());
return neighbours.stream();
}
public Stream<DynamicRegion> getNeighbours(Region region) {
public Stream<Pair<DynamicRegion, NeighbourDirection>> getNeighbours(Region region) {
return getNeighbours(region, false, true, regionMap.values())
.filter(DynamicRegion.class::isInstance)
.map(DynamicRegion.class::cast);
.filter(data -> data.getKey() instanceof DynamicRegion)
.map(data -> new Pair<>((DynamicRegion) data.getKey(), data.getValue()));
}
@Override
@@ -175,7 +185,9 @@ public class DynamicRegionSystem implements RegionSystem {
while (!current.isEmpty()) {
Region r = current.removeFirst();
if (!connected.add(r)) continue;
getNeighbours(r, true, false, regions).forEach(current::add);
getNeighbours(r, true, false, regions)
.map(Pair::getKey)
.forEach(current::add);
}
return connected.stream();