mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-27 06:20:02 +00:00
Unlatch platform block states
- Replaced the nine static final PlatformBlockState fields in IrisDimensionStackActuator, IrisTerrainNormalActuator, IrisPerfectionModifier, IrisPostModifier, IrisBiomeLayerGenerator, BiomeBuffetGenerator, ChunkDataHunkHolder and EngineMantle with BoundBlockState holders that re-resolve when a different platform binds, costing one volatile read of the cached binding, one of the bound platform and a reference compare per read - Turned the IrisPerfectionModifier ore-hiding table into a Map of BoundBlockState so the four base states follow the bound platform instead of the first one loaded - Kept the last resolution in BoundBlockState while nothing is bound so in-flight generation on an unbinding server reads the same states it did before, matching what B.registries already does - Added IrisPlatforms.getOrNull so the block-state holders read the binding once without an exception on a bare JVM - Added PlatformStateRebindTest, which fails on the old code: it binds two mock platforms in turn and asserts ChunkDataHunkHolder and EngineMantle serve the second one, and rejects any static PlatformBlockState field left on the converted classes - Indexed the .iob write palette by key so palette lookup is a hash probe rather than a scan of the palette list, cutting the 32767-state IrisObjectIoWriteLimitsTest from 4.9s to 0.7s while writing byte-identical files - Built the palette once per write instead of once in validateWritable and again in the writer, and shared it between the plain and progress-reporting write paths - Added IrisObjectIoPaletteTest, which pins the SHA-256 of a 30000-block, 3011-state object written by the previous implementation and asserts the palette keeps first-seen insertion order - Added BukkitTestServer, a single mock Bukkit server installed once per JVM under a lock, stubbing logger, name, version, plugin manager and both createBlockData overloads, and failing loudly if the install does not take - Moved IrisRuntimeSchedulerModeRoutingTest, WorldRuntimeControlServiceTimeLockTest, PreObjectMatterTest, CNGInjectorParityTest, BukkitSpiConformanceTest, MantleWriterPreObjectJournalTest, IrisFloatingChildBiomesCarvingResolutionTest and IrisDimensionCarvingResolverParityTest onto it, so whichever class runs first no longer decides whether createBlockData or getPluginManager is stubbed - Extracted the KeyedBlockState test double out of IrisObjectIoWriteLimitsTest so the palette test can reuse it - Replaced the IrisServices.clear() teardowns in nine test classes with a targeted remove of the PreservationRegistry each one registers, so a teardown no longer wipes a binding it did not install - Registered a PreservationRegistry in PackDownloaderTest and StudioSVCWorldPackPublishTest, which reach IrisData.get and openRuntime and were silently getting loaderless IrisData whenever no other class had leaked one
This commit is contained in:
1 parent
266fe0d71c
commit
9b9ca8de34
40 files changed
+668
-481
No files matched your search
@@ -29,7 +29,7 @@ import art.arcane.iris.engine.hydrology.cave.HydrologyCaveCell;
|
||||
import art.arcane.iris.engine.object.IrisBiome;
|
||||
import art.arcane.iris.engine.object.IrisDimension;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import art.arcane.iris.util.common.data.B;
|
||||
import art.arcane.iris.util.common.data.BoundBlockState;
|
||||
import art.arcane.iris.util.project.context.ChunkContext;
|
||||
import art.arcane.iris.util.project.hunk.Hunk;
|
||||
import art.arcane.iris.util.project.matter.TileWrapper;
|
||||
@@ -49,8 +49,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class IrisDimensionStackActuator extends EngineAssignedActuator<PlatformBlockState> {
|
||||
private static final PlatformBlockState AIR = B.getState("AIR");
|
||||
private static final PlatformBlockState BEDROCK = B.getState("BEDROCK");
|
||||
private static final BoundBlockState AIR = BoundBlockState.of("AIR");
|
||||
private static final BoundBlockState BEDROCK = BoundBlockState.of("BEDROCK");
|
||||
private static final List<Class<?>> REPLACED_METADATA = List.of(
|
||||
TileWrapper.class,
|
||||
Identifier.class,
|
||||
@@ -161,7 +161,7 @@ public final class IrisDimensionStackActuator extends EngineAssignedActuator<Pla
|
||||
);
|
||||
for (int y = minimumY; y <= maximumY; y++) {
|
||||
metadata.clear(localX, y, localZ);
|
||||
output.setRaw(localX, y, localZ, AIR);
|
||||
output.setRaw(localX, y, localZ, AIR.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ public final class IrisDimensionStackActuator extends EngineAssignedActuator<Pla
|
||||
for (int y = layer.renderMaxY(); y >= layer.renderMinY(); y--) {
|
||||
int sourceY = y - layer.localBaseY();
|
||||
if (sourceY == 0 && dimension.isBedrock()) {
|
||||
writeBlock(output, metadata, localX, y, localZ, BEDROCK);
|
||||
writeBlock(output, metadata, localX, y, localZ, BEDROCK.get());
|
||||
continue;
|
||||
}
|
||||
if (sourceY > layer.normalTerrainHeight() && sourceY <= layer.fluidHeight()) {
|
||||
|
||||
@@ -34,6 +34,7 @@ import art.arcane.iris.engine.object.IrisOreGeneratorBounds;
|
||||
import art.arcane.iris.engine.object.IrisRegion;
|
||||
import art.arcane.iris.engine.object.IrisRiverMaterialConfig;
|
||||
import art.arcane.iris.engine.object.IrisSurfaceRiverBankConfig;
|
||||
import art.arcane.iris.util.common.data.BoundBlockState;
|
||||
import art.arcane.volmlib.util.collection.KList;
|
||||
import art.arcane.iris.util.project.context.ChunkedDataCache;
|
||||
import art.arcane.iris.util.project.context.ChunkContext;
|
||||
@@ -42,11 +43,10 @@ import art.arcane.iris.util.project.hunk.Hunk;
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
import art.arcane.volmlib.util.scheduling.PrecisionStopwatch;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import art.arcane.iris.util.common.data.B;
|
||||
import lombok.Getter;
|
||||
|
||||
public class IrisTerrainNormalActuator extends EngineAssignedActuator<PlatformBlockState> {
|
||||
private static final PlatformBlockState BEDROCK = B.getState("BEDROCK");
|
||||
private static final BoundBlockState BEDROCK = BoundBlockState.of("BEDROCK");
|
||||
@Getter
|
||||
private final RNG rng;
|
||||
@Getter
|
||||
@@ -161,7 +161,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<PlatformBl
|
||||
|
||||
for (int i = topY; i >= 0; i--) {
|
||||
if (i == 0 && bedrockEnabled) {
|
||||
h.setRaw(xf, i, zf, BEDROCK);
|
||||
h.setRaw(xf, i, zf, BEDROCK.get());
|
||||
lastBedrock = i;
|
||||
continue;
|
||||
}
|
||||
@@ -256,7 +256,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<PlatformBl
|
||||
|
||||
for (int y = chunkHeight - 1; y >= upperSurfaceY; y--) {
|
||||
if (y == chunkHeight - 1 && bedrockEnabled) {
|
||||
h.setRaw(xf, y, zf, BEDROCK);
|
||||
h.setRaw(xf, y, zf, BEDROCK.get());
|
||||
continue;
|
||||
}
|
||||
if (y == upperSurfaceY && upperMappedSurface != null) {
|
||||
|
||||
@@ -413,7 +413,7 @@ final class DecoratorCore {
|
||||
if (mantle != null) {
|
||||
rs = mantle.getMantle().get(x + f.getModX(), yy, z + f.getModZ(), PlatformBlockState.class);
|
||||
}
|
||||
BlockData r = rs == null ? (BlockData) EngineMantle.AIR.nativeHandle() : (BlockData) rs.nativeHandle();
|
||||
BlockData r = rs == null ? (BlockData) EngineMantle.AIR.get().nativeHandle() : (BlockData) rs.nativeHandle();
|
||||
if (r.isFaceSturdy(f.getOppositeFace(), BlockSupport.FULL)) {
|
||||
if (data.getAllowedFaces().contains(f)) {
|
||||
found = true;
|
||||
|
||||
@@ -34,9 +34,9 @@ import art.arcane.iris.engine.object.IrisDimension;
|
||||
import art.arcane.iris.engine.hydrology.cave.HydrologyCaveCell;
|
||||
import art.arcane.iris.engine.hydrology.cave.HydrologyCaveStorage;
|
||||
import art.arcane.iris.engine.object.IrisPosition;
|
||||
import art.arcane.iris.util.common.data.BoundBlockState;
|
||||
import art.arcane.iris.util.project.matter.PreObjectMatterCell;
|
||||
import art.arcane.volmlib.util.collection.KList;
|
||||
import art.arcane.iris.util.common.data.B;
|
||||
import art.arcane.volmlib.util.documentation.BlockCoordinates;
|
||||
import art.arcane.volmlib.util.documentation.ChunkCoordinates;
|
||||
import art.arcane.iris.util.project.hunk.Hunk;
|
||||
@@ -61,7 +61,7 @@ import java.util.OptionalInt;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public interface EngineMantle extends MatterGenerator {
|
||||
PlatformBlockState AIR = B.getState("AIR");
|
||||
BoundBlockState AIR = BoundBlockState.of("AIR");
|
||||
|
||||
Mantle<Matter> getMantle();
|
||||
|
||||
@@ -161,7 +161,7 @@ public interface EngineMantle extends MatterGenerator {
|
||||
return natural;
|
||||
}
|
||||
}
|
||||
return block == null ? AIR : block;
|
||||
return block == null ? AIR.get() : block;
|
||||
}
|
||||
|
||||
default boolean isPreventingDecay() {
|
||||
|
||||
@@ -487,7 +487,7 @@ public class MantleWriter implements ObjectPassPlacer, AutoCloseable {
|
||||
return resolvedBlock(resolved.get(), y);
|
||||
}
|
||||
PlatformBlockState block = getPrerequisiteDataIfPresent(x, y, z, PlatformBlockState.class);
|
||||
return block == null ? AIR : block;
|
||||
return block == null ? AIR.get() : block;
|
||||
}
|
||||
|
||||
public boolean isPrerequisiteCarved(int x, int y, int z) {
|
||||
@@ -856,7 +856,7 @@ public class MantleWriter implements ObjectPassPlacer, AutoCloseable {
|
||||
}
|
||||
}
|
||||
if (block == null)
|
||||
return AIR;
|
||||
return AIR.get();
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -126,7 +126,7 @@ final class ObjectDestinationTransaction implements ObjectPassPlacer {
|
||||
DataKey key = new DataKey(x, y, z, PlatformBlockState.class);
|
||||
Object value = overlay.get(key);
|
||||
if (value == CLEARED) {
|
||||
return EngineMantle.AIR;
|
||||
return EngineMantle.AIR.get();
|
||||
}
|
||||
return value instanceof PlatformBlockState state
|
||||
? state
|
||||
|
||||
@@ -55,8 +55,6 @@ import java.util.Optional;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
|
||||
import static art.arcane.iris.engine.mantle.EngineMantle.AIR;
|
||||
|
||||
public class IrisFloatingChildBiomeModifier extends EngineAssignedModifier<PlatformBlockState> {
|
||||
public static final long FLOATING_BASE_SEED_SALT = 0x5EED_F107_00F1B10CL;
|
||||
private static final Runnable NOOP_DECORATION_MISS = () -> {
|
||||
|
||||
@@ -22,6 +22,7 @@ import art.arcane.iris.engine.decorator.IrisSpeleothems;
|
||||
import art.arcane.iris.engine.framework.Engine;
|
||||
import art.arcane.iris.engine.framework.EngineAssignedModifier;
|
||||
import art.arcane.iris.engine.object.IrisProceduralBlocks;
|
||||
import art.arcane.iris.util.common.data.BoundBlockState;
|
||||
import art.arcane.iris.util.project.context.ChunkContext;
|
||||
import art.arcane.iris.util.common.data.B;
|
||||
import art.arcane.iris.util.project.hunk.Hunk;
|
||||
@@ -36,22 +37,20 @@ import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class IrisPerfectionModifier extends EngineAssignedModifier<PlatformBlockState> {
|
||||
private static final class States {
|
||||
private static final PlatformBlockState AIR = B.getState("AIR");
|
||||
private static final PlatformBlockState WATER = B.getState("WATER");
|
||||
private static final Map<String, PlatformBlockState> ORE_BASES = buildOreBases();
|
||||
}
|
||||
private static final BoundBlockState AIR = BoundBlockState.of("AIR");
|
||||
private static final BoundBlockState WATER = BoundBlockState.of("WATER");
|
||||
private static final Map<String, BoundBlockState> ORE_BASES = buildOreBases();
|
||||
|
||||
public IrisPerfectionModifier(Engine engine) {
|
||||
super(engine, "Perfection");
|
||||
}
|
||||
|
||||
private static Map<String, PlatformBlockState> buildOreBases() {
|
||||
Map<String, PlatformBlockState> map = new HashMap<>();
|
||||
PlatformBlockState stone = B.getState("STONE");
|
||||
PlatformBlockState deepslate = B.getState("DEEPSLATE");
|
||||
PlatformBlockState netherrack = B.getState("NETHERRACK");
|
||||
PlatformBlockState blackstone = B.getState("BLACKSTONE");
|
||||
private static Map<String, BoundBlockState> buildOreBases() {
|
||||
Map<String, BoundBlockState> map = new HashMap<>();
|
||||
BoundBlockState stone = BoundBlockState.of("STONE");
|
||||
BoundBlockState deepslate = BoundBlockState.of("DEEPSLATE");
|
||||
BoundBlockState netherrack = BoundBlockState.of("NETHERRACK");
|
||||
BoundBlockState blackstone = BoundBlockState.of("BLACKSTONE");
|
||||
map.put("minecraft:coal_ore", stone);
|
||||
map.put("minecraft:copper_ore", stone);
|
||||
map.put("minecraft:iron_ore", stone);
|
||||
@@ -106,7 +105,7 @@ public class IrisPerfectionModifier extends EngineAssignedModifier<PlatformBlock
|
||||
for (int k = top; k >= 0; k--) {
|
||||
PlatformBlockState b = output.get(finalI, k, j);
|
||||
if (IrisSpeleothems.isSpike(b)) {
|
||||
b = normalizeSpike(b, output, finalI, j, k, States.AIR, States.WATER);
|
||||
b = normalizeSpike(b, output, finalI, j, k, AIR.get(), WATER.get());
|
||||
}
|
||||
boolean now = b != null && !(B.isAir(b) || B.isFluid(b));
|
||||
|
||||
@@ -148,10 +147,10 @@ public class IrisPerfectionModifier extends EngineAssignedModifier<PlatformBlock
|
||||
|
||||
if (remove) {
|
||||
changed.set(true);
|
||||
output.set(finalI, k, j, States.AIR);
|
||||
output.set(finalI, k, j, AIR.get());
|
||||
|
||||
if (remove2) {
|
||||
output.set(finalI, k - 1, j, States.AIR);
|
||||
output.set(finalI, k - 1, j, AIR.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,9 +210,9 @@ public class IrisPerfectionModifier extends EngineAssignedModifier<PlatformBlock
|
||||
if (block == null) {
|
||||
continue;
|
||||
}
|
||||
PlatformBlockState base = States.ORE_BASES.get(baseKey(block));
|
||||
BoundBlockState base = ORE_BASES.get(baseKey(block));
|
||||
if (base != null) {
|
||||
output.set(finalI, k, j, base);
|
||||
output.set(finalI, k, j, base.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import art.arcane.iris.engine.object.IrisBiome;
|
||||
import art.arcane.iris.engine.object.IrisDimension;
|
||||
import art.arcane.iris.engine.object.IrisProceduralBlocks;
|
||||
import art.arcane.iris.engine.object.IrisSlopeClip;
|
||||
import art.arcane.iris.util.common.data.BoundBlockState;
|
||||
import art.arcane.iris.util.project.context.ChunkContext;
|
||||
import art.arcane.iris.util.common.data.B;
|
||||
import art.arcane.iris.util.project.hunk.Hunk;
|
||||
@@ -34,9 +35,7 @@ import art.arcane.volmlib.util.scheduling.PrecisionStopwatch;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
|
||||
public class IrisPostModifier extends EngineAssignedModifier<PlatformBlockState> {
|
||||
private static final class States {
|
||||
private static final PlatformBlockState AIR = B.getState("AIR");
|
||||
}
|
||||
private static final BoundBlockState AIR = BoundBlockState.of("AIR");
|
||||
|
||||
private final RNG rng;
|
||||
|
||||
@@ -136,7 +135,7 @@ public class IrisPostModifier extends EngineAssignedModifier<PlatformBlockState>
|
||||
g += hd < h - 1 ? 1 : 0;
|
||||
|
||||
if (!river && g == 4 && isAir(x, h - 1, z, originX, originZ, currentData)) {
|
||||
setPostBlock(x, h, z, States.AIR, originX, originZ, currentData);
|
||||
setPostBlock(x, h, z, AIR.get(), originX, originZ, currentData);
|
||||
|
||||
for (int i = h - 1; i > 0; i--) {
|
||||
if (!isAir(x, i, z, originX, originZ, currentData)) {
|
||||
@@ -296,7 +295,7 @@ public class IrisPostModifier extends EngineAssignedModifier<PlatformBlockState>
|
||||
PlatformBlockState onto = getPostBlock(x, h, z, originX, originZ, currentData);
|
||||
|
||||
if (!B.canPlaceOnto(b, onto) && !B.isDecorant(b)) {
|
||||
setPostBlock(x, h + 1, z, States.AIR, originX, originZ, currentData);
|
||||
setPostBlock(x, h + 1, z, AIR.get(), originX, originZ, currentData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -366,6 +365,6 @@ public class IrisPostModifier extends EngineAssignedModifier<PlatformBlockState>
|
||||
public PlatformBlockState getPostBlock(int x, int y, int z, int originX, int originZ, Hunk<PlatformBlockState> h) {
|
||||
PlatformBlockState b = h.getClosest(x - originX, y, z - originZ);
|
||||
|
||||
return b == null ? States.AIR : b;
|
||||
return b == null ? AIR.get() : b;
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import art.arcane.iris.engine.framework.Engine;
|
||||
import art.arcane.iris.spi.IrisLogging;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import art.arcane.iris.util.common.data.B;
|
||||
import art.arcane.iris.util.common.data.BoundBlockState;
|
||||
import art.arcane.iris.util.project.noise.CNG;
|
||||
import art.arcane.iris.util.project.stream.ProceduralStream;
|
||||
import art.arcane.volmlib.util.collection.KList;
|
||||
@@ -35,9 +36,7 @@ import art.arcane.volmlib.util.math.RNG;
|
||||
* JSON, so its fields stay put and only the behavior lives here.
|
||||
*/
|
||||
final class IrisBiomeLayerGenerator {
|
||||
private static final class States {
|
||||
private static final PlatformBlockState BARRIER = B.getState("BARRIER");
|
||||
}
|
||||
private static final BoundBlockState BARRIER = BoundBlockState.of("BARRIER");
|
||||
|
||||
private IrisBiomeLayerGenerator() {
|
||||
}
|
||||
@@ -96,7 +95,7 @@ final class IrisBiomeLayerGenerator {
|
||||
|
||||
if (dim.isExplodeBiomePalettes()) {
|
||||
for (int j = 0; j < dim.getExplodeBiomePaletteSize(); j++) {
|
||||
data.add(States.BARRIER);
|
||||
data.add(BARRIER.get());
|
||||
|
||||
if (data.size() >= maxDepth) {
|
||||
break;
|
||||
@@ -143,7 +142,7 @@ final class IrisBiomeLayerGenerator {
|
||||
|
||||
if (dim.isExplodeBiomePalettes()) {
|
||||
for (int j = 0; j < dim.getExplodeBiomePaletteSize(); j++) {
|
||||
data.add(States.BARRIER);
|
||||
data.add(BARRIER.get());
|
||||
|
||||
if (data.size() >= maxDepth) {
|
||||
break;
|
||||
|
||||
@@ -41,6 +41,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -264,10 +265,7 @@ public final class IrisObjectIO {
|
||||
* write path now rejects them with a descriptive error before any byte is written.
|
||||
*/
|
||||
static void validateWritable(IrisObject self) throws IOException {
|
||||
KList<String> palette = new KList<>();
|
||||
for (PlatformBlockState i : self.blocks.values()) {
|
||||
palette.addIfMissing(i.key());
|
||||
}
|
||||
Palette palette = buildPalette(self);
|
||||
if (palette.size() > MAX_PALETTE_ENTRIES) {
|
||||
throw new IOException("Object '" + self.getLoadKey() + "' has " + palette.size()
|
||||
+ " distinct block states; the .iob format supports at most " + MAX_PALETTE_ENTRIES + ".");
|
||||
@@ -280,6 +278,14 @@ public final class IrisObjectIO {
|
||||
}
|
||||
}
|
||||
|
||||
private static Palette buildPalette(IrisObject self) {
|
||||
Palette palette = new Palette();
|
||||
for (PlatformBlockState i : self.blocks.values()) {
|
||||
palette.add(i.key());
|
||||
}
|
||||
return palette;
|
||||
}
|
||||
|
||||
private static void requireShortCoordinates(IrisObject self, String kind, IrisBlockVector position) throws IOException {
|
||||
requireShort(self, kind, "x", position.getBlockX(), position);
|
||||
requireShort(self, kind, "y", position.getBlockY(), position);
|
||||
@@ -305,15 +311,11 @@ public final class IrisObjectIO {
|
||||
dos.writeInt(self.h);
|
||||
dos.writeInt(self.d);
|
||||
dos.writeUTF("Iris V2 IOB;");
|
||||
KList<String> palette = new KList<>();
|
||||
|
||||
for (PlatformBlockState i : self.blocks.values()) {
|
||||
palette.addIfMissing(i.key());
|
||||
}
|
||||
Palette palette = buildPalette(self);
|
||||
|
||||
dos.writeShort(palette.size());
|
||||
|
||||
for (String i : palette) {
|
||||
for (String i : palette.keys()) {
|
||||
dos.writeUTF(i);
|
||||
}
|
||||
|
||||
@@ -363,17 +365,13 @@ public final class IrisObjectIO {
|
||||
dos.writeInt(self.d);
|
||||
dos.writeUTF("Iris V2 IOB;");
|
||||
|
||||
KList<String> palette = new KList<>();
|
||||
|
||||
for (PlatformBlockState i : self.blocks.values()) {
|
||||
palette.addIfMissing(i.key());
|
||||
++c;
|
||||
}
|
||||
Palette palette = buildPalette(self);
|
||||
c += self.blocks.size();
|
||||
total -= self.blocks.size() - palette.size();
|
||||
|
||||
dos.writeShort(palette.size());
|
||||
|
||||
for (String i : palette) {
|
||||
for (String i : palette.keys()) {
|
||||
dos.writeUTF(i);
|
||||
++c;
|
||||
}
|
||||
@@ -458,4 +456,29 @@ public final class IrisObjectIO {
|
||||
super("Invalid Header");
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Palette {
|
||||
private final KList<String> keys = new KList<>();
|
||||
private final Map<String, Integer> index = new HashMap<>();
|
||||
|
||||
private void add(String key) {
|
||||
index.computeIfAbsent(key, k -> {
|
||||
keys.add(k);
|
||||
return keys.size() - 1;
|
||||
});
|
||||
}
|
||||
|
||||
private int indexOf(String key) {
|
||||
Integer found = index.get(key);
|
||||
return found == null ? -1 : found;
|
||||
}
|
||||
|
||||
private int size() {
|
||||
return keys.size();
|
||||
}
|
||||
|
||||
private KList<String> keys() {
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -26,13 +26,13 @@ import art.arcane.iris.engine.framework.WrongEngineBroException;
|
||||
import art.arcane.iris.engine.object.IrisBiome;
|
||||
import art.arcane.iris.engine.platform.studio.EnginedStudioGenerator;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import art.arcane.iris.util.common.data.B;
|
||||
import art.arcane.iris.util.common.data.BoundBlockState;
|
||||
import art.arcane.iris.util.project.context.IrisContext;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class BiomeBuffetGenerator extends EnginedStudioGenerator {
|
||||
private static final PlatformBlockState FLOOR = B.getState("BARRIER");
|
||||
private static final BoundBlockState FLOOR = BoundBlockState.of("BARRIER");
|
||||
private final IrisBiome[] biomes;
|
||||
private final int width;
|
||||
private final int biomeSize;
|
||||
@@ -66,7 +66,7 @@ public class BiomeBuffetGenerator extends EnginedStudioGenerator {
|
||||
if (biome == null) {
|
||||
try (GenerationSessionLease lease = engine.acquireGenerationLease("bukkit_biome_buffet_stage");
|
||||
IrisContext.Scope ignored = IrisContext.open(engine, lease.sessionId(), null)) {
|
||||
tc.setRegion(0, 0, 0, 16, 1, 16, FLOOR);
|
||||
tc.setRegion(0, 0, 0, 16, 1, 16, FLOOR.get());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2026 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package art.arcane.iris.util.common.data;
|
||||
|
||||
import art.arcane.iris.spi.IrisPlatform;
|
||||
import art.arcane.iris.spi.IrisPlatforms;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
|
||||
public final class BoundBlockState {
|
||||
private final String key;
|
||||
private volatile Bound bound;
|
||||
|
||||
private BoundBlockState(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public static BoundBlockState of(String key) {
|
||||
return new BoundBlockState(key);
|
||||
}
|
||||
|
||||
public PlatformBlockState get() {
|
||||
Bound current = bound;
|
||||
IrisPlatform platform = IrisPlatforms.getOrNull();
|
||||
|
||||
if (current != null && (platform == null || current.platform() == platform)) {
|
||||
return current.state();
|
||||
}
|
||||
|
||||
IrisPlatform resolvedPlatform = IrisPlatforms.get();
|
||||
Bound resolved = new Bound(resolvedPlatform, B.getState(key));
|
||||
bound = resolved;
|
||||
return resolved.state();
|
||||
}
|
||||
|
||||
private record Bound(IrisPlatform platform, PlatformBlockState state) {
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ package art.arcane.iris.util.project.hunk.view;
|
||||
|
||||
import art.arcane.iris.core.nms.INMS;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import art.arcane.iris.util.common.data.B;
|
||||
import art.arcane.iris.util.common.data.BoundBlockState;
|
||||
import art.arcane.iris.util.common.data.IrisCustomData;
|
||||
import art.arcane.iris.util.project.hunk.storage.AtomicHunk;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
@@ -28,9 +28,7 @@ import org.bukkit.generator.ChunkGenerator.ChunkData;
|
||||
|
||||
@SuppressWarnings("ClassCanBeRecord")
|
||||
public class ChunkDataHunkHolder extends AtomicHunk<PlatformBlockState> {
|
||||
private static final class States {
|
||||
private static final PlatformBlockState AIR = B.getState("AIR");
|
||||
}
|
||||
private static final BoundBlockState AIR = BoundBlockState.of("AIR");
|
||||
|
||||
private final ChunkData chunk;
|
||||
|
||||
@@ -63,12 +61,12 @@ public class ChunkDataHunkHolder extends AtomicHunk<PlatformBlockState> {
|
||||
@Override
|
||||
public PlatformBlockState getRaw(int x, int y, int z) {
|
||||
if (y < 0 || y >= getHeight()) {
|
||||
return States.AIR;
|
||||
return AIR.get();
|
||||
}
|
||||
|
||||
PlatformBlockState b = super.getRaw(x, y, z);
|
||||
|
||||
return b != null ? b : States.AIR;
|
||||
return b != null ? b : AIR.get();
|
||||
}
|
||||
|
||||
public PlatformBlockState getStoredRaw(int x, int y, int z) {
|
||||
|
||||
Reference in new issue
Block a user