add kts hook for chunk updates

This commit is contained in:
Julian Krings
2025-09-21 22:30:48 +02:00
parent 7e7933858b
commit ae92bcf194
10 changed files with 93 additions and 7 deletions

View File

@@ -1,9 +1,12 @@
package com.volmit.iris.core.scripting.environment;
import com.volmit.iris.core.loader.IrisRegistrant;
import com.volmit.iris.core.scripting.func.UpdateExecutor;
import com.volmit.iris.core.scripting.kotlin.environment.IrisExecutionEnvironment;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.mantle.MantleChunk;
import lombok.NonNull;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.jetbrains.annotations.Nullable;
@@ -22,4 +25,6 @@ public interface EngineEnvironment extends PackEnvironment {
void postSpawnMob(@NonNull String script, @NonNull Location location, @NonNull Entity mob);
void preprocessObject(@NonNull String script, @NonNull IrisRegistrant object);
void updateChunk(@NonNull String script, @NonNull MantleChunk mantleChunk, @NonNull Chunk chunk, @NonNull UpdateExecutor executor);
}

View File

@@ -0,0 +1,22 @@
package com.volmit.iris.core.scripting.func;
import org.jetbrains.annotations.NotNull;
@FunctionalInterface
public interface UpdateExecutor {
@NotNull Runnable wrap(int delay, @NotNull Runnable runnable);
@NotNull
default Runnable wrap(@NotNull Runnable runnable) {
return wrap(1, runnable);
}
default void execute(@NotNull Runnable runnable) {
execute(1, runnable);
}
default void execute(int delay, @NotNull Runnable runnable) {
wrap(delay, runnable).run();
}
}

View File

@@ -294,7 +294,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
var chunk = mantle.getChunk(c).use();
try {
Semaphore semaphore = new Semaphore(3);
Semaphore semaphore = new Semaphore(1024);
chunk.raiseFlag(MantleFlag.ETCHED, () -> {
chunk.raiseFlagUnchecked(MantleFlag.TILE, run(semaphore, () -> {
chunk.iterate(TileWrapper.class, (x, y, z, v) -> {
@@ -355,8 +355,18 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
}, RNG.r.i(1, 20))); //Why is there a random delay here?
});
chunk.raiseFlagUnchecked(MantleFlag.SCRIPT, () -> {
var scripts = getDimension().getChunkUpdateScripts();
if (scripts == null || scripts.isEmpty())
return;
for (var script : scripts) {
getExecution().updateChunk(script, chunk, c, (delay, task) -> run(semaphore, task, delay));
}
});
try {
semaphore.acquire(3);
semaphore.acquire(1024);
} catch (InterruptedException ignored) {}
} finally {
chunk.release();
@@ -365,8 +375,11 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
private static Runnable run(Semaphore semaphore, Runnable runnable, int delay) {
return () -> {
if (!semaphore.tryAcquire())
return;
try {
semaphore.acquire();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
J.s(() -> {
try {

View File

@@ -257,6 +257,10 @@ public class IrisDimension extends IrisRegistrant {
@RegistryListResource(IrisScript.class)
@ArrayType(type = String.class, min = 1)
private KList<String> dataScripts = new KList<>();
@Desc("A list of scripts executed on chunk update")
@RegistryListResource(IrisScript.class)
@ArrayType(type = String.class, min = 1)
private KList<String> chunkUpdateScripts = new KList<>();
@Desc("Use legacy rarity instead of modern one\nWARNING: Changing this may break expressions and image maps")
private boolean legacyRarity = true;

View File

@@ -176,14 +176,26 @@ public class MantleChunk {
if (guard != null && isFlagged(guard)) return;
synchronized (flagLocks[flag.ordinal()]) {
if (flags.compareAndSet(flag.ordinal(), false, true)) {
r.run();
try {
r.run();
} catch (RuntimeException | Error e) {
flags.set(flag.ordinal(), false);
throw e;
}
}
}
}
public void raiseFlagUnchecked(MantleFlag flag, Runnable r) {
if (closed.get()) throw new IllegalStateException("Chunk is closed!");
if (flags.compareAndSet(flag.ordinal(), false, true)) r.run();
if (flags.compareAndSet(flag.ordinal(), false, true)) {
try {
r.run();
} catch (RuntimeException | Error e) {
flags.set(flag.ordinal(), false);
throw e;
}
}
}
public boolean isFlagged(MantleFlag flag) {

View File

@@ -40,6 +40,7 @@ public sealed interface MantleFlag permits CustomFlag, ReservedFlag {
MantleFlag CUSTOM = ReservedFlag.CUSTOM;
MantleFlag DISCOVERED = ReservedFlag.DISCOVERED;
MantleFlag CUSTOM_ACTIVE = ReservedFlag.CUSTOM_ACTIVE;
MantleFlag SCRIPT = ReservedFlag.SCRIPT;
int RESERVED_FLAGS = ReservedFlag.values().length;

View File

@@ -16,7 +16,8 @@ public enum ReservedFlag implements MantleFlag {
TILE,
CUSTOM,
DISCOVERED,
CUSTOM_ACTIVE;
CUSTOM_ACTIVE,
SCRIPT;
@Override
public boolean isCustom() {

View File

@@ -0,0 +1,21 @@
package com.volmit.iris.core.scripting.kotlin.base
import com.volmit.iris.core.scripting.func.UpdateExecutor
import com.volmit.iris.util.mantle.MantleChunk
import org.bukkit.Chunk
import kotlin.script.experimental.annotations.KotlinScript
import kotlin.script.experimental.api.ScriptCompilationConfiguration
import kotlin.script.experimental.api.providedProperties
@KotlinScript(fileExtension = "update.kts", compilationConfiguration = ChunkUpdateScriptDefinition::class)
abstract class ChunkUpdateScript
object ChunkUpdateScriptDefinition : ScriptCompilationConfiguration(listOf(EngineScriptDefinition), {
providedProperties(
"mantleChunk" to MantleChunk::class,
"chunk" to Chunk::class,
"executor" to UpdateExecutor::class
)
}) {
private fun readResolve(): Any = MobSpawningScriptDefinition
}

View File

@@ -3,11 +3,15 @@ package com.volmit.iris.core.scripting.kotlin.environment
import com.volmit.iris.core.loader.IrisRegistrant
import com.volmit.iris.core.scripting.environment.EngineEnvironment
import com.volmit.iris.core.scripting.func.BiomeLookup
import com.volmit.iris.core.scripting.func.UpdateExecutor
import com.volmit.iris.core.scripting.kotlin.base.ChunkUpdateScript
import com.volmit.iris.core.scripting.kotlin.base.EngineScript
import com.volmit.iris.core.scripting.kotlin.base.MobSpawningScript
import com.volmit.iris.core.scripting.kotlin.base.PostMobSpawningScript
import com.volmit.iris.core.scripting.kotlin.base.PreprocessorScript
import com.volmit.iris.engine.framework.Engine
import com.volmit.iris.util.mantle.MantleChunk
import org.bukkit.Chunk
import org.bukkit.Location
import org.bukkit.entity.Entity
@@ -31,6 +35,9 @@ data class IrisExecutionEnvironment(
override fun preprocessObject(script: String, `object`: IrisRegistrant) =
execute(script, PreprocessorScript::class.java, engine.parameters("object" to `object`))
override fun updateChunk(script: String, mantleChunk: MantleChunk, chunk: Chunk, executor: UpdateExecutor) =
execute(script, ChunkUpdateScript::class.java, engine.parameters("mantleChunk" to mantleChunk, "chunk" to chunk, "executor" to executor))
private fun Engine.parameters(vararg values: Pair<String, Any?>): Map<String, Any?> {
return mapOf(
"data" to data,