Spaces:
Build error
Build error
File size: 5,164 Bytes
d46f4a3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
package net.minecraft.commands.execution;
import com.google.common.collect.Queues;
import com.mojang.brigadier.context.ContextChain;
import com.mojang.logging.LogUtils;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.Deque;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.commands.CommandResultCallback;
import net.minecraft.commands.ExecutionCommandSource;
import net.minecraft.commands.execution.tasks.BuildContexts;
import net.minecraft.commands.execution.tasks.CallFunction;
import net.minecraft.commands.functions.InstantiatedFunction;
import net.minecraft.util.profiling.ProfilerFiller;
import org.slf4j.Logger;
public class ExecutionContext<T> implements AutoCloseable {
private static final int MAX_QUEUE_DEPTH = 10000000;
private static final Logger LOGGER = LogUtils.getLogger();
private final int commandLimit;
private final int forkLimit;
private final ProfilerFiller profiler;
@Nullable
private TraceCallbacks tracer;
private int commandQuota;
private boolean queueOverflow;
private final Deque<CommandQueueEntry<T>> commandQueue = Queues.newArrayDeque();
private final List<CommandQueueEntry<T>> newTopCommands = new ObjectArrayList<>();
private int currentFrameDepth;
public ExecutionContext(int p_313193_, int p_311309_, ProfilerFiller p_309602_) {
this.commandLimit = p_313193_;
this.forkLimit = p_311309_;
this.profiler = p_309602_;
this.commandQuota = p_313193_;
}
private static <T extends ExecutionCommandSource<T>> Frame createTopFrame(ExecutionContext<T> p_310887_, CommandResultCallback p_311060_) {
if (p_310887_.currentFrameDepth == 0) {
return new Frame(0, p_311060_, p_310887_.commandQueue::clear);
} else {
int i = p_310887_.currentFrameDepth + 1;
return new Frame(i, p_311060_, p_310887_.frameControlForDepth(i));
}
}
public static <T extends ExecutionCommandSource<T>> void queueInitialFunctionCall(
ExecutionContext<T> p_311344_, InstantiatedFunction<T> p_309533_, T p_310187_, CommandResultCallback p_310874_
) {
p_311344_.queueNext(
new CommandQueueEntry<>(createTopFrame(p_311344_, p_310874_), new CallFunction<>(p_309533_, p_310187_.callback(), false).bind(p_310187_))
);
}
public static <T extends ExecutionCommandSource<T>> void queueInitialCommandExecution(
ExecutionContext<T> p_311278_, String p_310967_, ContextChain<T> p_311656_, T p_312145_, CommandResultCallback p_309674_
) {
p_311278_.queueNext(new CommandQueueEntry<>(createTopFrame(p_311278_, p_309674_), new BuildContexts.TopLevel<>(p_310967_, p_311656_, p_312145_)));
}
private void handleQueueOverflow() {
this.queueOverflow = true;
this.newTopCommands.clear();
this.commandQueue.clear();
}
public void queueNext(CommandQueueEntry<T> p_311113_) {
if (this.newTopCommands.size() + this.commandQueue.size() > 10000000) {
this.handleQueueOverflow();
}
if (!this.queueOverflow) {
this.newTopCommands.add(p_311113_);
}
}
public void discardAtDepthOrHigher(int p_313117_) {
while (!this.commandQueue.isEmpty() && this.commandQueue.peek().frame().depth() >= p_313117_) {
this.commandQueue.removeFirst();
}
}
public Frame.FrameControl frameControlForDepth(int p_311323_) {
return () -> this.discardAtDepthOrHigher(p_311323_);
}
public void runCommandQueue() {
this.pushNewCommands();
while (true) {
if (this.commandQuota <= 0) {
LOGGER.info("Command execution stopped due to limit (executed {} commands)", this.commandLimit);
break;
}
CommandQueueEntry<T> commandqueueentry = this.commandQueue.pollFirst();
if (commandqueueentry == null) {
return;
}
this.currentFrameDepth = commandqueueentry.frame().depth();
commandqueueentry.execute(this);
if (this.queueOverflow) {
LOGGER.error("Command execution stopped due to command queue overflow (max {})", 10000000);
break;
}
this.pushNewCommands();
}
this.currentFrameDepth = 0;
}
private void pushNewCommands() {
for (int i = this.newTopCommands.size() - 1; i >= 0; i--) {
this.commandQueue.addFirst(this.newTopCommands.get(i));
}
this.newTopCommands.clear();
}
public void tracer(@Nullable TraceCallbacks p_309595_) {
this.tracer = p_309595_;
}
@Nullable
public TraceCallbacks tracer() {
return this.tracer;
}
public ProfilerFiller profiler() {
return this.profiler;
}
public int forkLimit() {
return this.forkLimit;
}
public void incrementCost() {
this.commandQuota--;
}
@Override
public void close() {
if (this.tracer != null) {
this.tracer.close();
}
}
} |