diff --git a/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java b/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java index 9e2d50a59..3c9813fa3 100644 --- a/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java +++ b/core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java @@ -23,6 +23,7 @@ import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.link.Identifier; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.service.ExternalDataSVC; +import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineAssignedWorldManager; import com.volmit.iris.engine.object.*; @@ -57,13 +58,10 @@ import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.inventory.ItemStack; -import java.lang.ref.WeakReference; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -81,6 +79,8 @@ public class IrisWorldManager extends EngineAssignedWorldManager { private final ChronoLatch cln; private final ChronoLatch chunkUpdater; private final ChronoLatch chunkDiscovery; + private final KMap> cleanup = new KMap<>(); + private final ScheduledExecutorService cleanupService; private double energy = 25; private int entityCount = 0; private long charge = 0; @@ -98,6 +98,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager { looper = null; chunkUpdater = null; chunkDiscovery = null; + cleanupService = null; id = -1; } @@ -109,6 +110,11 @@ public class IrisWorldManager extends EngineAssignedWorldManager { cl = new ChronoLatch(3000); ecl = new ChronoLatch(250); clw = new ChronoLatch(1000, true); + cleanupService = Executors.newSingleThreadScheduledExecutor(runnable -> { + var thread = new Thread(runnable, "Iris Mantle Cleanup " + getTarget().getWorld().name()); + thread.setPriority(Thread.MIN_PRIORITY); + return thread; + }); id = engine.getCacheID(); energy = 25; looper = new Looper() { @@ -425,16 +431,14 @@ public class IrisWorldManager extends EngineAssignedWorldManager { return; } - var ref = new WeakReference<>(e.getWorld()); int cX = e.getX(), cZ = e.getZ(); - J.s(() -> { - World world = ref.get(); - if (world == null || !world.isChunkLoaded(cX, cZ)) - return; + Long key = Cache.key(e); + cleanup.put(key, cleanupService.schedule(() -> { + cleanup.remove(key); energy += 0.3; fixEnergy(); getEngine().cleanupMantleChunk(cX, cZ); - }, IrisSettings.get().getPerformance().mantleCleanupDelay); + }, Math.max(IrisSettings.get().getPerformance().mantleCleanupDelay * 50L, 0), TimeUnit.MILLISECONDS)); if (generated) { //INMS.get().injectBiomesFromMantle(e, getMantle()); @@ -458,6 +462,14 @@ public class IrisWorldManager extends EngineAssignedWorldManager { } } + @Override + public void onChunkUnload(Chunk e) { + final var future = cleanup.remove(Cache.key(e)); + if (future != null) { + future.cancel(false); + } + } + private void spawn(IrisPosition block, IrisSpawner spawner, boolean initial) { if (getEngine().isClosed()) { return; diff --git a/core/src/main/java/com/volmit/iris/engine/framework/Engine.java b/core/src/main/java/com/volmit/iris/engine/framework/Engine.java index 41610a722..fd972ff1d 100644 --- a/core/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/core/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -1000,7 +1000,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat default void cleanupMantleChunk(int x, int z) { if (IrisSettings.get().getPerformance().isTrimMantleInStudio() || !isStudio()) { - J.a(() -> getMantle().cleanupChunk(x, z)); + getMantle().cleanupChunk(x, z); } } } diff --git a/core/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java b/core/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java index e53b35e5c..7dabc01de 100644 --- a/core/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java +++ b/core/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java @@ -34,6 +34,7 @@ import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.world.ChunkLoadEvent; +import org.bukkit.event.world.ChunkUnloadEvent; import org.bukkit.event.world.WorldSaveEvent; import org.bukkit.event.world.WorldUnloadEvent; import org.bukkit.inventory.EquipmentSlot; @@ -125,6 +126,13 @@ public abstract class EngineAssignedWorldManager extends EngineAssignedComponent } } + @EventHandler + public void on(ChunkUnloadEvent e) { + if (e.getChunk().getWorld().equals(getTarget().getWorld().realWorld())) { + onChunkUnload(e.getChunk()); + } + } + @Override public void close() { super.close(); diff --git a/core/src/main/java/com/volmit/iris/engine/framework/EngineWorldManager.java b/core/src/main/java/com/volmit/iris/engine/framework/EngineWorldManager.java index 28403d6ac..36a31b1f2 100644 --- a/core/src/main/java/com/volmit/iris/engine/framework/EngineWorldManager.java +++ b/core/src/main/java/com/volmit/iris/engine/framework/EngineWorldManager.java @@ -45,6 +45,8 @@ public interface EngineWorldManager { void onChunkLoad(Chunk e, boolean generated); + void onChunkUnload(Chunk e); + void chargeEnergy(); void teleportAsync(PlayerTeleportEvent e);