Merge pull request #1234 from VolmitSoftware/dev

3.8.2
This commit is contained in:
Aidan Aeternum
2026-01-15 02:50:03 -05:00
committed by GitHub
11 changed files with 87 additions and 47 deletions

View File

@@ -182,10 +182,14 @@ tasks {
} }
val templateSource = file("src/main/templates") val templateSource = file("src/main/templates")
val templateDest = layout.buildDirectory.dir("generated/sources/templates") val templateDest = layout.buildDirectory.dir("generated/sources/templates")!!
val generateTemplates = tasks.register<Copy>("generateTemplates") { val generateTemplates = tasks.register<Copy>("generateTemplates") {
inputs.properties( inputs.properties(
"environment" to if (project.hasProperty("release")) "production" else "development", "environment" to when {
project.hasProperty("release") -> "production"
project.hasProperty("argghh") -> "Argghh!"
else -> "development"
},
"commit" to provider { "commit" to provider {
val res = runCatching { project.extensions.getByType<Grgit>().head().id } val res = runCatching { project.extensions.getByType<Grgit>().head().id }
res.getOrDefault("") res.getOrDefault("")

View File

@@ -103,7 +103,7 @@ public class IrisData implements ExclusionStrategy, TypeAdapterFactory {
} }
public static void dereference() { public static void dereference() {
dataLoaders.v().forEach(IrisData::cleanupEngine); dataLoaders.values().forEach(IrisData::cleanupEngine);
} }
public static int cacheSize() { public static int cacheSize() {

View File

@@ -23,6 +23,7 @@ import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.link.Identifier; import com.volmit.iris.core.link.Identifier;
import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.core.service.ExternalDataSVC; 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.Engine;
import com.volmit.iris.engine.framework.EngineAssignedWorldManager; import com.volmit.iris.engine.framework.EngineAssignedWorldManager;
import com.volmit.iris.engine.object.*; 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.event.player.PlayerTeleportEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.lang.ref.WeakReference;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -81,6 +79,8 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
private final ChronoLatch cln; private final ChronoLatch cln;
private final ChronoLatch chunkUpdater; private final ChronoLatch chunkUpdater;
private final ChronoLatch chunkDiscovery; private final ChronoLatch chunkDiscovery;
private final KMap<Long, Future<?>> cleanup = new KMap<>();
private final ScheduledExecutorService cleanupService;
private double energy = 25; private double energy = 25;
private int entityCount = 0; private int entityCount = 0;
private long charge = 0; private long charge = 0;
@@ -98,6 +98,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
looper = null; looper = null;
chunkUpdater = null; chunkUpdater = null;
chunkDiscovery = null; chunkDiscovery = null;
cleanupService = null;
id = -1; id = -1;
} }
@@ -109,6 +110,11 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
cl = new ChronoLatch(3000); cl = new ChronoLatch(3000);
ecl = new ChronoLatch(250); ecl = new ChronoLatch(250);
clw = new ChronoLatch(1000, true); 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(); id = engine.getCacheID();
energy = 25; energy = 25;
looper = new Looper() { looper = new Looper() {
@@ -122,10 +128,6 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
getEngine().getWorld().tryGetRealWorld(); getEngine().getWorld().tryGetRealWorld();
} }
if (!IrisSettings.get().getWorld().isMarkerEntitySpawningSystem() && !IrisSettings.get().getWorld().isAnbientEntitySpawningSystem()) {
return 3000;
}
if (getEngine().getWorld().hasRealWorld()) { if (getEngine().getWorld().hasRealWorld()) {
if (getEngine().getWorld().getPlayers().isEmpty()) { if (getEngine().getWorld().getPlayers().isEmpty()) {
return 5000; return 5000;
@@ -139,6 +141,13 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
discoverChunks(); discoverChunks();
} }
if (cln.flip()) {
engine.getEngineData().cleanup(getEngine());
}
if (!IrisSettings.get().getWorld().isMarkerEntitySpawningSystem() && !IrisSettings.get().getWorld().isAnbientEntitySpawningSystem()) {
return 3000;
}
if (getDimension().isInfiniteEnergy()) { if (getDimension().isInfiniteEnergy()) {
energy += 1000; energy += 1000;
@@ -150,10 +159,6 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
fixEnergy(); fixEnergy();
} }
if (cln.flip()) {
engine.getEngineData().cleanup(getEngine());
}
if (precount != null) { if (precount != null) {
entityCount = 0; entityCount = 0;
for (Entity i : precount) { for (Entity i : precount) {
@@ -181,7 +186,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
} }
}; };
looper.setPriority(Thread.MIN_PRIORITY); looper.setPriority(Thread.MIN_PRIORITY);
looper.setName("Iris World Manager"); looper.setName("Iris World Manager " + getTarget().getWorld().name());
looper.start(); looper.start();
} }
@@ -425,16 +430,14 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
return; return;
} }
var ref = new WeakReference<>(e.getWorld());
int cX = e.getX(), cZ = e.getZ(); int cX = e.getX(), cZ = e.getZ();
J.s(() -> { Long key = Cache.key(e);
World world = ref.get(); cleanup.put(key, cleanupService.schedule(() -> {
if (world == null || !world.isChunkLoaded(cX, cZ)) cleanup.remove(key);
return;
energy += 0.3; energy += 0.3;
fixEnergy(); fixEnergy();
getEngine().cleanupMantleChunk(cX, cZ); getEngine().cleanupMantleChunk(cX, cZ);
}, IrisSettings.get().getPerformance().mantleCleanupDelay); }, Math.max(IrisSettings.get().getPerformance().mantleCleanupDelay * 50L, 0), TimeUnit.MILLISECONDS));
if (generated) { if (generated) {
//INMS.get().injectBiomesFromMantle(e, getMantle()); //INMS.get().injectBiomesFromMantle(e, getMantle());
@@ -458,6 +461,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) { private void spawn(IrisPosition block, IrisSpawner spawner, boolean initial) {
if (getEngine().isClosed()) { if (getEngine().isClosed()) {
return; return;

View File

@@ -1000,7 +1000,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
default void cleanupMantleChunk(int x, int z) { default void cleanupMantleChunk(int x, int z) {
if (IrisSettings.get().getPerformance().isTrimMantleInStudio() || !isStudio()) { if (IrisSettings.get().getPerformance().isTrimMantleInStudio() || !isStudio()) {
J.a(() -> getMantle().cleanupChunk(x, z)); getMantle().cleanupChunk(x, z);
} }
} }
} }

View File

@@ -34,6 +34,7 @@ import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.WorldSaveEvent; import org.bukkit.event.world.WorldSaveEvent;
import org.bukkit.event.world.WorldUnloadEvent; import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.inventory.EquipmentSlot; 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 @Override
public void close() { public void close() {
super.close(); super.close();

View File

@@ -45,6 +45,8 @@ public interface EngineWorldManager {
void onChunkLoad(Chunk e, boolean generated); void onChunkLoad(Chunk e, boolean generated);
void onChunkUnload(Chunk e);
void chargeEnergy(); void chargeEnergy();
void teleportAsync(PlayerTeleportEvent e); void teleportAsync(PlayerTeleportEvent e);

View File

@@ -40,6 +40,7 @@ import com.volmit.iris.util.matter.Matter;
import com.volmit.iris.util.matter.MatterCavern; import com.volmit.iris.util.matter.MatterCavern;
import com.volmit.iris.util.matter.TileWrapper; import com.volmit.iris.util.matter.TileWrapper;
import com.volmit.iris.util.noise.CNG; import com.volmit.iris.util.noise.CNG;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import lombok.Data; import lombok.Data;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
@@ -62,7 +63,7 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
this.mantle = mantle; this.mantle = mantle;
this.radius = radius * 2; this.radius = radius * 2;
final int d = this.radius + 1; final int d = this.radius + 1;
this.cachedChunks = multicore ? new KMap<>(d * d, 0.75f, Math.max(32, Runtime.getRuntime().availableProcessors() * 4)) : new HashMap<>(d * d); this.cachedChunks = multicore ? new KMap<>(d * d, 0.75f, Math.max(32, Runtime.getRuntime().availableProcessors() * 4)) : new Long2ObjectOpenHashMap<>(d * d);
this.x = x; this.x = x;
this.z = z; this.z = z;

View File

@@ -63,14 +63,20 @@ public class IrisContext {
} }
} }
public static void dereference() { public static synchronized void dereference() {
for (Thread i : context.k()) { var it = context.entrySet().iterator();
if (!i.isAlive() || context.get(i).engine.isClosed()) { while (it.hasNext()) {
if (context.get(i).engine.isClosed()) { var entry = it.next();
Iris.debug("Dereferenced Context<Engine> " + i.getName() + " " + i.threadId()); var thread = entry.getKey();
} var context = entry.getValue();
if (thread == null || context == null) {
it.remove();
continue;
}
context.remove(i); if (!thread.isAlive() || context.engine.isClosed()) {
Iris.debug("Dereferenced Context<Engine> " + thread.getName() + " " + thread.threadId());
it.remove();
} }
} }
} }

View File

@@ -24,6 +24,10 @@ public class AtomicBooleanArray implements Serializable {
AA.setVolatile(array, index, newValue); AA.setVolatile(array, index, newValue);
} }
public final boolean getAndSet(int index, boolean newValue) {
return (boolean) AA.getAndSet(array, index, newValue);
}
public final boolean compareAndSet(int index, boolean expectedValue, boolean newValue) { public final boolean compareAndSet(int index, boolean expectedValue, boolean newValue) {
return (boolean) AA.compareAndSet(array, index, expectedValue, newValue); return (boolean) AA.compareAndSet(array, index, expectedValue, newValue);
} }

View File

@@ -27,13 +27,21 @@ interface MatterGenerator {
mantle.write(engine.mantle, x, z, radius, multicore).use { writer -> mantle.write(engine.mantle, x, z, radius, multicore).use { writer ->
for (pair in components) { for (pair in components) {
radius(x, z, pair.b) { x, z -> runBlocking {
for (c in pair.a) { radius(x, z, pair.b) { x, z ->
launch(multicore) { val mc = writer.acquireChunk(x, z)
writer.acquireChunk(x, z) if (mc.isFlagged(MantleFlag.PLANNED))
.raiseFlagSuspend(MantleFlag.PLANNED, c.flag) { return@radius
for (c in pair.a) {
if (mc.isFlagged(c.flag))
continue
launch(multicore) {
mc.raiseFlagSuspend(c.flag) {
c.generateLayer(writer, x, z, context) c.generateLayer(writer, x, z, context)
} }
}
} }
} }
} }
@@ -46,7 +54,7 @@ interface MatterGenerator {
} }
} }
private inline fun radius(x: Int, z: Int, radius: Int, crossinline task: suspend CoroutineScope.(Int, Int) -> Unit) = runBlocking { private inline fun radius(x: Int, z: Int, radius: Int, crossinline task: (Int, Int) -> Unit) {
for (i in -radius..radius) { for (i in -radius..radius) {
for (j in -radius..radius) { for (j in -radius..radius) {
task(x + i, z + j) task(x + i, z + j)

View File

@@ -49,19 +49,15 @@ abstract class FlaggedChunk() {
flags.set(flag.ordinal(), value) flags.set(flag.ordinal(), value)
} }
suspend fun raiseFlagSuspend(guard: MantleFlag?, flag: MantleFlag, task: suspend () -> Unit) { suspend fun raiseFlagSuspend(flag: MantleFlag, task: suspend () -> Unit) {
if (isClosed()) throw IllegalStateException("Chunk is closed!") if (isClosed()) throw IllegalStateException("Chunk is closed!")
if (guard != null && isFlagged(guard)) return if (isFlagged(flag)) return
locks[flag.ordinal()].withLock { locks[flag.ordinal()].withLock {
if (flags.compareAndSet(flag.ordinal(), false, true)) { if (isFlagged(flag)) return
try { task()
task() if (flags.getAndSet(flag.ordinal(), true))
} catch (e: Throwable) { throw IllegalStateException("Flag ${flag.name()} was already set after task ran!")
flags.set(flag.ordinal(), false)
throw e
}
}
} }
} }