Well.. not for now at least let me just remove that-

This commit is contained in:
piexel committed 2026-10-25 22:21:33 +01:00
1 parent b7499d23f2
commit 3766a40256
12 files changed
+21 -122

No files matched your search

@@ -87,10 +87,6 @@ import java.util.stream.Collectors;
public interface Engine extends DataProvider, Fallible, BlockUpdater, Renderer, Hotloadable { public interface Engine extends DataProvider, Fallible, BlockUpdater, Renderer, Hotloadable {
IrisComplex getComplex(); IrisComplex getComplex();
default art.arcane.iris.structure.object.PlacementLifecycles getPlacementLifecycles() {
return art.arcane.iris.structure.object.PlacementLifecycles.defaults();
}
default BiomeEnvironment getBiomeEnvironment(int x, int y, int z) { default BiomeEnvironment getBiomeEnvironment(int x, int y, int z) {
return new BiomeEnvironment(0L, getBiome(x, y, z), getRegion(x, y, z), getDimension(), getData()); return new BiomeEnvironment(0L, getBiome(x, y, z), getRegion(x, y, z), getDimension(), getData());
} }
@@ -96,8 +96,7 @@ final class EngineHotloader {
assembly.complex, assembly.complex,
assembly.upperContext, assembly.upperContext,
assembly.dimensionStackContext, assembly.dimensionStackContext,
biomeMaxes, biomeMaxes);
assembly.placementLifecycles);
next = previous.withGeneration(nextGeneration); next = previous.withGeneration(nextGeneration);
} finally { } finally {
engine.threadState.setAssembly(null); engine.threadState.setAssembly(null);
@@ -18,8 +18,6 @@
package art.arcane.iris.generation.runtime; package art.arcane.iris.generation.runtime;
import art.arcane.iris.structure.object.PlacementLifecycles;
import art.arcane.iris.pack.loading.IrisData; import art.arcane.iris.pack.loading.IrisData;
import art.arcane.iris.pack.loading.ResourceLoader; import art.arcane.iris.pack.loading.ResourceLoader;
import art.arcane.iris.generation.runtime.GenerationRuntime.BiomeMaxes; import art.arcane.iris.generation.runtime.GenerationRuntime.BiomeMaxes;
@@ -422,7 +420,6 @@ final class EngineRuntimeBuilder {
final GenerationKernelRegistry.RuntimeKernel runtimeKernel; final GenerationKernelRegistry.RuntimeKernel runtimeKernel;
final SeedManager seedManager; final SeedManager seedManager;
final TransitionGenerationPlan transitionPlan; final TransitionGenerationPlan transitionPlan;
final PlacementLifecycles placementLifecycles;
static int nextRuntimeId() { static int nextRuntimeId() {
return RUNTIME_IDS.incrementAndGet(); return RUNTIME_IDS.incrementAndGet();
@@ -471,7 +468,6 @@ final class EngineRuntimeBuilder {
this.seedManager = this.runtimeKernel.createSeedManager(target.getWorld().getRawWorldSeed()); this.seedManager = this.runtimeKernel.createSeedManager(target.getWorld().getRawWorldSeed());
this.kernelVersion = this.runtimeKernel.version(); this.kernelVersion = this.runtimeKernel.version();
this.transitionPlan = transitionPlan; this.transitionPlan = transitionPlan;
this.placementLifecycles = PlacementLifecycles.resolve();
} }
GenerationRuntime freezeGeneration(BiomeMaxes biomeMaxes) { GenerationRuntime freezeGeneration(BiomeMaxes biomeMaxes) {
@@ -494,8 +490,7 @@ final class EngineRuntimeBuilder {
mantle, mantle,
mantleStorageDirectory, mantleStorageDirectory,
hash32, hash32,
biomeMaxes, biomeMaxes);
placementLifecycles);
} }
EngineRuntime freezeRuntime(BiomeMaxes biomeMaxes) { EngineRuntime freezeRuntime(BiomeMaxes biomeMaxes) {
@@ -18,8 +18,6 @@
package art.arcane.iris.generation.runtime; package art.arcane.iris.generation.runtime;
import art.arcane.iris.structure.object.PlacementLifecycles;
import art.arcane.iris.pack.loading.IrisData; import art.arcane.iris.pack.loading.IrisData;
import art.arcane.iris.world.history.TransitionGenerationPlan; import art.arcane.iris.world.history.TransitionGenerationPlan;
import art.arcane.iris.world.history.GenerationKernelRegistry; import art.arcane.iris.world.history.GenerationKernelRegistry;
@@ -46,8 +44,7 @@ record GenerationRuntime(
EngineMantle mantle, EngineMantle mantle,
Path mantleStorageDirectory, Path mantleStorageDirectory,
CompletableFuture<Long> hash32, CompletableFuture<Long> hash32,
BiomeMaxes biomeMaxes, BiomeMaxes biomeMaxes
PlacementLifecycles placementLifecycles
) { ) {
GenerationRuntime { GenerationRuntime {
Objects.requireNonNull(target, "generation target"); Objects.requireNonNull(target, "generation target");
@@ -64,7 +61,6 @@ record GenerationRuntime(
Objects.requireNonNull(mantle, "generation mantle"); Objects.requireNonNull(mantle, "generation mantle");
mantleStorageDirectory = IrisEngineMantle.normalizeStorageDirectory(mantleStorageDirectory); mantleStorageDirectory = IrisEngineMantle.normalizeStorageDirectory(mantleStorageDirectory);
Objects.requireNonNull(hash32, "generation pack hash"); Objects.requireNonNull(hash32, "generation pack hash");
Objects.requireNonNull(placementLifecycles, "placement lifecycles");
Objects.requireNonNull(biomeMaxes, "generation biome maximums"); Objects.requireNonNull(biomeMaxes, "generation biome maximums");
if (target.getData() != data || target.getDimension() != dimension) { if (target.getData() != data || target.getDimension() != dimension) {
throw new IllegalArgumentException("Generation target, data, and dimension must describe one runtime."); throw new IllegalArgumentException("Generation target, data, and dimension must describe one runtime.");
@@ -76,8 +72,7 @@ record GenerationRuntime(
IrisComplex nextComplex, IrisComplex nextComplex,
UpperDimensionContext nextUpperContext, UpperDimensionContext nextUpperContext,
DimensionStackContext nextDimensionStackContext, DimensionStackContext nextDimensionStackContext,
BiomeMaxes nextBiomeMaxes, BiomeMaxes nextBiomeMaxes
PlacementLifecycles nextPlacementLifecycles
) { ) {
return new GenerationRuntime( return new GenerationRuntime(
nextCacheId, nextCacheId,
@@ -95,8 +90,7 @@ record GenerationRuntime(
mantle, mantle,
mantleStorageDirectory, mantleStorageDirectory,
hash32, hash32,
nextBiomeMaxes, nextBiomeMaxes);
nextPlacementLifecycles);
} }
record BiomeMaxes(double objectDensity, double layerDensity, double decoratorDensity) { record BiomeMaxes(double objectDensity, double layerDensity, double decoratorDensity) {
@@ -1403,20 +1403,6 @@ public class IrisEngine implements Engine {
return current == null ? null : current.complex(); return current == null ? null : current.complex();
} }
@Override
public art.arcane.iris.structure.object.PlacementLifecycles getPlacementLifecycles() {
EngineThreadState.Frame frame = threadState.current();
RuntimeAssembly assembly = frame == null ? null : frame.assembly;
if (assembly != null) {
return assembly.placementLifecycles;
}
GenerationRuntime current = selectedGenerationRuntime(frame);
if (current == null) {
throw new IllegalStateException("Placement requires an active Iris runtime.");
}
return current.placementLifecycles();
}
@Override @Override
public EngineTarget getTarget() { public EngineTarget getTarget() {
return targetIn(threadState.current()); return targetIn(threadState.current());
@@ -27,7 +27,7 @@ import art.arcane.volmlib.util.math.RNG;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
/** Entry point for executing an engine's resolved placement plan. */ /** Entry point for executing the resolved placement plan of a mode. */
final class IrisObjectPlacementRunner { final class IrisObjectPlacementRunner {
private final IrisObject self; private final IrisObject self;
private final IrisObjectPlacementAlignment alignment; private final IrisObjectPlacementAlignment alignment;
@@ -40,6 +40,6 @@ final class IrisObjectPlacementRunner {
int place(int x, int yv, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng, int place(int x, int yv, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng,
BiConsumer<BlockPosition, NativeBlockState> listener, CarveResult cave, IrisData data) { BiConsumer<BlockPosition, NativeBlockState> listener, CarveResult cave, IrisData data) {
PlacementContext context = new PlacementContext(config, data, placer, cave, rng, self, alignment, x, z, yv, listener); PlacementContext context = new PlacementContext(config, data, placer, cave, rng, self, alignment, x, z, yv, listener);
return PlacementLifecycles.forPlacer(placer).get(config.getMode()).execute(context).heightOrRejected(); return PlacementLifecycles.defaults().get(config.getMode()).execute(context).heightOrRejected();
} }
} }
@@ -3,16 +3,17 @@ package art.arcane.iris.structure.object;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** One resolved plan per mode in an engine runtime. Engine-less tools share a separate default set. */ /** One resolved plan per mode. Plans are immutable, so every placement shares the default set. */
public final class PlacementLifecycles { final class PlacementLifecycles {
private final Map<ObjectPlaceMode, PlacementLifecycle> plans; private final Map<ObjectPlaceMode, PlacementLifecycle> plans;
private PlacementLifecycles(Map<ObjectPlaceMode, PlacementLifecycle> plans) { private PlacementLifecycles(Map<ObjectPlaceMode, PlacementLifecycle> plans) {
this.plans = Map.copyOf(plans); this.plans = Map.copyOf(plans);
} }
public static PlacementLifecycles resolve() { static PlacementLifecycles resolve() {
Map<ObjectPlaceMode, PlacementLifecycle> plans = new EnumMap<>(ObjectPlaceMode.class); Map<ObjectPlaceMode, PlacementLifecycle> plans = new EnumMap<>(ObjectPlaceMode.class);
for (ObjectPlaceMode mode : ObjectPlaceMode.values()) { for (ObjectPlaceMode mode : ObjectPlaceMode.values()) {
try { try {
@@ -24,18 +25,12 @@ public final class PlacementLifecycles {
return new PlacementLifecycles(plans); return new PlacementLifecycles(plans);
} }
public static PlacementLifecycles defaults() { static PlacementLifecycles defaults() {
return Defaults.INSTANCE; return Defaults.INSTANCE;
} }
static PlacementLifecycles forPlacer(IObjectPlacer placer) { PlacementLifecycle get(ObjectPlaceMode mode) {
var engine = placer.getEngine(); return plans.get(Objects.requireNonNull(mode, "Placement mode"));
PlacementLifecycles plans = engine == null ? null : engine.getPlacementLifecycles();
return plans == null ? defaults() : plans;
}
public PlacementLifecycle get(ObjectPlaceMode mode) {
return plans.get(java.util.Objects.requireNonNull(mode, "Placement mode"));
} }
private static final class Defaults { private static final class Defaults {
@@ -1,62 +0,0 @@
package art.arcane.iris.generation.runtime;
import art.arcane.iris.generation.runtime.EngineEffects;
import art.arcane.iris.generation.runtime.EngineMode;
import art.arcane.iris.generation.runtime.EngineTarget;
import art.arcane.iris.generation.runtime.EngineWorldManager;
import art.arcane.iris.structure.object.ObjectPlaceMode;
import org.junit.Test;
import java.util.concurrent.CompletableFuture;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
public class EnginePlacementLifecycleTest {
@Test
public void runtimeAssemblyResolvesBeforePublicationAndKeepsOldPlansIntact() {
var initial = assembly(1);
EngineRuntime previous = initial.freezeRuntime(new GenerationRuntime.BiomeMaxes(0, 0, 0));
var replacement = assembly(2);
EngineRuntime next = replacement.freezeRuntime(new GenerationRuntime.BiomeMaxes(0, 0, 0));
assertSame(initial.placementLifecycles, previous.generation().placementLifecycles());
assertSame(replacement.placementLifecycles, next.generation().placementLifecycles());
for (ObjectPlaceMode mode : ObjectPlaceMode.values()) {
assertNotNull(next.generation().placementLifecycles().get(mode));
assertNotSame(previous.generation().placementLifecycles().get(mode), next.generation().placementLifecycles().get(mode));
}
assertSame(initial.placementLifecycles, previous.generation().placementLifecycles());
}
@Test
public void complexReplacementCarriesNewPlansAlongsideTheNewComplex() {
var initial = assembly(1);
EngineRuntime previous = initial.freezeRuntime(new GenerationRuntime.BiomeMaxes(0, 0, 0));
var replacement = assembly(2);
EngineRuntime next = previous.withGeneration(previous.generation().withComplex(2, replacement.complex, null, null,
new GenerationRuntime.BiomeMaxes(1, 1, 1), replacement.placementLifecycles));
assertSame(replacement.placementLifecycles, next.generation().placementLifecycles());
assertSame(replacement.complex, next.generation().complex());
assertSame(previous.worldManager(), next.worldManager());
assertSame(initial.placementLifecycles, previous.generation().placementLifecycles());
}
private EngineRuntimeBuilder.RuntimeAssembly assembly(int id) {
EngineTarget target = mock(EngineTarget.class);
var world = mock(art.arcane.iris.world.IrisWorld.class);
org.mockito.Mockito.when(target.getWorld()).thenReturn(world);
org.mockito.Mockito.when(target.getData()).thenReturn(mock(art.arcane.iris.pack.loading.IrisData.class));
org.mockito.Mockito.when(target.getDimension()).thenReturn(mock(art.arcane.iris.generation.terrain.IrisDimension.class));
var assembly = new EngineRuntimeBuilder.RuntimeAssembly(id, target,
java.nio.file.Path.of("build", "test-mantles", "placement-" + id));
assembly.mantle = mock(art.arcane.iris.generation.mantle.EngineMantle.class);
assembly.complex = mock(IrisComplex.class);
assembly.effects = mock(EngineEffects.class);
assembly.mode = mock(EngineMode.class);
assembly.worldManager = mock(EngineWorldManager.class);
assembly.hash32 = CompletableFuture.completedFuture(0L);
return assembly;
}
}
@@ -858,7 +858,7 @@ public class EngineShutdownDrainTest {
when(generation.runtimeKernel()).thenReturn(kernel); when(generation.runtimeKernel()).thenReturn(kernel);
GenerationRuntime nextGeneration = generation(target, mantle); GenerationRuntime nextGeneration = generation(target, mantle);
when(nextGeneration.complex()).thenReturn(replacement); when(nextGeneration.complex()).thenReturn(replacement);
when(generation.withComplex(anyInt(), same(replacement), isNull(), isNull(), any(), any())) when(generation.withComplex(anyInt(), same(replacement), isNull(), isNull(), any()))
.thenReturn(nextGeneration); .thenReturn(nextGeneration);
EngineRuntimeBuilder builder = spy(new EngineRuntimeBuilder(engine)); EngineRuntimeBuilder builder = spy(new EngineRuntimeBuilder(engine));
doReturn(new GenerationRuntime.BiomeMaxes(0D, 0D, 0D)).when(builder).computeBiomeMaxes(); doReturn(new GenerationRuntime.BiomeMaxes(0D, 0D, 0D)).when(builder).computeBiomeMaxes();
@@ -335,7 +335,6 @@ public class IrisEngineGenerationRuntimeScopeTest {
assertSame(detached.dimension, engine.getDimension()); assertSame(detached.dimension, engine.getDimension());
assertSame(detached.runtime.seedManager(), engine.getSeedManager()); assertSame(detached.runtime.seedManager(), engine.getSeedManager());
assertSame(detached.complex, engine.getComplex()); assertSame(detached.complex, engine.getComplex());
assertSame(detached.runtime.placementLifecycles(), engine.getPlacementLifecycles());
assertSame(detached.upperContext, engine.getUpperContext()); assertSame(detached.upperContext, engine.getUpperContext());
assertSame(detached.dimensionStackContext, engine.getDimensionStackContext()); assertSame(detached.dimensionStackContext, engine.getDimensionStackContext());
assertSame(detached.mode, engine.getMode()); assertSame(detached.mode, engine.getMode());
@@ -352,7 +351,6 @@ public class IrisEngineGenerationRuntimeScopeTest {
assertSame(active.target, engine.getTarget()); assertSame(active.target, engine.getTarget());
assertSame(active.data, engine.getData()); assertSame(active.data, engine.getData());
assertSame(active.runtime.seedManager(), engine.getSeedManager()); assertSame(active.runtime.seedManager(), engine.getSeedManager());
assertSame(active.runtime.placementLifecycles(), engine.getPlacementLifecycles());
assertSame(active.mantle, engine.getMantle()); assertSame(active.mantle, engine.getMantle());
assertEquals(1, engine.getCacheID()); assertEquals(1, engine.getCacheID());
} }
@@ -1011,8 +1009,7 @@ public class IrisEngineGenerationRuntimeScopeTest {
mantle, mantle,
mantleStorageDirectory, mantleStorageDirectory,
hash32, hash32,
new BiomeMaxes(objectDensity, layerDensity, decoratorDensity), new BiomeMaxes(objectDensity, layerDensity, decoratorDensity));
art.arcane.iris.structure.object.PlacementLifecycles.resolve());
return new RuntimeFixture( return new RuntimeFixture(
runtime, runtime,
target, target,
@@ -271,7 +271,7 @@ public class IrisObjectPlacementLifecycleRegressionTest {
} }
@Test @Test
public void runnerUsesTheEnginePlanAndCompletesTheBlockPassBeforeAfterBlocks() { public void customPlanCompletesTheBlockPassBeforeAfterBlocks() {
RecordingPlacer placer = new RecordingPlacer(engine); RecordingPlacer placer = new RecordingPlacer(engine);
PlacementLifecycleBuilder builder = new PlacementLifecycleBuilder(); PlacementLifecycleBuilder builder = new PlacementLifecycleBuilder();
ObjectPlaceMode.CENTER_HEIGHT.install(builder); ObjectPlaceMode.CENTER_HEIGHT.install(builder);
@@ -280,11 +280,10 @@ public class IrisObjectPlacementLifecycleRegressionTest {
List<Integer> finishedSizes = new ArrayList<>(); List<Integer> finishedSizes = new ArrayList<>();
builder.add(new PlacementLifecycleDependency("test.finished"), PlacementStage.AFTER_BLOCKS, builder.add(new PlacementLifecycleDependency("test.finished"), PlacementStage.AFTER_BLOCKS,
(context, state, ignored) -> finishedSizes.add(placer.writes().size())); (context, state, ignored) -> finishedSizes.add(placer.writes().size()));
PlacementLifecycles plans = mock(PlacementLifecycles.class); PlacementContext context = new PlacementContext(placement(), data, placer, null, new RNG(2L), lineObject(3),
when(plans.get(ObjectPlaceMode.CENTER_HEIGHT)).thenReturn(builder.build()); 0, 0, ANCHOR_Y, null);
when(engine.getPlacementLifecycles()).thenReturn(plans);
assertEquals(ANCHOR_Y + 5, lineObject(3).place(0, ANCHOR_Y, 0, placer, placement(), new RNG(2L), data)); assertEquals(ANCHOR_Y + 5, builder.build().execute(context).heightOrRejected());
assertEquals(List.of(3), finishedSizes); assertEquals(List.of(3), finishedSizes);
assertTrue(placer.writes().stream().allMatch(write -> write.y() == ANCHOR_Y + 5)); assertTrue(placer.writes().stream().allMatch(write -> write.y() == ANCHOR_Y + 5));
} }
@@ -98,7 +98,7 @@ public class PlacementLifecycleTest {
} }
@Test @Test
public void everyModeResolvesAndRuntimePlansAreIndependent() { public void everyModeResolvesToIndependentPlans() {
PlacementLifecycles first = PlacementLifecycles.resolve(); PlacementLifecycles first = PlacementLifecycles.resolve();
PlacementLifecycles second = PlacementLifecycles.resolve(); PlacementLifecycles second = PlacementLifecycles.resolve();
for (ObjectPlaceMode mode : ObjectPlaceMode.values()) { for (ObjectPlaceMode mode : ObjectPlaceMode.values()) {