@hastearcade/snowglobe
Version:
A TypeScript port of CrystalOrb, a high-level Rust game networking library
79 lines • 3.01 kB
JavaScript
import { CommandBuffer } from './command.js';
import * as Timestamp from './timestamp.js';
export var InitializationType;
(function (InitializationType) {
InitializationType[InitializationType["PreInitialized"] = 0] = "PreInitialized";
InitializationType[InitializationType["NeedsInitialization"] = 1] = "NeedsInitialization";
})(InitializationType || (InitializationType = {}));
export class Simulation {
world;
commandBuffer = new CommandBuffer();
hasInitialized;
constructor(world, initializationType) {
this.world = world;
this.hasInitialized = initializationType === InitializationType.PreInitialized;
}
step(endingTimestamp = this.simulatingTimestamp()) {
const startTime = Date.now();
const commands = this.commandBuffer.drainUpTo(endingTimestamp);
for (const command of commands) {
this.world.applyCommand(command);
}
this.world.step();
this.commandBuffer.updateTimestamp(Timestamp.add(this.lastCompletedTimestamp(), 1));
const endTime = Date.now();
if (endTime - startTime > 15) {
console.log(`\n\nsimulation step took ${endTime - startTime}`);
}
}
getWorld() {
return this.world;
}
simulatingTimestamp() {
return Timestamp.add(this.lastCompletedTimestamp(), 1);
}
scheduleCommand(command) {
this.commandBuffer.insert(command);
}
tryCompletingSimulationsUpTo(targetCompletedTimestamp, maxSteps) {
for (let i = 0; i < maxSteps; i++) {
if (Timestamp.cmp(this.lastCompletedTimestamp(), targetCompletedTimestamp) > -1) {
break;
}
this.step();
}
}
applyCompletedSnapshot(completedSnapshot, rewoundCommandBuffer) {
this.world.applySnapshot(Timestamp.set(completedSnapshot, completedSnapshot.timestamp));
this.commandBuffer = rewoundCommandBuffer;
this.commandBuffer.updateTimestamp(Timestamp.get(completedSnapshot));
this.hasInitialized = true;
}
lastCompletedSnapshot() {
return Timestamp.set(this.world.snapshot(), this.lastCompletedTimestamp());
}
lastCompletedTimestamp() {
return this.commandBuffer.timestamp();
}
resetLastCompletedTimestamp(timestamp) {
const oldTimestamp = this.lastCompletedTimestamp();
this.commandBuffer.updateTimestamp(timestamp);
if (Timestamp.cmp(timestamp, oldTimestamp) === -1) {
const commands = this.commandBuffer.drainAll();
for (const command of commands) {
this.world.applyCommand(command);
}
}
}
displayState() {
if (this.hasInitialized) {
return Timestamp.set(this.world.displayState(), this.lastCompletedTimestamp());
}
return undefined;
}
bufferedCommands() {
return this.commandBuffer[Symbol.iterator]();
}
postUpdate() { }
}
//# sourceMappingURL=simulation.js.map