From bddc62f385b57d3a5d3c5b206686f9206206b655 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Sun, 20 Jul 2025 00:50:11 +0200 Subject: [PATCH] fix object saving --- .../com/volmit/iris/core/service/WandSVC.java | 79 +----------- .../com/volmit/iris/util/data/Cuboid.java | 8 +- .../iris/util/scheduling/jobs/ScanJob.java | 118 ++++++++++++++++++ 3 files changed, 127 insertions(+), 78 deletions(-) create mode 100644 core/src/main/java/com/volmit/iris/util/scheduling/jobs/ScanJob.java diff --git a/core/src/main/java/com/volmit/iris/core/service/WandSVC.java b/core/src/main/java/com/volmit/iris/core/service/WandSVC.java index 8d984ba91..ffe84e900 100644 --- a/core/src/main/java/com/volmit/iris/core/service/WandSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/WandSVC.java @@ -35,6 +35,7 @@ import com.volmit.iris.util.plugin.VolmitSender; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.SR; import com.volmit.iris.util.scheduling.jobs.Job; +import com.volmit.iris.util.scheduling.jobs.ScanJob; import org.bukkit.*; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; @@ -86,80 +87,10 @@ public class WandSVC implements IrisService { Cuboid c = new Cuboid(f[0], f[1]); IrisObject s = new IrisObject(c.getSizeX(), c.getSizeY(), c.getSizeZ()); - var it = c.chunkedIterator(); - - int total = c.getSizeX() * c.getSizeY() * c.getSizeZ(); - var latch = new CountDownLatch(1); - new Job() { - private int i; - private Chunk chunk; - - @Override - public String getName() { - return "Scanning Selection"; - } - - @Override - public void execute() { - new SR() { - @Override - public void run() { - var time = M.ms() + MS_PER_TICK; - while (time > M.ms()) { - if (!it.hasNext()) { - if (chunk != null) { - chunk.removePluginChunkTicket(Iris.instance); - chunk = null; - } - - cancel(); - latch.countDown(); - return; - } - - try { - var b = it.next(); - var bChunk = b.getChunk(); - if (chunk == null) { - chunk = bChunk; - chunk.addPluginChunkTicket(Iris.instance); - } else if (chunk != bChunk) { - chunk.removePluginChunkTicket(Iris.instance); - chunk = bChunk; - } - - if (b.getType().equals(Material.AIR)) - continue; - - BlockVector bv = b.getLocation().subtract(c.getLowerNE().toVector()).toVector().toBlockVector(); - s.setUnsigned(bv.getBlockX(), bv.getBlockY(), bv.getBlockZ(), b, legacy); - } finally { - i++; - } - } - } - }; - try { - latch.await(); - } catch (InterruptedException ignored) {} - } - - @Override - public void completeWork() {} - - @Override - public int getTotalWork() { - return total; - } - - @Override - public int getWorkCompleted() { - return i; - } - }.execute(new VolmitSender(p), true, () -> {}); - try { - latch.await(); - } catch (InterruptedException ignored) {} + new ScanJob("Scanning Selection", c, MS_PER_TICK, (bv, b) -> { + if (b.getType().equals(Material.AIR)) return; + s.setUnsigned(bv.getBlockX(), bv.getBlockY(), bv.getBlockZ(), b, legacy); + }).execute(new VolmitSender(p), true, () -> {}); return s; } catch (Throwable e) { diff --git a/core/src/main/java/com/volmit/iris/util/data/Cuboid.java b/core/src/main/java/com/volmit/iris/util/data/Cuboid.java index ccd837eb2..df377fec6 100644 --- a/core/src/main/java/com/volmit/iris/util/data/Cuboid.java +++ b/core/src/main/java/com/volmit/iris/util/data/Cuboid.java @@ -652,7 +652,7 @@ public class Cuboid implements Iterable, Cloneable, ConfigurationSerializ return new CuboidIterator(getWorld(), x1, y1, z1, x2, y2, z2); } - public Iterator chunkedIterator() { + public Iterator chunkedIterator() { return new ChunkedCuboidIterator(getWorld(), x1, y1, z1, x2, y2, z2); } @@ -751,7 +751,7 @@ public class Cuboid implements Iterable, Cloneable, ConfigurationSerializ } } - public static class ChunkedCuboidIterator implements Iterator { + public static class ChunkedCuboidIterator implements Iterator { private final World w; private final int minRX, minY, minRZ, maxRX, maxY, maxRZ; private final int minCX, minCZ, maxCX, maxCZ; @@ -795,7 +795,7 @@ public class Cuboid implements Iterable, Cloneable, ConfigurationSerializ } @Override - public Block next() { + public Location next() { if (chunk == null) { chunk = new Position2(cX, cZ); if (++cX > maxCX) { @@ -809,7 +809,7 @@ public class Cuboid implements Iterable, Cloneable, ConfigurationSerializ rZ = chunk.getZ() == minCZ ? minRZ : 0; } - var b = w.getBlockAt((chunk.getX() << 4) + rX, y, (chunk.getZ() << 4) + rZ); + var b = new Location(w, (chunk.getX() << 4) + rX, y, (chunk.getZ() << 4) + rZ); if (++y > maxY) { y = minY; if (++rX > mX) { diff --git a/core/src/main/java/com/volmit/iris/util/scheduling/jobs/ScanJob.java b/core/src/main/java/com/volmit/iris/util/scheduling/jobs/ScanJob.java new file mode 100644 index 000000000..42036fe7a --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/scheduling/jobs/ScanJob.java @@ -0,0 +1,118 @@ +package com.volmit.iris.util.scheduling.jobs; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.data.Cuboid; +import com.volmit.iris.util.math.M; +import com.volmit.iris.util.plugin.VolmitSender; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.util.BlockVector; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiConsumer; + +public class ScanJob implements Job { + private final CountDownLatch latch = new CountDownLatch(1); + private final AtomicInteger completed = new AtomicInteger(); + private final String name; + private final Cuboid cuboid; + private final BiConsumer action; + private final int msPerTick, total; + private volatile Chunk chunk; + + public ScanJob(String name, + Cuboid cuboid, + int msPerTick, + BiConsumer action + ) { + this.name = name; + this.cuboid = cuboid; + this.action = action; + this.msPerTick = msPerTick; + total = cuboid.volume(); + } + + @Override + public String getName() { + return name; + } + + @Override + public void execute() { + Thread.ofVirtual() + .name("Iris Job - " + name) + .start(this::executeTask); + await(); + } + + public void await() { + try { + latch.await(); + } catch (InterruptedException ignored) {} + } + + private void executeTask() { + var it = cuboid.chunkedIterator(); + var region = Iris.platform.getRegionScheduler(); + + var tmp = it.next(); + while (tmp != null) { + Location finalTmp = tmp; + tmp = region.run(tmp, () -> { + var time = M.ms() + msPerTick; + var next = finalTmp; + + while (time > M.ms()) { + if (!consume(next)) break; + completed.incrementAndGet(); + next = it.hasNext() ? it.next() : null; + } + + return next; + }).getResult().join(); + } + + latch.countDown(); + } + + private boolean consume(Location next) { + if (!Iris.platform.isOwnedByCurrentRegion(next)) + return true; + + final Chunk nextChunk = next.getChunk(); + if (chunk == null) { + chunk.removePluginChunkTicket(Iris.instance); + chunk = next.getChunk(); + } else if (chunk != nextChunk) { + chunk.removePluginChunkTicket(Iris.instance); + chunk = nextChunk; + chunk.addPluginChunkTicket(Iris.instance); + } + + final Block block = next.getBlock(); + action.accept(next.subtract(cuboid.getLowerNE().toVector()).toVector().toBlockVector(), block); + return false; + } + + @Override + public void completeWork() { + } + + @Override + public int getTotalWork() { + return total; + } + + @Override + public int getWorkCompleted() { + return completed.get(); + } + + @Override + public void execute(VolmitSender sender, boolean silentMsg, Runnable whenComplete) { + Job.super.execute(sender, silentMsg, whenComplete); + await(); + } +}