Files
Construct-CN/packs/BP/scripts/classes/Verifier/StructureVerifier.js
T
wed150 136d5ffa3b
/ build (push) Has been cancelled
Start working at 1.2.0
2026-08-26 09:54:39 +08:00

148 lines
4.2 KiB
JavaScript

import { system } from "@minecraft/server";
import { Vector } from "../../lib/Vector";
import { CellVerifier } from "./CellVerifier";
import { GridBuffers } from "./GridBuffers";
import { PriorityPass } from "./PriorityPass";
import { RefreshRate } from "./RefreshRate";
import { DebugBoxSweepObserver, SilentSweepObserver } from "./SweepObserver";
import { VerificationRun } from "./VerificationRun";
import { VerificationSweep } from "./VerificationSweep";
import { InstanceVerifierSettings, StandaloneVerifierSettings } from "./VerifierSettings";
export class StructureVerifier {
#instance;
#settings;
#buffers = new GridBuffers();
#priorityPass = new PriorityPass();
#run;
#loop;
#isPassPending = false;
static forInstance(instance) {
return new StructureVerifier(instance, new InstanceVerifierSettings(instance));
}
static standalone(instance, options) {
return new StructureVerifier(instance, new StandaloneVerifierSettings(options));
}
constructor(instance, settings) {
this.#instance = instance;
this.#settings = settings;
}
isEnabled() {
return this.#settings.isEnabled();
}
getCompletedGrid() {
return this.#buffers.completed();
}
refresh(isPriority = false) {
this.#stopLoop();
this.#cancelRun();
if (isPriority)
this.#priorityPass.arm();
if (this.#instance.isEnabled())
this.#startLoop();
}
async verifyStructure(shouldRender = false) {
if (!this.isEnabled())
return void 0;
const bounds = this.#instance.getActiveBounds();
const volume = Vector.volume(bounds.min, bounds.max);
if (volume <= 0)
return this.#buffers.completed();
this.#cancelRun();
const run = this.#beginRun(bounds, volume, shouldRender);
this.#finishRun(run, await run.start());
return this.#buffers.completed();
}
patchCell(location) {
const completed = this.#buffers.completed();
if (!completed)
return;
const cell = this.#tryVerifyCell(location);
if (!cell)
return;
completed.setCell(location, cell.verificationLevel, cell.flags);
const filling = this.#buffers.filling()
filling?.setCell(location, cell.verificationLevel, cell.flags);
}
#tryVerifyCell(location) {
try {
return this.#newCellVerifier().verify(location);
} catch {
return void 0;
}
}
#startLoop() {
this.#isPassPending = true;
this.#loop = system.runInterval(() => {
if (this.#isPassPending)
this.verifyStructure();
});
}
#stopLoop() {
if (!this.#loop)
return;
system.clearRun(this.#loop);
this.#loop = void 0;
}
#beginRun(bounds, volume, shouldRender) {
this.#isPassPending = false;
this.#run = new VerificationRun(
this.#newSweep(bounds, shouldRender),
this.#blocksPerTick(volume)
);
return this.#run;
}
#blocksPerTick(volume) {
if (this.#priorityPass.isArmed())
return RefreshRate.priorityBlocksPerTick();
return this.#settings.blocksPerTick(volume);
}
#finishRun(run, didComplete) {
if (this.#run === run)
this.#run = void 0;
if (!didComplete)
return;
this.#priorityPass.disarm();
this.#buffers.commit();
this.#isPassPending = true;
}
#cancelRun() {
this.#run?.cancel();
}
#newSweep(bounds, shouldRender) {
return new VerificationSweep({
bounds,
grid: this.#buffers.beginPass(bounds),
origin: this.#instance.toGlobalCoords({ x: 0, y: 0, z: 0 }),
cellVerifier: this.#newCellVerifier(),
observer: this.#newObserver(shouldRender)
});
}
#newCellVerifier() {
return new CellVerifier(this.#instance, this.#settings.showsBlockPreview());
}
#newObserver(shouldRender) {
if (!shouldRender)
return new SilentSweepObserver();
return new DebugBoxSweepObserver(this.#instance, this.#settings.particleLifetimeSeconds());
}
}