debug overhaul, fixes stringifying over-recursion

This commit is contained in:
Emmaline Autumn 2025-02-15 18:33:19 -07:00
parent ffa2ef97e0
commit 8bd2c30108
5 changed files with 101 additions and 48 deletions

View File

@ -1,4 +1,6 @@
import { TrackSegment } from "../track/system.ts";
import { Train, TrainCar } from "../train/train.ts";
import { InputManager } from "./input.ts";
type ContextStore = Record<string, any>;
@ -85,33 +87,59 @@ if (debug) {
function safeStringify(obj: any) {
const seen = new WeakSet();
return JSON.stringify(obj, (key, value) => {
if (value instanceof Map) {
const val: Record<string, unknown> = {};
for (const [k, v] of value) {
if (typeof k !== "string") continue;
val[k] = v;
}
return val;
}
if (value instanceof Set) {
return Array.from(value);
}
if (value instanceof TrackSegment) {
return {
...value,
frontNeighbours: value.frontNeighbours.map((n) => n.id),
backNeighbours: value.backNeighbours.map((n) => n.id),
};
}
if (typeof value === "object" && value !== null) {
if (seen.has(value)) {
return "[Circular]"; // Replace circular references
}
seen.add(value);
}
if (value instanceof Map) {
const val: Record<string, unknown> = {};
for (const [k, v] of value) {
if (typeof k !== "string") continue;
val[k] = v;
}
seen.add(value);
return val;
}
if (value instanceof Set) {
seen.add(value);
value = Array.from(value);
return value;
}
if (value instanceof TrackSegment) {
seen.add(value);
const val = { ...value };
(val as any).frontNeighbours = value.frontNeighbours.map((n) => n.id);
(val as any).backNeighbours = value.backNeighbours.map((n) => n.id);
return val;
}
// if (value instanceof Train) {
// const val = { ...value };
// // val.segments = value.segments.map((s) => s.id);
// delete (val as any).path;
// delete (val as any).nodes;
// delete (val as any).cars;
// delete (val as any).t;
// // val.t
// // val.
// return null;
// }
// if (value instanceof InputManager) {
// return {};
// }
// if (value instanceof TrainCar) {
// const val = { ...value };
// return val;
// }
return value;
}, 2);
}

View File

@ -24,7 +24,7 @@ const doodler = new ZoomableDoodler({
(doodler as any as { ctx: CanvasRenderingContext2D }).ctx
.imageSmoothingEnabled = false;
// doodler.minScale = 0.1;
// (doodler as any).scale = doodler.maxScale;
(doodler as any).scale = 3.14;
const colors = [
"red",
@ -41,7 +41,11 @@ setDefaultContext({
inputManager,
doodler,
resources,
debug: false,
debug: {
track: false,
train: false,
path: false,
},
colors,
});

View File

@ -4,33 +4,37 @@ import { getContextItem, setDefaultContext } from "../lib/context.ts";
import { clamp } from "../math/clamp.ts";
export class TrackSystem {
private segments: Map<string, TrackSegment> = new Map();
private _segments: Map<string, TrackSegment> = new Map();
private doodler: Doodler;
constructor(segments: TrackSegment[]) {
this.doodler = getContextItem<Doodler>("doodler");
for (const segment of segments) {
this.segments.set(segment.id, segment);
this._segments.set(segment.id, segment);
}
}
getSegment(id: string) {
return this._segments.get(id);
}
get firstSegment() {
return this.segments.values().next().value;
return this._segments.values().next().value;
}
get lastSegment() {
return this.segments.values().toArray().pop();
return this._segments.values().toArray().pop();
}
optimize(percent: number) {
console.log("Optimizing track", percent * 100 / 4);
for (const segment of this.segments.values()) {
for (const segment of this._segments.values()) {
segment.recalculateRailPoints(Math.round(percent * 100 / 4));
}
}
recalculateAll() {
for (const segment of this.segments.values()) {
for (const segment of this._segments.values()) {
segment.recalculateRailPoints();
segment.length = segment.calculateApproxLength();
}
@ -38,11 +42,11 @@ export class TrackSystem {
registerSegment(segment: TrackSegment) {
segment.setTrack(this);
this.segments.set(segment.id, segment);
this._segments.set(segment.id, segment);
}
unregisterSegment(segment: TrackSegment) {
this.segments.delete(segment.id);
for (const s of this.segments.values()) {
this._segments.delete(segment.id);
for (const s of this._segments.values()) {
s.backNeighbours = s.backNeighbours.filter((n) => n !== segment);
s.frontNeighbours = s.frontNeighbours.filter((n) => n !== segment);
}
@ -52,7 +56,7 @@ export class TrackSystem {
}
draw(showControls = false) {
for (const [i, segment] of this.segments.entries()) {
for (const [i, segment] of this._segments.entries()) {
segment.draw(showControls);
}
@ -85,7 +89,7 @@ export class TrackSystem {
endArray: End[] = [];
findEnds() {
for (const segment of this.segments.values()) {
for (const segment of this._segments.values()) {
if (this.ends.has(segment)) continue;
const ends: [End, End] = [
{
@ -109,14 +113,14 @@ export class TrackSystem {
serialize() {
return JSON.stringify(
this.segments.values().map((s) => s.serialize()).toArray(),
this._segments.values().map((s) => s.serialize()).toArray(),
);
}
copy() {
const track = new TrackSystem([]);
for (const segment of this.segments.values()) {
track.segments.set(segment.id, segment.copy());
for (const segment of this._segments.values()) {
track._segments.set(segment.id, segment.copy());
}
return track;
}
@ -127,19 +131,19 @@ export class TrackSystem {
const neighborMap = new Map<string, [string[], string[]]>();
for (const segment of data) {
track.segments.set(segment.id, TrackSegment.deserialize(segment));
track._segments.set(segment.id, TrackSegment.deserialize(segment));
neighborMap.set(segment.id, [segment.fNeighbors, segment.bNeighbors]);
}
for (const segment of track.segments.values()) {
for (const segment of track._segments.values()) {
segment.setTrack(track);
const neighbors = neighborMap.get(segment.id);
if (neighbors) {
segment.backNeighbours = neighbors[1].map((id) =>
track.segments.get(id)
track._segments.get(id)
).filter((s) => s) as TrackSegment[];
segment.frontNeighbours = neighbors[0].map((id) =>
track.segments.get(id)
track._segments.get(id)
).filter((s) => s) as TrackSegment[];
}
}
@ -148,7 +152,7 @@ export class TrackSystem {
}
translate(v: Vector) {
for (const segment of this.segments.values()) {
for (const segment of this._segments.values()) {
segment.translate(v);
}
}

View File

@ -3,7 +3,7 @@ import { Follower } from "../physics/follower.ts";
import { Mover } from "../physics/mover.ts";
import { getContext, getContextItem } from "../lib/context.ts";
import { Doodler, Vector } from "@bearmetal/doodler";
import { Spline, TrackSegment } from "../track/system.ts";
import { Spline, TrackSegment, TrackSystem } from "../track/system.ts";
import { ResourceManager } from "../lib/resources.ts";
import { map } from "../math/lerp.ts";
@ -107,9 +107,9 @@ export class Train {
// }
draw() {
const ctx = getContext();
if (ctx.debug) {
const doodler = getContextItem<Doodler>("doodler");
const debug = getContextItem<Debug>("debug");
const doodler = getContextItem<Doodler>("doodler");
if (debug.path) {
// doodler.drawLine(this.path.points, {
// color: "red",
// weight: 3,
@ -124,6 +124,16 @@ export class Train {
doodler.drawCircle(p.p, 2, { color, weight: .5 });
}
}
if (debug.train) {
const track = getContextItem<TrackSystem>("track");
for (const segmentId of this.segments) {
const segment = track.getSegment(segmentId);
segment &&
doodler.drawBezier(...segment.points, { color: "red", weight: 3 });
}
}
for (const car of this.cars) {
car.draw();
}
@ -185,8 +195,8 @@ export class TrainCar {
);
});
const ctx = getContext();
if (ctx.debug) {
const debug = getContextItem<Debug>("debug");
if (debug.car) {
doodler.drawLine(this.points, {
color: "blue",
weight: 3,

View File

@ -15,4 +15,11 @@ declare global {
bNeighbors: string[];
fNeighbors: string[];
};
type Debug = {
track: boolean;
train: boolean;
car: boolean;
path: boolean;
};
}