GameTestInfo.java
net.minecraft.gametest.framework.GameTestInfo
信息
- 全限定名:net.minecraft.gametest.framework.GameTestInfo
- 类型:public class
- 包:net.minecraft.gametest.framework
- 源码路径:src/main/java/net/minecraft/gametest/framework/GameTestInfo.java
- 起始行号:L31
- 职责:
TODO
字段/常量
-
test- 类型:
Holder.Reference<GameTestInstance> - 修饰符:
private final - 源码定位:
L32 - 说明:
TODO
- 类型:
-
testBlockPos- 类型:
BlockPos - 修饰符:
private - 源码定位:
L33 - 说明:
TODO
- 类型:
-
level- 类型:
ServerLevel - 修饰符:
private final - 源码定位:
L34 - 说明:
TODO
- 类型:
-
listeners- 类型:
Collection<GameTestListener> - 修饰符:
private final - 源码定位:
L35 - 说明:
TODO
- 类型:
-
timeoutTicks- 类型:
int - 修饰符:
private final - 源码定位:
L36 - 说明:
TODO
- 类型:
-
sequences- 类型:
Collection<GameTestSequence> - 修饰符:
private final - 源码定位:
L37 - 说明:
TODO
- 类型:
-
runAtTickTimeMap- 类型:
Object2LongMap<Runnable> - 修饰符:
private final - 源码定位:
L38 - 说明:
TODO
- 类型:
-
placedStructure- 类型:
boolean - 修饰符:
private - 源码定位:
L39 - 说明:
TODO
- 类型:
-
chunksLoaded- 类型:
boolean - 修饰符:
private - 源码定位:
L40 - 说明:
TODO
- 类型:
-
tickCount- 类型:
int - 修饰符:
private - 源码定位:
L41 - 说明:
TODO
- 类型:
-
started- 类型:
boolean - 修饰符:
private - 源码定位:
L42 - 说明:
TODO
- 类型:
-
retryOptions- 类型:
RetryOptions - 修饰符:
private final - 源码定位:
L43 - 说明:
TODO
- 类型:
-
timer- 类型:
Stopwatch - 修饰符:
private final - 源码定位:
L44 - 说明:
TODO
- 类型:
-
done- 类型:
boolean - 修饰符:
private - 源码定位:
L45 - 说明:
TODO
- 类型:
-
extraRotation- 类型:
Rotation - 修饰符:
private final - 源码定位:
L46 - 说明:
TODO
- 类型:
-
error- 类型:
GameTestException - 修饰符:
private - 源码定位:
L47 - 说明:
TODO
- 类型:
-
testInstanceBlockEntity- 类型:
TestInstanceBlockEntity - 修饰符:
private - 源码定位:
L48 - 说明:
TODO
- 类型:
内部类/嵌套类型
- 无
构造器
public GameTestInfo(Holder.Reference<GameTestInstance> test, Rotation extraRotation, ServerLevel level, RetryOptions retryOptions) @ L50
- 构造器名:GameTestInfo
- 源码定位:L50
- 修饰符:public
参数:
- test: Holder.Reference
- extraRotation: Rotation
- level: ServerLevel
- retryOptions: RetryOptions
说明:
TODO
方法
下面的方法块按源码顺序生成。
public void setTestBlockPos(BlockPos testBlockPos) @ L58
- 方法名:setTestBlockPos
- 源码定位:L58
- 返回类型:void
- 修饰符:public
参数:
- testBlockPos: BlockPos
说明:
TODO
public GameTestInfo startExecution(int tickDelay) @ L62
- 方法名:startExecution
- 源码定位:L62
- 返回类型:GameTestInfo
- 修饰符:public
参数:
- tickDelay: int
说明:
TODO
public void placeStructure() @ L67
- 方法名:placeStructure
- 源码定位:L67
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void tick(GameTestRunner runner) @ L83
- 方法名:tick
- 源码定位:L83
- 返回类型:void
- 修饰符:public
参数:
- runner: GameTestRunner
说明:
TODO
private void tickInternal() @ L115
- 方法名:tickInternal
- 源码定位:L115
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private void startTest() @ L156
- 方法名:startTest
- 源码定位:L156
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
public void setRunAtTickTime(long time, Runnable assertAtTickTime) @ L172
- 方法名:setRunAtTickTime
- 源码定位:L172
- 返回类型:void
- 修饰符:public
参数:
- time: long
- assertAtTickTime: Runnable
说明:
TODO
public Identifier id() @ L176
- 方法名:id
- 源码定位:L176
- 返回类型:Identifier
- 修饰符:public
参数:
- 无
说明:
TODO
public BlockPos getTestBlockPos() @ L180
- 方法名:getTestBlockPos
- 源码定位:L180
- 返回类型:BlockPos
- 修饰符:public
参数:
- 无
说明:
TODO
public BlockPos getTestOrigin() @ L184
- 方法名:getTestOrigin
- 源码定位:L184
- 返回类型:BlockPos
- 修饰符:public
参数:
- 无
说明:
TODO
public AABB getStructureBounds() @ L188
- 方法名:getStructureBounds
- 源码定位:L188
- 返回类型:AABB
- 修饰符:public
参数:
- 无
说明:
TODO
public TestInstanceBlockEntity getTestInstanceBlockEntity() @ L193
- 方法名:getTestInstanceBlockEntity
- 源码定位:L193
- 返回类型:TestInstanceBlockEntity
- 修饰符:public
参数:
- 无
说明:
TODO
public ServerLevel getLevel() @ L211
- 方法名:getLevel
- 源码定位:L211
- 返回类型:ServerLevel
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean hasSucceeded() @ L215
- 方法名:hasSucceeded
- 源码定位:L215
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean hasFailed() @ L219
- 方法名:hasFailed
- 源码定位:L219
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean hasStarted() @ L223
- 方法名:hasStarted
- 源码定位:L223
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isDone() @ L227
- 方法名:isDone
- 源码定位:L227
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public long getRunTime() @ L231
- 方法名:getRunTime
- 源码定位:L231
- 返回类型:long
- 修饰符:public
参数:
- 无
说明:
TODO
private void finish() @ L235
- 方法名:finish
- 源码定位:L235
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
public void succeed() @ L244
- 方法名:succeed
- 源码定位:L244
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void fail(Component message) @ L253
- 方法名:fail
- 源码定位:L253
- 返回类型:void
- 修饰符:public
参数:
- message: Component
说明:
TODO
public void fail(GameTestException error) @ L257
- 方法名:fail
- 源码定位:L257
- 返回类型:void
- 修饰符:public
参数:
- error: GameTestException
说明:
TODO
public GameTestException getError() @ L261
- 方法名:getError
- 源码定位:L261
- 返回类型:GameTestException
- 修饰符:public
参数:
- 无
说明:
TODO
public String toString() @ L265
- 方法名:toString
- 源码定位:L265
- 返回类型:String
- 修饰符:public
参数:
- 无
说明:
TODO
public void addListener(GameTestListener listener) @ L270
- 方法名:addListener
- 源码定位:L270
- 返回类型:void
- 修饰符:public
参数:
- listener: GameTestListener
说明:
TODO
public GameTestInfo prepareTestStructure() @ L274
- 方法名:prepareTestStructure
- 源码定位:L274
- 返回类型:GameTestInfo
- 修饰符:public
参数:
- 无
说明:
TODO
private TestInstanceBlockEntity createTestInstanceBlock(BlockPos testPos, Rotation rotation, ServerLevel level) @ L285
- 方法名:createTestInstanceBlock
- 源码定位:L285
- 返回类型:TestInstanceBlockEntity
- 修饰符:private
参数:
- testPos: BlockPos
- rotation: Rotation
- level: ServerLevel
说明:
TODO
int getTick() @ L299
- 方法名:getTick
- 源码定位:L299
- 返回类型:int
- 修饰符:package-private
参数:
- 无
说明:
TODO
GameTestSequence createSequence() @ L303
- 方法名:createSequence
- 源码定位:L303
- 返回类型:GameTestSequence
- 修饰符:package-private
参数:
- 无
说明:
TODO
public boolean isRequired() @ L309
- 方法名:isRequired
- 源码定位:L309
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isOptional() @ L313
- 方法名:isOptional
- 源码定位:L313
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public Identifier getStructure() @ L317
- 方法名:getStructure
- 源码定位:L317
- 返回类型:Identifier
- 修饰符:public
参数:
- 无
说明:
TODO
public Rotation getRotation() @ L321
- 方法名:getRotation
- 源码定位:L321
- 返回类型:Rotation
- 修饰符:public
参数:
- 无
说明:
TODO
public GameTestInstance getTest() @ L325
- 方法名:getTest
- 源码定位:L325
- 返回类型:GameTestInstance
- 修饰符:public
参数:
- 无
说明:
TODO
public Holder.Reference<GameTestInstance> getTestHolder() @ L329
- 方法名:getTestHolder
- 源码定位:L329
- 返回类型:Holder.Reference
- 修饰符:public
参数:
- 无
说明:
TODO
public int getTimeoutTicks() @ L333
- 方法名:getTimeoutTicks
- 源码定位:L333
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public boolean isFlaky() @ L337
- 方法名:isFlaky
- 源码定位:L337
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public int maxAttempts() @ L341
- 方法名:maxAttempts
- 源码定位:L341
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public int requiredSuccesses() @ L345
- 方法名:requiredSuccesses
- 源码定位:L345
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public RetryOptions retryOptions() @ L349
- 方法名:retryOptions
- 源码定位:L349
- 返回类型:RetryOptions
- 修饰符:public
参数:
- 无
说明:
TODO
public Stream<GameTestListener> getListeners() @ L353
- 方法名:getListeners
- 源码定位:L353
- 返回类型:Stream
- 修饰符:public
参数:
- 无
说明:
TODO
public GameTestInfo copyReset() @ L357
- 方法名:copyReset
- 源码定位:L357
- 返回类型:GameTestInfo
- 修饰符:public
参数:
- 无
说明:
TODO
代码
public class GameTestInfo {
private final Holder.Reference<GameTestInstance> test;
private @Nullable BlockPos testBlockPos;
private final ServerLevel level;
private final Collection<GameTestListener> listeners = Lists.newArrayList();
private final int timeoutTicks;
private final Collection<GameTestSequence> sequences = Lists.newCopyOnWriteArrayList();
private final Object2LongMap<Runnable> runAtTickTimeMap = new Object2LongOpenHashMap<>();
private boolean placedStructure;
private boolean chunksLoaded;
private int tickCount;
private boolean started;
private final RetryOptions retryOptions;
private final Stopwatch timer = Stopwatch.createUnstarted();
private boolean done;
private final Rotation extraRotation;
private @Nullable GameTestException error;
private @Nullable TestInstanceBlockEntity testInstanceBlockEntity;
public GameTestInfo(Holder.Reference<GameTestInstance> test, Rotation extraRotation, ServerLevel level, RetryOptions retryOptions) {
this.test = test;
this.level = level;
this.retryOptions = retryOptions;
this.timeoutTicks = test.value().maxTicks();
this.extraRotation = extraRotation;
}
public void setTestBlockPos(@Nullable BlockPos testBlockPos) {
this.testBlockPos = testBlockPos;
}
public GameTestInfo startExecution(int tickDelay) {
this.tickCount = -(this.test.value().setupTicks() + tickDelay + 1);
return this;
}
public void placeStructure() {
if (!this.placedStructure) {
TestInstanceBlockEntity test = this.getTestInstanceBlockEntity();
if (!test.placeStructure()) {
this.fail(Component.translatable("test.error.structure.failure", test.getTestName().getString()));
}
this.placedStructure = true;
test.encaseStructure();
BoundingBox boundingBox = test.getTestBoundingBox();
this.level.getBlockTicks().clearArea(boundingBox);
this.level.clearBlockEvents(boundingBox);
this.listeners.forEach(listener -> listener.testStructureLoaded(this));
}
}
public void tick(GameTestRunner runner) {
if (!this.isDone()) {
if (!this.placedStructure) {
this.fail(Component.translatable("test.error.ticking_without_structure"));
}
if (this.testInstanceBlockEntity == null) {
this.fail(Component.translatable("test.error.missing_block_entity"));
}
if (this.error != null) {
this.finish();
} else {
if (!this.chunksLoaded
&& !this.testInstanceBlockEntity.getStructureBoundingBox().intersectingChunks().allMatch(this.level::areEntitiesActuallyLoadedAndTicking)) {
return;
}
this.chunksLoaded = true;
}
this.tickInternal();
if (this.isDone()) {
if (this.error != null) {
this.listeners.forEach(listener -> listener.testFailed(this, runner));
} else {
this.listeners.forEach(listener -> listener.testPassed(this, runner));
}
}
}
}
private void tickInternal() {
this.tickCount++;
if (this.tickCount >= 0) {
if (!this.started) {
this.startTest();
}
ObjectIterator<Entry<Runnable>> it = this.runAtTickTimeMap.object2LongEntrySet().iterator();
while (it.hasNext()) {
Entry<Runnable> entry = it.next();
if (entry.getLongValue() <= this.tickCount) {
try {
entry.getKey().run();
} catch (GameTestException var4) {
this.fail(var4);
} catch (Exception var5) {
this.fail(new UnknownGameTestException(var5));
}
it.remove();
}
}
if (this.tickCount > this.timeoutTicks) {
if (this.sequences.isEmpty()) {
this.fail(new GameTestTimeoutException(Component.translatable("test.error.timeout.no_result", this.test.value().maxTicks())));
} else {
this.sequences.forEach(ticker -> ticker.tickAndFailIfNotComplete(this.tickCount));
if (this.error == null) {
this.fail(
new GameTestTimeoutException(Component.translatable("test.error.timeout.no_sequences_finished", this.test.value().maxTicks()))
);
}
}
} else {
this.sequences.forEach(ticker -> ticker.tickAndContinue(this.tickCount));
}
}
}
private void startTest() {
if (!this.started) {
this.started = true;
this.timer.start();
this.getTestInstanceBlockEntity().setRunning();
try {
this.test.value().run(new GameTestHelper(this));
} catch (GameTestException var2) {
this.fail(var2);
} catch (Exception var3) {
this.fail(new UnknownGameTestException(var3));
}
}
}
public void setRunAtTickTime(long time, Runnable assertAtTickTime) {
this.runAtTickTimeMap.put(assertAtTickTime, time);
}
public Identifier id() {
return this.test.key().identifier();
}
public @Nullable BlockPos getTestBlockPos() {
return this.testBlockPos;
}
public BlockPos getTestOrigin() {
return this.testInstanceBlockEntity.getStartCorner();
}
public AABB getStructureBounds() {
TestInstanceBlockEntity blockEntity = this.getTestInstanceBlockEntity();
return blockEntity.getStructureBounds();
}
public TestInstanceBlockEntity getTestInstanceBlockEntity() {
if (this.testInstanceBlockEntity == null) {
if (this.testBlockPos == null) {
throw new IllegalStateException("This GameTestInfo has no position");
}
if (this.level.getBlockEntity(this.testBlockPos) instanceof TestInstanceBlockEntity blockEntity) {
this.testInstanceBlockEntity = blockEntity;
}
if (this.testInstanceBlockEntity == null) {
throw new IllegalStateException("Could not find a test instance block entity at the given coordinate " + this.testBlockPos);
}
}
return this.testInstanceBlockEntity;
}
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;
}
public long getRunTime() {
return this.timer.elapsed(TimeUnit.MILLISECONDS);
}
private void finish() {
if (!this.done) {
this.done = true;
if (this.timer.isRunning()) {
this.timer.stop();
}
}
}
public void succeed() {
if (this.error == null) {
this.finish();
AABB bounds = this.getStructureBounds();
List<Entity> entities = this.getLevel().getEntitiesOfClass(Entity.class, bounds.inflate(1.0), mob -> !(mob instanceof Player));
entities.forEach(e -> e.remove(Entity.RemovalReason.DISCARDED));
}
}
public void fail(Component message) {
this.fail(new GameTestAssertException(message, this.tickCount));
}
public void fail(GameTestException error) {
this.error = error;
}
public @Nullable GameTestException getError() {
return this.error;
}
@Override
public String toString() {
return this.id().toString();
}
public void addListener(GameTestListener listener) {
this.listeners.add(listener);
}
public @Nullable GameTestInfo prepareTestStructure() {
TestInstanceBlockEntity testInstanceBlock = this.createTestInstanceBlock(Objects.requireNonNull(this.testBlockPos), this.extraRotation, this.level);
if (testInstanceBlock != null) {
this.testInstanceBlockEntity = testInstanceBlock;
this.placeStructure();
return this;
} else {
return null;
}
}
private @Nullable TestInstanceBlockEntity createTestInstanceBlock(BlockPos testPos, Rotation rotation, ServerLevel level) {
level.setBlockAndUpdate(testPos, Blocks.TEST_INSTANCE_BLOCK.defaultBlockState());
if (level.getBlockEntity(testPos) instanceof TestInstanceBlockEntity blockEntity) {
ResourceKey<GameTestInstance> test = this.getTestHolder().key();
Vec3i size = TestInstanceBlockEntity.getStructureSize(level, test).orElse(new Vec3i(1, 1, 1));
blockEntity.set(
new TestInstanceBlockEntity.Data(Optional.of(test), size, rotation, false, TestInstanceBlockEntity.Status.CLEARED, Optional.empty())
);
return blockEntity;
} else {
return null;
}
}
int getTick() {
return this.tickCount;
}
GameTestSequence createSequence() {
GameTestSequence sequence = new GameTestSequence(this);
this.sequences.add(sequence);
return sequence;
}
public boolean isRequired() {
return this.test.value().required();
}
public boolean isOptional() {
return !this.test.value().required();
}
public Identifier getStructure() {
return this.test.value().structure();
}
public Rotation getRotation() {
return this.test.value().info().rotation().getRotated(this.extraRotation);
}
public GameTestInstance getTest() {
return this.test.value();
}
public Holder.Reference<GameTestInstance> getTestHolder() {
return this.test;
}
public int getTimeoutTicks() {
return this.timeoutTicks;
}
public boolean isFlaky() {
return this.test.value().maxAttempts() > 1;
}
public int maxAttempts() {
return this.test.value().maxAttempts();
}
public int requiredSuccesses() {
return this.test.value().requiredSuccesses();
}
public RetryOptions retryOptions() {
return this.retryOptions;
}
public Stream<GameTestListener> getListeners() {
return this.listeners.stream();
}
public GameTestInfo copyReset() {
GameTestInfo i = new GameTestInfo(this.test, this.extraRotation, this.level, this.retryOptions());
if (this.testBlockPos != null) {
i.setTestBlockPos(this.testBlockPos);
}
return i;
}
}引用的其他类
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
Vec3i()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
GameTestAssertException()
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
GameTestHelper()
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
GameTestSequence()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
GameTestTimeoutException()
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
UnknownGameTestException()
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
Component.translatable()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Stopwatch.createUnstarted()
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
字段/方法调用/构造调用/返回值 - 关联成员:
Data(), TestInstanceBlockEntity.Data(), TestInstanceBlockEntity.getStructureSize()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置: