mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-12 03:24:14 +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:
@@ -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) {
|
||||
|
||||
@@ -1,22 +1,11 @@
|
||||
package art.arcane.iris.core;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import art.arcane.iris.testsupport.BukkitTestServer;
|
||||
import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.mockingDetails;
|
||||
|
||||
public class IrisRuntimeSchedulerModeRoutingTest {
|
||||
@@ -65,30 +54,7 @@ public class IrisRuntimeSchedulerModeRoutingTest {
|
||||
}
|
||||
|
||||
private void installServer(String name, String version) {
|
||||
Server server = Bukkit.getServer();
|
||||
if (server == null) {
|
||||
server = mock(Server.class);
|
||||
try {
|
||||
Bukkit.setServer(server);
|
||||
} catch (Throwable ignored) {
|
||||
server = Bukkit.getServer();
|
||||
}
|
||||
}
|
||||
|
||||
assumeTrue(server != null && mockingDetails(server).isMock());
|
||||
|
||||
doReturn(Logger.getLogger("IrisTest")).when(server).getLogger();
|
||||
doReturn(name).when(server).getName();
|
||||
doReturn(version).when(server).getVersion();
|
||||
doReturn(version).when(server).getBukkitVersion();
|
||||
doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, Material.class).name().toLowerCase(Locale.ROOT))).when(server).createBlockData(any(Material.class));
|
||||
doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, String.class))).when(server).createBlockData(anyString());
|
||||
}
|
||||
|
||||
private static BlockData namedBlockData(String key) {
|
||||
String canonical = key.indexOf(':') >= 0 ? key : "minecraft:" + key;
|
||||
BlockData data = mock(BlockData.class);
|
||||
doReturn(canonical).when(data).getAsString();
|
||||
return data;
|
||||
assumeTrue(mockingDetails(BukkitTestServer.install()).isMock());
|
||||
BukkitTestServer.brand(name, version);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public class IrisDataAuthoringCacheTest {
|
||||
if (epoch != null) {
|
||||
epoch.close();
|
||||
}
|
||||
IrisServices.clear();
|
||||
IrisServices.remove(PreservationRegistry.class);
|
||||
IrisSettings.settings = previousSettings;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ public class IrisDataDatapackCompilerCacheTest {
|
||||
if (runtimeData != null) {
|
||||
runtimeData.close();
|
||||
}
|
||||
IrisServices.clear();
|
||||
IrisServices.remove(PreservationRegistry.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -36,7 +36,7 @@ public class IrisDataEngineRegistryTest {
|
||||
if (data != null) {
|
||||
data.close();
|
||||
}
|
||||
IrisServices.clear();
|
||||
IrisServices.remove(PreservationRegistry.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -37,7 +37,7 @@ public class IrisDataRetainedPackTest {
|
||||
if (retained != null) {
|
||||
retained.close();
|
||||
}
|
||||
IrisServices.clear();
|
||||
IrisServices.remove(PreservationRegistry.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -20,10 +20,12 @@ package art.arcane.iris.core.pack;
|
||||
|
||||
import art.arcane.iris.core.IrisSettings;
|
||||
import art.arcane.iris.core.loader.IrisData;
|
||||
import art.arcane.iris.engine.framework.PreservationRegistry;
|
||||
import art.arcane.iris.engine.object.IrisDimension;
|
||||
import art.arcane.iris.engine.object.IrisEnvironment;
|
||||
import art.arcane.iris.spi.IrisPlatform;
|
||||
import art.arcane.iris.spi.IrisPlatforms;
|
||||
import art.arcane.iris.spi.IrisServices;
|
||||
import art.arcane.iris.spi.PlatformStructureHooks;
|
||||
import org.junit.Assume;
|
||||
import org.junit.After;
|
||||
@@ -92,6 +94,7 @@ public class PackDownloaderTest {
|
||||
when(structureHooks.templatePoolKeys()).thenReturn(List.of("minecraft:empty"));
|
||||
IrisPlatforms.bind(platform);
|
||||
IrisSettings.settings = new IrisSettings();
|
||||
IrisServices.register(PreservationRegistry.class, mock(PreservationRegistry.class));
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -102,6 +105,7 @@ public class PackDownloaderTest {
|
||||
}
|
||||
IrisSettings.settings = previousSettings;
|
||||
PackValidationRegistry.clear();
|
||||
IrisServices.remove(PreservationRegistry.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Vendored
+1
-1
@@ -39,7 +39,7 @@ public class PregenCacheExecutorRegistrationTest {
|
||||
|
||||
@After
|
||||
public void clearServices() {
|
||||
IrisServices.clear();
|
||||
IrisServices.remove(PreservationRegistry.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -61,7 +61,7 @@ public class IrisCodeWorkspaceTest {
|
||||
data.close();
|
||||
data = null;
|
||||
}
|
||||
IrisServices.clear();
|
||||
IrisServices.remove(PreservationRegistry.class);
|
||||
IrisPlatforms.unbind();
|
||||
if (previousPlatform != null) {
|
||||
IrisPlatforms.bind(previousPlatform);
|
||||
|
||||
+2
-17
@@ -2,10 +2,9 @@ package art.arcane.iris.core.runtime;
|
||||
|
||||
import art.arcane.iris.core.lifecycle.CapabilitySnapshot;
|
||||
import art.arcane.iris.core.lifecycle.ServerFamily;
|
||||
import art.arcane.iris.testsupport.BukkitTestServer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -14,28 +13,14 @@ import java.lang.reflect.Proxy;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class WorldRuntimeControlServiceTimeLockTest {
|
||||
@Before
|
||||
public void ensureBukkitServer() {
|
||||
if (Bukkit.getServer() != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Server server = mock(Server.class);
|
||||
PluginManager pluginManager = mock(PluginManager.class);
|
||||
doReturn(pluginManager).when(server).getPluginManager();
|
||||
doReturn(Logger.getLogger("WorldRuntimeControlServiceTimeLockTest")).when(server).getLogger();
|
||||
try {
|
||||
Bukkit.setServer(server);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
BukkitTestServer.install();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -6,8 +6,11 @@ import art.arcane.iris.core.pack.AtomicDirectoryPublisher;
|
||||
import art.arcane.iris.core.pack.BrokenPackException;
|
||||
import art.arcane.iris.core.pack.PackValidationRegistry;
|
||||
import art.arcane.iris.core.pack.PackValidationResult;
|
||||
import art.arcane.iris.engine.framework.PreservationRegistry;
|
||||
import art.arcane.iris.spi.IrisServices;
|
||||
import org.junit.Assume;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
@@ -26,14 +29,21 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class StudioSVCWorldPackPublishTest {
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
@Before
|
||||
public void registerPreservationService() {
|
||||
IrisServices.register(PreservationRegistry.class, mock(PreservationRegistry.class));
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearValidationRegistry() {
|
||||
PackValidationRegistry.clear();
|
||||
IrisServices.remove(PreservationRegistry.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ public class IrisDataStructureRecoveryTest {
|
||||
if (data != null) {
|
||||
data.close();
|
||||
}
|
||||
IrisServices.clear();
|
||||
IrisServices.remove(PreservationRegistry.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -66,7 +66,7 @@ public class SavedBiomeRuntimeTest {
|
||||
|
||||
@After
|
||||
public void restoreServices() {
|
||||
IrisServices.clear();
|
||||
IrisServices.remove(PreservationRegistry.class);
|
||||
IrisSettings.settings = previousSettings;
|
||||
}
|
||||
|
||||
|
||||
+2
-28
@@ -6,6 +6,7 @@ import art.arcane.iris.spi.IrisPlatform;
|
||||
import art.arcane.iris.spi.IrisPlatforms;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import art.arcane.iris.spi.PlatformRegistries;
|
||||
import art.arcane.iris.testsupport.BukkitTestServer;
|
||||
import art.arcane.iris.util.project.matter.IrisMatterSupport;
|
||||
import art.arcane.iris.util.project.matter.PreObjectMatterCell;
|
||||
import art.arcane.volmlib.util.mantle.runtime.Mantle;
|
||||
@@ -14,10 +15,6 @@ import art.arcane.volmlib.util.matter.IrisMatter;
|
||||
import art.arcane.volmlib.util.matter.Matter;
|
||||
import art.arcane.volmlib.util.matter.MatterCavern;
|
||||
import art.arcane.volmlib.util.matter.MatterSlice;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
@@ -28,8 +25,6 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -38,9 +33,6 @@ import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -54,20 +46,7 @@ public class MantleWriterPreObjectJournalTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBukkit() {
|
||||
if (Bukkit.getServer() != null) {
|
||||
return;
|
||||
}
|
||||
Server server = mock(Server.class);
|
||||
doReturn(Logger.getLogger("IrisTest")).when(server).getLogger();
|
||||
doReturn("IrisTestServer").when(server).getName();
|
||||
doReturn("1.0").when(server).getVersion();
|
||||
doReturn("1.0").when(server).getBukkitVersion();
|
||||
doAnswer(invocation -> blockData(invocation.getArgument(0, Material.class).name()
|
||||
.toLowerCase(Locale.ROOT))).when(server).createBlockData(any(Material.class));
|
||||
try {
|
||||
Bukkit.setServer(server);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
BukkitTestServer.install();
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -230,9 +209,4 @@ public class MantleWriterPreObjectJournalTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static BlockData blockData(String key) {
|
||||
BlockData data = mock(BlockData.class);
|
||||
doReturn("minecraft:" + key).when(data).getAsString();
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ final class CompatTestPlatform {
|
||||
}
|
||||
|
||||
void unbind() {
|
||||
IrisServices.clear();
|
||||
IrisServices.remove(PreservationRegistry.class);
|
||||
IrisPlatforms.unbind();
|
||||
if (previous != null) {
|
||||
IrisPlatforms.bind(previous);
|
||||
|
||||
+2
-29
@@ -4,12 +4,9 @@ import art.arcane.iris.core.loader.IrisData;
|
||||
import art.arcane.iris.core.loader.ResourceLoader;
|
||||
import art.arcane.iris.engine.framework.Engine;
|
||||
import art.arcane.iris.engine.framework.SeedManager;
|
||||
import art.arcane.iris.testsupport.BukkitTestServer;
|
||||
import art.arcane.iris.util.project.noise.CNG;
|
||||
import art.arcane.volmlib.util.collection.KList;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
@@ -19,7 +16,6 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@@ -27,7 +23,6 @@ import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
@@ -38,7 +33,6 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyDouble;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
@@ -53,28 +47,7 @@ public class IrisDimensionCarvingResolverParityTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void setupBukkit() {
|
||||
if (Bukkit.getServer() != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Server server = mock(Server.class);
|
||||
doReturn(Logger.getLogger("IrisTest")).when(server).getLogger();
|
||||
doReturn("IrisTestServer").when(server).getName();
|
||||
doReturn("1.0").when(server).getVersion();
|
||||
doReturn("1.0").when(server).getBukkitVersion();
|
||||
doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, Material.class).name().toLowerCase(Locale.ROOT))).when(server).createBlockData(any(Material.class));
|
||||
doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, String.class))).when(server).createBlockData(anyString());
|
||||
try {
|
||||
Bukkit.setServer(server);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private static BlockData namedBlockData(String key) {
|
||||
String canonical = key.indexOf(':') >= 0 ? key : "minecraft:" + key;
|
||||
BlockData data = mock(BlockData.class);
|
||||
doReturn(canonical).when(data).getAsString();
|
||||
return data;
|
||||
BukkitTestServer.install();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+2
-32
@@ -3,52 +3,22 @@ package art.arcane.iris.engine.object;
|
||||
import art.arcane.iris.core.loader.IrisData;
|
||||
import art.arcane.iris.core.loader.ResourceLoader;
|
||||
import art.arcane.iris.engine.framework.Engine;
|
||||
import art.arcane.iris.testsupport.BukkitTestServer;
|
||||
import art.arcane.volmlib.util.collection.KList;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class IrisFloatingChildBiomesCarvingResolutionTest {
|
||||
@BeforeClass
|
||||
public static void setupBukkit() {
|
||||
if (Bukkit.getServer() != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Server server = mock(Server.class);
|
||||
doReturn(Logger.getLogger("IrisTest")).when(server).getLogger();
|
||||
doReturn("IrisTestServer").when(server).getName();
|
||||
doReturn("1.0").when(server).getVersion();
|
||||
doReturn("1.0").when(server).getBukkitVersion();
|
||||
doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, Material.class).name().toLowerCase(Locale.ROOT))).when(server).createBlockData(any(Material.class));
|
||||
doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, String.class))).when(server).createBlockData(anyString());
|
||||
try {
|
||||
Bukkit.setServer(server);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private static BlockData namedBlockData(String key) {
|
||||
String canonical = key.indexOf(':') >= 0 ? key : "minecraft:" + key;
|
||||
BlockData data = mock(BlockData.class);
|
||||
doReturn(canonical).when(data).getAsString();
|
||||
return data;
|
||||
BukkitTestServer.install();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
package art.arcane.iris.engine.object;
|
||||
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import art.arcane.iris.util.common.math.IrisBlockVector;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.HexFormat;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class IrisObjectIoPaletteTest {
|
||||
private static final int BLOCK_COUNT = 30_000;
|
||||
private static final int UNIQUE_KEYS = 3_000;
|
||||
private static final String PINNED_DIGEST = "9fbd42fe7686cc725e0acab8595b0223d71c1a45762b78ac0e6146230dbb8849";
|
||||
|
||||
@Test
|
||||
public void writesTheSameBytesAsTheOrderedPaletteScan() throws IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
|
||||
IrisObjectIO.write(representativeObject(), out);
|
||||
|
||||
assertEquals(PINNED_DIGEST, digest(out.toByteArray()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void paletteKeepsFirstSeenInsertionOrder() throws IOException {
|
||||
IrisObject object = representativeObject();
|
||||
List<String> firstSeen = new ArrayList<>();
|
||||
Set<String> seen = new HashSet<>();
|
||||
|
||||
for (Map.Entry<IrisBlockVector, PlatformBlockState> entry : object.blocks) {
|
||||
if (seen.add(entry.getValue().key())) {
|
||||
firstSeen.add(entry.getValue().key());
|
||||
}
|
||||
}
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
IrisObjectIO.write(object, out);
|
||||
|
||||
assertEquals(firstSeen, writtenPalette(out.toByteArray()));
|
||||
}
|
||||
|
||||
private static List<String> writtenPalette(byte[] bytes) throws IOException {
|
||||
DataInputStream din = new DataInputStream(new ByteArrayInputStream(bytes));
|
||||
din.readInt();
|
||||
din.readInt();
|
||||
din.readInt();
|
||||
din.readUTF();
|
||||
int count = din.readShort();
|
||||
List<String> palette = new ArrayList<>(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
palette.add(din.readUTF());
|
||||
}
|
||||
return palette;
|
||||
}
|
||||
|
||||
private static IrisObject representativeObject() {
|
||||
IrisObject object = new IrisObject(64, 64, 64);
|
||||
object.setLoadKey("palette-order");
|
||||
int placed = 0;
|
||||
int distinct = 0;
|
||||
outer:
|
||||
for (int x = 0; x < 64; x++) {
|
||||
for (int y = 0; y < 64; y++) {
|
||||
for (int z = 0; z < 64; z++) {
|
||||
if (placed >= BLOCK_COUNT) {
|
||||
break outer;
|
||||
}
|
||||
String key;
|
||||
if (placed % 7 == 0 && distinct < UNIQUE_KEYS) {
|
||||
key = "iris:unique_" + distinct;
|
||||
distinct++;
|
||||
} else {
|
||||
key = "iris:shared_" + (placed % 11);
|
||||
}
|
||||
object.blocks.put(new IrisBlockVector(x, y, z), new KeyedBlockState(key));
|
||||
placed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
private static String digest(byte[] bytes) {
|
||||
try {
|
||||
return HexFormat.of().formatHex(MessageDigest.getInstance("SHA-256").digest(bytes));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,172 +106,4 @@ public class IrisObjectIoWriteLimitsTest {
|
||||
assertArrayEquals("a rejected write must not truncate the previous object", before,
|
||||
Files.readAllBytes(file.toPath()));
|
||||
}
|
||||
|
||||
private static final class KeyedBlockState implements PlatformBlockState {
|
||||
private final String key;
|
||||
|
||||
private KeyedBlockState(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String key() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String namespace() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String materialKey() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAir() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSolid() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOccluding() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCustom() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deferredPlacementKey() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformBlockState placementBaseState() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFluid() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWater() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWaterLogged() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdatable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFoliage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTreeBlock() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFoliagePlantable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDecorant() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStorage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStorageChest() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOre() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeepSlate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVineBlock() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceOnto(PlatformBlockState onto) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(PlatformBlockState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAirOrFluid() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformBlockState withProperty(String name, String value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object nativeHandle() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return key.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return this == other;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
package art.arcane.iris.engine.object;
|
||||
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
|
||||
final class KeyedBlockState implements PlatformBlockState {
|
||||
private final String key;
|
||||
|
||||
KeyedBlockState(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String key() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String namespace() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String materialKey() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAir() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSolid() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOccluding() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCustom() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deferredPlacementKey() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformBlockState placementBaseState() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFluid() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWater() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWaterLogged() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdatable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFoliage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTreeBlock() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFoliagePlantable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDecorant() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStorage() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStorageChest() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOre() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeepSlate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVineBlock() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceOnto(PlatformBlockState onto) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(PlatformBlockState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAirOrFluid() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformBlockState withProperty(String name, String value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object nativeHandle() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return key.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return this == other;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
@@ -24,12 +24,11 @@ import art.arcane.iris.spi.IrisPlatforms;
|
||||
import art.arcane.iris.spi.PlatformBlockProperty;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import art.arcane.iris.spi.PlatformRegistries;
|
||||
import art.arcane.iris.testsupport.BukkitTestServer;
|
||||
import art.arcane.iris.util.common.data.IrisCustomData;
|
||||
import art.arcane.iris.util.project.matter.slices.PlatformBlockMatter;
|
||||
import io.papermc.paper.registry.RegistryAccess;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Entity;
|
||||
@@ -38,7 +37,6 @@ import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -46,10 +44,8 @@ import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -57,29 +53,12 @@ import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class BukkitSpiConformanceTest {
|
||||
@BeforeClass
|
||||
public static void setup() {
|
||||
Server server = Bukkit.getServer();
|
||||
if (server == null) {
|
||||
server = mock(Server.class);
|
||||
doReturn(Logger.getLogger("IrisTest")).when(server).getLogger();
|
||||
doReturn("IrisTestServer").when(server).getName();
|
||||
doReturn("1.0").when(server).getVersion();
|
||||
doReturn("1.0").when(server).getBukkitVersion();
|
||||
doAnswer((InvocationOnMock invocation) -> blockData("minecraft:" + invocation.getArgument(0, Material.class).name().toLowerCase(Locale.ROOT))).when(server).createBlockData(any(Material.class));
|
||||
try {
|
||||
Bukkit.setServer(server);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
doAnswer((InvocationOnMock invocation) -> blockData(invocation.getArgument(0))).when(server).createBlockData(anyString());
|
||||
BukkitTestServer.install();
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -93,10 +72,7 @@ public class BukkitSpiConformanceTest {
|
||||
}
|
||||
|
||||
private static BlockData blockData(String asString) {
|
||||
BlockData data = mock(BlockData.class);
|
||||
doReturn(asString).when(data).getAsString();
|
||||
doReturn(asString).when(data).getAsString(anyBoolean());
|
||||
return data;
|
||||
return BukkitTestServer.blockData(asString);
|
||||
}
|
||||
|
||||
private static PlatformRegistries registries() {
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package art.arcane.iris.testsupport;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public final class BukkitTestServer {
|
||||
private static final Object LOCK = new Object();
|
||||
private static volatile Server installed;
|
||||
|
||||
private BukkitTestServer() {
|
||||
}
|
||||
|
||||
public static Server install() {
|
||||
Server current = installed;
|
||||
|
||||
if (current != null) {
|
||||
return current;
|
||||
}
|
||||
|
||||
synchronized (LOCK) {
|
||||
if (installed != null) {
|
||||
return installed;
|
||||
}
|
||||
|
||||
Server existing = Bukkit.getServer();
|
||||
|
||||
if (existing != null) {
|
||||
installed = existing;
|
||||
return existing;
|
||||
}
|
||||
|
||||
Server server = mock(Server.class);
|
||||
doReturn(Logger.getLogger("IrisTest")).when(server).getLogger();
|
||||
doReturn(mock(PluginManager.class)).when(server).getPluginManager();
|
||||
doReturn("IrisTestServer").when(server).getName();
|
||||
doReturn("1.0").when(server).getVersion();
|
||||
doReturn("1.0").when(server).getBukkitVersion();
|
||||
doAnswer((InvocationOnMock invocation) -> blockData(invocation.getArgument(0, Material.class).name().toLowerCase(Locale.ROOT)))
|
||||
.when(server).createBlockData(any(Material.class));
|
||||
doAnswer((InvocationOnMock invocation) -> blockData(invocation.getArgument(0, String.class)))
|
||||
.when(server).createBlockData(anyString());
|
||||
|
||||
try {
|
||||
Bukkit.setServer(server);
|
||||
} catch (Throwable e) {
|
||||
if (Bukkit.getServer() != server) {
|
||||
throw new IllegalStateException("The shared Bukkit test server could not be installed", e);
|
||||
}
|
||||
}
|
||||
|
||||
installed = server;
|
||||
return server;
|
||||
}
|
||||
}
|
||||
|
||||
public static void brand(String name, String version) {
|
||||
Server server = install();
|
||||
doReturn(name).when(server).getName();
|
||||
doReturn(version).when(server).getVersion();
|
||||
doReturn(version).when(server).getBukkitVersion();
|
||||
}
|
||||
|
||||
public static BlockData blockData(String key) {
|
||||
String canonical = key.indexOf(':') >= 0 ? key : "minecraft:" + key;
|
||||
BlockData data = mock(BlockData.class);
|
||||
doReturn(canonical).when(data).getAsString();
|
||||
doReturn(canonical).when(data).getAsString(anyBoolean());
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package art.arcane.iris.util.common.data;
|
||||
|
||||
import art.arcane.iris.engine.mantle.EngineMantle;
|
||||
import art.arcane.iris.spi.IrisPlatform;
|
||||
import art.arcane.iris.spi.IrisPlatforms;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import art.arcane.iris.spi.PlatformRegistries;
|
||||
import art.arcane.iris.util.project.hunk.view.ChunkDataHunkHolder;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class PlatformStateRebindTest {
|
||||
private static final List<String> CONVERTED = List.of(
|
||||
"art.arcane.iris.engine.actuator.IrisDimensionStackActuator",
|
||||
"art.arcane.iris.engine.actuator.IrisTerrainNormalActuator",
|
||||
"art.arcane.iris.engine.modifier.IrisPerfectionModifier",
|
||||
"art.arcane.iris.engine.modifier.IrisPostModifier",
|
||||
"art.arcane.iris.engine.object.IrisBiomeLayerGenerator",
|
||||
"art.arcane.iris.engine.platform.studio.generators.BiomeBuffetGenerator",
|
||||
"art.arcane.iris.engine.mantle.EngineMantle",
|
||||
"art.arcane.iris.util.project.hunk.view.ChunkDataHunkHolder");
|
||||
|
||||
@After
|
||||
public void unbindPlatform() {
|
||||
IrisPlatforms.unbind();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chunkDataAirIsResolvedAgainstTheCurrentlyBoundPlatform() {
|
||||
PlatformBlockState first = bindPlatform("first");
|
||||
ChunkGenerator.ChunkData chunk = mock(ChunkGenerator.ChunkData.class);
|
||||
when(chunk.getMinHeight()).thenReturn(-64);
|
||||
when(chunk.getMaxHeight()).thenReturn(320);
|
||||
ChunkDataHunkHolder holder = new ChunkDataHunkHolder(chunk);
|
||||
|
||||
assertSame(first, holder.getRaw(0, -1, 0));
|
||||
|
||||
IrisPlatforms.unbind();
|
||||
PlatformBlockState second = bindPlatform("second");
|
||||
|
||||
assertSame(second, holder.getRaw(0, -1, 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mantleAirIsResolvedAgainstTheCurrentlyBoundPlatform() {
|
||||
PlatformBlockState first = bindPlatform("first");
|
||||
|
||||
assertSame(first, EngineMantle.AIR.get());
|
||||
|
||||
IrisPlatforms.unbind();
|
||||
PlatformBlockState second = bindPlatform("second");
|
||||
|
||||
assertSame(second, EngineMantle.AIR.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aLatchKeepsServingTheLastResolutionWhileNothingIsBound() {
|
||||
PlatformBlockState first = bindPlatform("first");
|
||||
BoundBlockState state = BoundBlockState.of("AIR");
|
||||
|
||||
assertSame(first, state.get());
|
||||
|
||||
IrisPlatforms.unbind();
|
||||
|
||||
assertSame(first, state.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noGenerationClassLatchesABlockStateAtClassInitialisation() throws ClassNotFoundException {
|
||||
List<String> latched = new ArrayList<>();
|
||||
|
||||
for (String name : CONVERTED) {
|
||||
Class<?> owner = Class.forName(name, false, PlatformStateRebindTest.class.getClassLoader());
|
||||
collectLatches(owner, latched);
|
||||
for (Class<?> nested : owner.getDeclaredClasses()) {
|
||||
collectLatches(nested, latched);
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(List.of(), latched);
|
||||
}
|
||||
|
||||
private static void collectLatches(Class<?> type, List<String> latched) {
|
||||
for (Field field : type.getDeclaredFields()) {
|
||||
if (!Modifier.isStatic(field.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
Class<?> fieldType = field.getType();
|
||||
if (PlatformBlockState.class.isAssignableFrom(fieldType)
|
||||
|| (fieldType.isArray() && PlatformBlockState.class.isAssignableFrom(fieldType.getComponentType()))) {
|
||||
latched.add(type.getName() + "." + field.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static PlatformBlockState bindPlatform(String label) {
|
||||
Map<String, PlatformBlockState> states = new HashMap<>();
|
||||
PlatformRegistries registries = mock(PlatformRegistries.class);
|
||||
when(registries.block(anyString())).thenAnswer(invocation -> states.computeIfAbsent(
|
||||
label + ':' + invocation.<String>getArgument(0),
|
||||
key -> {
|
||||
PlatformBlockState state = mock(PlatformBlockState.class);
|
||||
when(state.key()).thenReturn(key);
|
||||
return state;
|
||||
}));
|
||||
IrisPlatform platform = mock(IrisPlatform.class);
|
||||
when(platform.registries()).thenReturn(registries);
|
||||
IrisPlatforms.bind(platform);
|
||||
return registries.block("AIR");
|
||||
}
|
||||
}
|
||||
+2
-28
@@ -3,16 +3,13 @@ package art.arcane.iris.util.project.matter.slices;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import art.arcane.iris.engine.hydrology.cave.HydrologyCaveCell;
|
||||
import art.arcane.iris.engine.hydrology.cave.HydrologyCaveAction;
|
||||
import art.arcane.iris.testsupport.BukkitTestServer;
|
||||
import art.arcane.iris.util.project.matter.IrisMatterSupport;
|
||||
import art.arcane.iris.util.project.matter.PreObjectMatterCell;
|
||||
import art.arcane.volmlib.util.matter.IrisMatter;
|
||||
import art.arcane.volmlib.util.matter.Matter;
|
||||
import art.arcane.volmlib.util.matter.MatterCavern;
|
||||
import art.arcane.volmlib.util.matter.MatterSlice;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -21,8 +18,6 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -30,28 +25,12 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class PreObjectMatterTest {
|
||||
@BeforeClass
|
||||
public static void setUpBukkit() {
|
||||
if (Bukkit.getServer() != null) {
|
||||
return;
|
||||
}
|
||||
Server server = mock(Server.class);
|
||||
doReturn(Logger.getLogger("IrisTest")).when(server).getLogger();
|
||||
doReturn("IrisTestServer").when(server).getName();
|
||||
doReturn("1.0").when(server).getVersion();
|
||||
doReturn("1.0").when(server).getBukkitVersion();
|
||||
doAnswer(invocation -> blockData(invocation.getArgument(0, Material.class).name()
|
||||
.toLowerCase(Locale.ROOT))).when(server).createBlockData(any(Material.class));
|
||||
try {
|
||||
Bukkit.setServer(server);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
BukkitTestServer.install();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -149,9 +128,4 @@ public class PreObjectMatterTest {
|
||||
return new DataInputStream(new ByteArrayInputStream(new byte[]{(byte) flags}));
|
||||
}
|
||||
|
||||
private static BlockData blockData(String key) {
|
||||
BlockData data = mock(BlockData.class);
|
||||
doReturn("minecraft:" + key).when(data).getAsString();
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +1,20 @@
|
||||
package art.arcane.iris.util.project.noise;
|
||||
|
||||
import art.arcane.iris.testsupport.BukkitTestServer;
|
||||
import art.arcane.volmlib.util.function.NoiseInjector;
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class CNGInjectorParityTest {
|
||||
@BeforeClass
|
||||
public static void setupBukkit() {
|
||||
if (Bukkit.getServer() != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Server server = mock(Server.class);
|
||||
doReturn(Logger.getLogger("IrisTest")).when(server).getLogger();
|
||||
doReturn("IrisTestServer").when(server).getName();
|
||||
doReturn("1.0").when(server).getVersion();
|
||||
doReturn("1.0").when(server).getBukkitVersion();
|
||||
doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, Material.class).name().toLowerCase(Locale.ROOT))).when(server).createBlockData(any(Material.class));
|
||||
doAnswer((InvocationOnMock invocation) -> namedBlockData(invocation.getArgument(0, String.class))).when(server).createBlockData(anyString());
|
||||
try {
|
||||
Bukkit.setServer(server);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private static BlockData namedBlockData(String key) {
|
||||
String canonical = key.indexOf(':') >= 0 ? key : "minecraft:" + key;
|
||||
BlockData data = mock(BlockData.class);
|
||||
doReturn(canonical).when(data).getAsString();
|
||||
return data;
|
||||
BukkitTestServer.install();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user