197 lines
6.0 KiB
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();
|
|
}
|
|
}
|