Skip to content

Commit d2cb8a9

Browse files
Merge pull request #1234 from VolmitSoftware/dev
3.8.2
2 parents 6a89b8b + 5097150 commit d2cb8a9

11 files changed

Lines changed: 88 additions & 48 deletions

File tree

core/build.gradle.kts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,14 @@ tasks {
182182
}
183183

184184
val templateSource = file("src/main/templates")
185-
val templateDest = layout.buildDirectory.dir("generated/sources/templates")
185+
val templateDest = layout.buildDirectory.dir("generated/sources/templates")!!
186186
val generateTemplates = tasks.register<Copy>("generateTemplates") {
187187
inputs.properties(
188-
"environment" to if (project.hasProperty("release")) "production" else "development",
188+
"environment" to when {
189+
project.hasProperty("release") -> "production"
190+
project.hasProperty("argghh") -> "Argghh!"
191+
else -> "development"
192+
},
189193
"commit" to provider {
190194
val res = runCatching { project.extensions.getByType<Grgit>().head().id }
191195
res.getOrDefault("")

core/src/main/java/com/volmit/iris/core/loader/IrisData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public static Optional<IrisData> getLoaded(File dataFolder) {
103103
}
104104

105105
public static void dereference() {
106-
dataLoaders.v().forEach(IrisData::cleanupEngine);
106+
dataLoaders.values().forEach(IrisData::cleanupEngine);
107107
}
108108

109109
public static int cacheSize() {

core/src/main/java/com/volmit/iris/engine/IrisWorldManager.java

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.volmit.iris.core.link.Identifier;
2424
import com.volmit.iris.core.loader.IrisData;
2525
import com.volmit.iris.core.service.ExternalDataSVC;
26+
import com.volmit.iris.engine.data.cache.Cache;
2627
import com.volmit.iris.engine.framework.Engine;
2728
import com.volmit.iris.engine.framework.EngineAssignedWorldManager;
2829
import com.volmit.iris.engine.object.*;
@@ -57,13 +58,10 @@
5758
import org.bukkit.event.player.PlayerTeleportEvent;
5859
import org.bukkit.inventory.ItemStack;
5960

60-
import java.lang.ref.WeakReference;
6161
import java.util.List;
6262
import java.util.Map;
6363
import java.util.Set;
64-
import java.util.concurrent.CompletableFuture;
65-
import java.util.concurrent.ExecutionException;
66-
import java.util.concurrent.Future;
64+
import java.util.concurrent.*;
6765
import java.util.concurrent.atomic.AtomicBoolean;
6866
import java.util.function.Predicate;
6967
import java.util.stream.Collectors;
@@ -81,6 +79,8 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
8179
private final ChronoLatch cln;
8280
private final ChronoLatch chunkUpdater;
8381
private final ChronoLatch chunkDiscovery;
82+
private final KMap<Long, Future<?>> cleanup = new KMap<>();
83+
private final ScheduledExecutorService cleanupService;
8484
private double energy = 25;
8585
private int entityCount = 0;
8686
private long charge = 0;
@@ -98,6 +98,7 @@ public IrisWorldManager() {
9898
looper = null;
9999
chunkUpdater = null;
100100
chunkDiscovery = null;
101+
cleanupService = null;
101102
id = -1;
102103
}
103104

@@ -109,6 +110,11 @@ public IrisWorldManager(Engine engine) {
109110
cl = new ChronoLatch(3000);
110111
ecl = new ChronoLatch(250);
111112
clw = new ChronoLatch(1000, true);
113+
cleanupService = Executors.newSingleThreadScheduledExecutor(runnable -> {
114+
var thread = new Thread(runnable, "Iris Mantle Cleanup " + getTarget().getWorld().name());
115+
thread.setPriority(Thread.MIN_PRIORITY);
116+
return thread;
117+
});
112118
id = engine.getCacheID();
113119
energy = 25;
114120
looper = new Looper() {
@@ -122,10 +128,6 @@ protected long loop() {
122128
getEngine().getWorld().tryGetRealWorld();
123129
}
124130

125-
if (!IrisSettings.get().getWorld().isMarkerEntitySpawningSystem() && !IrisSettings.get().getWorld().isAnbientEntitySpawningSystem()) {
126-
return 3000;
127-
}
128-
129131
if (getEngine().getWorld().hasRealWorld()) {
130132
if (getEngine().getWorld().getPlayers().isEmpty()) {
131133
return 5000;
@@ -139,6 +141,13 @@ protected long loop() {
139141
discoverChunks();
140142
}
141143

144+
if (cln.flip()) {
145+
engine.getEngineData().cleanup(getEngine());
146+
}
147+
148+
if (!IrisSettings.get().getWorld().isMarkerEntitySpawningSystem() && !IrisSettings.get().getWorld().isAnbientEntitySpawningSystem()) {
149+
return 3000;
150+
}
142151

143152
if (getDimension().isInfiniteEnergy()) {
144153
energy += 1000;
@@ -150,10 +159,6 @@ protected long loop() {
150159
fixEnergy();
151160
}
152161

153-
if (cln.flip()) {
154-
engine.getEngineData().cleanup(getEngine());
155-
}
156-
157162
if (precount != null) {
158163
entityCount = 0;
159164
for (Entity i : precount) {
@@ -181,7 +186,7 @@ protected long loop() {
181186
}
182187
};
183188
looper.setPriority(Thread.MIN_PRIORITY);
184-
looper.setName("Iris World Manager");
189+
looper.setName("Iris World Manager " + getTarget().getWorld().name());
185190
looper.start();
186191
}
187192

@@ -425,16 +430,14 @@ public void onChunkLoad(Chunk e, boolean generated) {
425430
return;
426431
}
427432

428-
var ref = new WeakReference<>(e.getWorld());
429433
int cX = e.getX(), cZ = e.getZ();
430-
J.s(() -> {
431-
World world = ref.get();
432-
if (world == null || !world.isChunkLoaded(cX, cZ))
433-
return;
434+
Long key = Cache.key(e);
435+
cleanup.put(key, cleanupService.schedule(() -> {
436+
cleanup.remove(key);
434437
energy += 0.3;
435438
fixEnergy();
436439
getEngine().cleanupMantleChunk(cX, cZ);
437-
}, IrisSettings.get().getPerformance().mantleCleanupDelay);
440+
}, Math.max(IrisSettings.get().getPerformance().mantleCleanupDelay * 50L, 0), TimeUnit.MILLISECONDS));
438441

439442
if (generated) {
440443
//INMS.get().injectBiomesFromMantle(e, getMantle());
@@ -458,6 +461,14 @@ public void onChunkLoad(Chunk e, boolean generated) {
458461
}
459462
}
460463

464+
@Override
465+
public void onChunkUnload(Chunk e) {
466+
final var future = cleanup.remove(Cache.key(e));
467+
if (future != null) {
468+
future.cancel(false);
469+
}
470+
}
471+
461472
private void spawn(IrisPosition block, IrisSpawner spawner, boolean initial) {
462473
if (getEngine().isClosed()) {
463474
return;

core/src/main/java/com/volmit/iris/engine/framework/Engine.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1000,7 +1000,7 @@ default void gotoPOI(String type, Player p, boolean teleport) {
10001000

10011001
default void cleanupMantleChunk(int x, int z) {
10021002
if (IrisSettings.get().getPerformance().isTrimMantleInStudio() || !isStudio()) {
1003-
J.a(() -> getMantle().cleanupChunk(x, z));
1003+
getMantle().cleanupChunk(x, z);
10041004
}
10051005
}
10061006
}

core/src/main/java/com/volmit/iris/engine/framework/EngineAssignedWorldManager.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.bukkit.event.block.BlockPlaceEvent;
3535
import org.bukkit.event.player.PlayerInteractEvent;
3636
import org.bukkit.event.world.ChunkLoadEvent;
37+
import org.bukkit.event.world.ChunkUnloadEvent;
3738
import org.bukkit.event.world.WorldSaveEvent;
3839
import org.bukkit.event.world.WorldUnloadEvent;
3940
import org.bukkit.inventory.EquipmentSlot;
@@ -125,6 +126,13 @@ public void on(ChunkLoadEvent e) {
125126
}
126127
}
127128

129+
@EventHandler
130+
public void on(ChunkUnloadEvent e) {
131+
if (e.getChunk().getWorld().equals(getTarget().getWorld().realWorld())) {
132+
onChunkUnload(e.getChunk());
133+
}
134+
}
135+
128136
@Override
129137
public void close() {
130138
super.close();

core/src/main/java/com/volmit/iris/engine/framework/EngineWorldManager.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ public interface EngineWorldManager {
4545

4646
void onChunkLoad(Chunk e, boolean generated);
4747

48+
void onChunkUnload(Chunk e);
49+
4850
void chargeEnergy();
4951

5052
void teleportAsync(PlayerTeleportEvent e);

core/src/main/java/com/volmit/iris/engine/mantle/MantleWriter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.volmit.iris.util.matter.MatterCavern;
4141
import com.volmit.iris.util.matter.TileWrapper;
4242
import com.volmit.iris.util.noise.CNG;
43+
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
4344
import lombok.Data;
4445
import org.bukkit.block.data.BlockData;
4546
import org.bukkit.util.Vector;
@@ -62,7 +63,7 @@ public MantleWriter(EngineMantle engineMantle, Mantle mantle, int x, int z, int
6263
this.mantle = mantle;
6364
this.radius = radius * 2;
6465
final int d = this.radius + 1;
65-
this.cachedChunks = multicore ? new KMap<>(d * d, 0.75f, Math.max(32, Runtime.getRuntime().availableProcessors() * 4)) : new HashMap<>(d * d);
66+
this.cachedChunks = multicore ? new KMap<>(d * d, 0.75f, Math.max(32, Runtime.getRuntime().availableProcessors() * 4)) : new Long2ObjectOpenHashMap<>(d * d);
6667
this.x = x;
6768
this.z = z;
6869

core/src/main/java/com/volmit/iris/util/context/IrisContext.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,20 @@ public static void touch(IrisContext c) {
6363
}
6464
}
6565

66-
public static void dereference() {
67-
for (Thread i : context.k()) {
68-
if (!i.isAlive() || context.get(i).engine.isClosed()) {
69-
if (context.get(i).engine.isClosed()) {
70-
Iris.debug("Dereferenced Context<Engine> " + i.getName() + " " + i.threadId());
71-
}
72-
73-
context.remove(i);
66+
public static synchronized void dereference() {
67+
var it = context.entrySet().iterator();
68+
while (it.hasNext()) {
69+
var entry = it.next();
70+
var thread = entry.getKey();
71+
var context = entry.getValue();
72+
if (thread == null || context == null) {
73+
it.remove();
74+
continue;
75+
}
76+
77+
if (!thread.isAlive() || context.engine.isClosed()) {
78+
Iris.debug("Dereferenced Context<Engine> " + thread.getName() + " " + thread.threadId());
79+
it.remove();
7480
}
7581
}
7682
}

core/src/main/java/com/volmit/iris/util/parallel/AtomicBooleanArray.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ public final void set(int index, boolean newValue) {
2424
AA.setVolatile(array, index, newValue);
2525
}
2626

27+
public final boolean getAndSet(int index, boolean newValue) {
28+
return (boolean) AA.getAndSet(array, index, newValue);
29+
}
30+
2731
public final boolean compareAndSet(int index, boolean expectedValue, boolean newValue) {
2832
return (boolean) AA.compareAndSet(array, index, expectedValue, newValue);
2933
}

core/src/main/kotlin/com/volmit/iris/engine/mantle/MatterGenerator.kt

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,21 @@ interface MatterGenerator {
2727

2828
mantle.write(engine.mantle, x, z, radius, multicore).use { writer ->
2929
for (pair in components) {
30-
radius(x, z, pair.b) { x, z ->
31-
for (c in pair.a) {
32-
launch(multicore) {
33-
writer.acquireChunk(x, z)
34-
.raiseFlagSuspend(MantleFlag.PLANNED, c.flag) {
30+
runBlocking {
31+
radius(x, z, pair.b) { x, z ->
32+
val mc = writer.acquireChunk(x, z)
33+
if (mc.isFlagged(MantleFlag.PLANNED))
34+
return@radius
35+
36+
for (c in pair.a) {
37+
if (mc.isFlagged(c.flag))
38+
continue
39+
40+
launch(multicore) {
41+
mc.raiseFlagSuspend(c.flag) {
3542
c.generateLayer(writer, x, z, context)
3643
}
44+
}
3745
}
3846
}
3947
}
@@ -46,7 +54,7 @@ interface MatterGenerator {
4654
}
4755
}
4856

49-
private inline fun radius(x: Int, z: Int, radius: Int, crossinline task: suspend CoroutineScope.(Int, Int) -> Unit) = runBlocking {
57+
private inline fun radius(x: Int, z: Int, radius: Int, crossinline task: (Int, Int) -> Unit) {
5058
for (i in -radius..radius) {
5159
for (j in -radius..radius) {
5260
task(x + i, z + j)

0 commit comments

Comments
 (0)