minecraft-source/src/net/minecraft/gametest/framework/GameTestInfo.java

197 lines
6.0 KiB
Java

package net.minecraft.gametest.framework;
import net.minecraft.world.level.block.entity.StructureBlockEntity;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
import com.google.common.collect.Lists;
import javax.annotation.Nullable;
import com.google.common.base.Stopwatch;
import it.unimi.dsi.fastutil.objects.Object2LongMap;
import java.util.Collection;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.core.BlockPos;
public class GameTestInfo {
private final TestFunction testFunction;
private BlockPos testPos;
private final ServerLevel level;
private final Collection<GameTestListener> listeners;
private final int timeoutTicks;
private final Collection<GameTestSequence> sequences;
private Object2LongMap<Runnable> runAtTickTimeMap;
private long startTick;
private long tickCount;
private boolean started;
private final Stopwatch timer;
private boolean done;
@Nullable
private Throwable error;
public GameTestInfo(final TestFunction jk, final ServerLevel xd) {
this.listeners = Lists.newArrayList();
this.sequences = Lists.newCopyOnWriteArrayList();
this.runAtTickTimeMap = (Object2LongMap<Runnable>)new Object2LongOpenHashMap();
this.started = false;
this.timer = Stopwatch.createUnstarted();
this.done = false;
this.testFunction = jk;
this.level = xd;
this.timeoutTicks = jk.getMaxTicks();
}
public GameTestInfo(final TestFunction jk, final BlockPos fk, final ServerLevel xd) {
this(jk, xd);
this.assignPosition(fk);
}
void assignPosition(final BlockPos fk) {
this.testPos = fk;
}
void startExecution() {
this.startTick = this.level.getGameTime() + 1L + this.testFunction.getSetupTicks();
this.timer.start();
}
public void tick() {
if (this.isDone()) {
return;
}
this.tickCount = this.level.getGameTime() - this.startTick;
if (this.tickCount < 0L) {
return;
}
if (this.tickCount == 0L) {
this.startTest();
}
final ObjectIterator<Object2LongMap.Entry<Runnable>> objectIterator2 = (ObjectIterator<Object2LongMap.Entry<Runnable>>)this.runAtTickTimeMap.object2LongEntrySet().iterator();
while (objectIterator2.hasNext()) {
final Object2LongMap.Entry<Runnable> entry3 = (Object2LongMap.Entry<Runnable>)objectIterator2.next();
if (entry3.getLongValue() <= this.tickCount) {
try {
((Runnable)entry3.getKey()).run();
}
catch (Exception exception4) {
this.fail(exception4);
}
objectIterator2.remove();
}
}
if (this.tickCount > this.timeoutTicks) {
if (this.sequences.isEmpty()) {
this.fail(new GameTestTimeoutException("Didn't succeed or fail within " + this.testFunction.getMaxTicks() + " ticks"));
}
else {
this.sequences.forEach(ja -> ja.tickAndFailIfNotComplete(this.tickCount));
if (this.error == null) {
this.fail(new GameTestTimeoutException("No sequences finished"));
}
}
}
else {
this.sequences.forEach(ja -> ja.tickAndContinue(this.tickCount));
}
}
private void startTest() {
if (this.started) {
throw new IllegalStateException("Test already started");
}
this.started = true;
try {
this.testFunction.run(new GameTestHelper(this));
}
catch (Exception exception2) {
this.fail(exception2);
}
}
public String getTestName() {
return this.testFunction.getTestName();
}
public BlockPos getTestPos() {
return this.testPos;
}
@Nullable
public BlockPos getStructureSize() {
final StructureBlockEntity bxi2 = this.getStructureBlockEntity();
if (bxi2 == null) {
return null;
}
return bxi2.getStructureSize();
}
@Nullable
private StructureBlockEntity getStructureBlockEntity() {
return (StructureBlockEntity)this.level.getBlockEntity(this.testPos);
}
public ServerLevel getLevel() {
return this.level;
}
public boolean hasSucceeded() {
return this.done && this.error == null;
}
public boolean hasFailed() {
return this.error != null;
}
public boolean hasStarted() {
return this.started;
}
public boolean isDone() {
return this.done;
}
private void finish() {
if (!this.done) {
this.done = true;
this.timer.stop();
}
}
public void fail(final Throwable throwable) {
this.finish();
this.error = throwable;
this.listeners.forEach(ix -> ix.testFailed(this));
}
@Nullable
public Throwable getError() {
return this.error;
}
@Override
public String toString() {
return this.getTestName();
}
public void addListener(final GameTestListener ix) {
this.listeners.add(ix);
}
public void spawnStructure(final int integer) {
final StructureBlockEntity bxi3 = StructureUtils.spawnStructure(this.testFunction.getStructureName(), this.testPos, integer, this.level, false);
bxi3.setStructureName(this.getTestName());
StructureUtils.addCommandBlockAndButtonToStartTest(this.testPos.offset(1, 0, -1), this.level);
this.listeners.forEach(ix -> ix.testStructureLoaded(this));
}
public boolean isRequired() {
return this.testFunction.isRequired();
}
public boolean isOptional() {
return !this.testFunction.isRequired();
}
public String getStructureName() {
return this.testFunction.getStructureName();
}
}