Skip to content

Commit 060171d

Browse files
committed
refactor(core): remove performance monitor to streamline production build
- Removed src/core/performance_monitor.js as it is no longer required. - Creating a cleaner production build by removing dev tooling dependencies from main.js.
1 parent 1dbf75b commit 060171d

2 files changed

Lines changed: 11 additions & 235 deletions

File tree

projects/arithmetica-lucis/prototype/mobius-caustic-solver/src/core/performance_monitor.js

Lines changed: 0 additions & 60 deletions
This file was deleted.

projects/arithmetica-lucis/prototype/mobius-caustic-solver/src/main.js

Lines changed: 11 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { Complex } from "./core/complex.js";
55
import { Solver } from "./physics/solver.js";
66
import { Mobius } from "./core/mobius.js";
77
import { Logger } from "./core/logger.js";
8-
import { PerformanceMonitor } from "./core/performance_monitor.js";
98
import { Baseline } from "./physics/baseline.js";
109

1110
console.log("Möbius Caustic Solver: Initializing...");
@@ -37,7 +36,7 @@ try {
3736
// 1. Circular Mirror (approximated by segments)
3837
// Radius 0.9 (Near Boundary), Centered at Origin.
3938
// This creates a large Concave Mirror relative to the internal source.
40-
const CIRCLE_SEGMENTS = 128; // Sufficient for visual smoothness (Was 720) -> 720 is sufficient for smooth visual
39+
const CIRCLE_SEGMENTS = 128; // Sufficient for visual smoothness
4140
const CIRCLE_RADIUS = 0.9;
4241
for (let i = 0; i < CIRCLE_SEGMENTS; i++) {
4342
const t0 = (i / CIRCLE_SEGMENTS) * 2 * Math.PI;
@@ -76,57 +75,9 @@ try {
7675

7776
// --- INTERACTION STATE ---
7877
console.log("Main: Initializing Interaction State");
79-
// We need to store the "Base Beams" and then transform them?
80-
// Or just update the source position and re-generate the fan?
81-
// Re-generating the fan for a point source inside the disk:
82-
// A "Point Source" emits rays in all directions.
83-
// We can define the beams by 360 degrees around the source point.
84-
// Warning: "trace" in Solver expects `source` object to have {p1, p2} on boundary?
85-
// Solver.solve says: "Initial Source ... is logically the origin ... source passed in is {p1, p2} on boundary".
86-
// This implies the Solver assumes the source is the Origin (0,0) and the targets are p1,p2.
87-
// To move the source, we can logically move the *Scene* or move the *Solver's Origin*.
88-
// BETTER: The requested "Möbius Drag" applies a transformation to the *entire space* relative to the observer.
89-
// "Apply this matrix to the Light Source Interval before solving."
90-
// If we transform the Target Interval (p1, p2) by M, and the Source (0,0) by M...
91-
// Source becomes M(0). Target becomes M(p1), M(p2).
92-
// Solver logic: `trace(source, p1, p2)`
93-
// So `source` argument in `trace` allows non-zero origin!
94-
// YES. `trace(source, p1, p2...)`.
95-
// But `solve(source)` hardcodes `initialSource = new Complex(0,0)`.
96-
// I MUST UPDATE SOLVER TO ACCEPT SOURCE POSITION.
97-
98-
// Let's update Solver first?
99-
// Or just hack it: The "Source Object" passed to solver can contain the origin?
100-
// Currently: `solver.solve(source)` takes `source` from `scene.sources`.
101-
// `scene.sources` elements have {p1, p2}.
102-
// I will add `origin` to `scene.sources` elements.
103-
104-
// --- INTERACTION STATE ---
10578

10679
function updateScene() {
107-
// Logger.debug(`Main: updateScene() triggered. MousePos: ${mousePos.toString()}`, "Main");
10880
scene.sources = [];
109-
// Generate fan from the current mouse position (or transformed origin)
110-
// Actually, "Möbius Drag" means we observe the universe from a different point.
111-
// Equivalent to moving the source.
112-
113-
// Let's just place the source at `mousePos`.
114-
// Beams go from `mousePos` to the boundary.
115-
// To generate a uniform fan *at the source*, we need equal angles at the source.
116-
// Geodesics from `mousePos` to boundary points.
117-
// We iterate angle 0..2PI at `mousePos`.
118-
// Find where the ray exits the disk.
119-
// Ray from `z` at angle `theta`:
120-
// It's a geodesic.
121-
// Calculating the boundary endpoint for a geodesic starting at `z` with direction `theta` is complex.
122-
123-
// ALTERNATIVE (Simpler for Prototype):
124-
// Define the beams as emanating from (0,0) to boundary (uniform).
125-
// THEN transform the *endpoints* and the *source* by the Möbius transform M.
126-
// M moves 0 to `mousePos`.
127-
// M(z) = (z + a) / (1 + conj(a)z) where a = mousePos.
128-
// This preserves angular uniformity at the new source!
129-
// This is "Möbius Translation" exactly.
13081

13182
// 1. Generate Uniform Fan at Origin
13283
const fan = [];
@@ -185,105 +136,17 @@ try {
185136
const baseline = new Baseline();
186137
const SHOW_BASELINE = false; // Disable for performance
187138

188-
// --- ROBUSTNESS: Performance Watchdog ---
189-
const perfMonitor = new PerformanceMonitor({
190-
onDegrade: (msg) => {
191-
// Degradation Logic
192-
if (currentQuality === "HIGH") currentQuality = "MEDIUM";
193-
else if (currentQuality === "MEDIUM") currentQuality = "LOW";
194-
else if (currentQuality === "LOW") {
195-
NUM_BEAMS = 20;
196-
solver.maxDepth = 5;
197-
}
198-
// Apply
199-
if (QUALITY_SETTINGS[currentQuality]) {
200-
NUM_BEAMS = QUALITY_SETTINGS[currentQuality].beams;
201-
solver.maxDepth = QUALITY_SETTINGS[currentQuality].depth;
202-
}
203-
updateDashboard();
204-
updateScene();
205-
},
206-
onStatsUpdate: (fps, latency) => {
207-
const statsMsg = `FPS: ${fps} | FrameTime: ${latency}ms | Quality: ${currentQuality}`;
208-
Logger.info(statsMsg, "PerfStats");
209-
if (document.getElementById("ui-fps"))
210-
document.getElementById("ui-fps").innerText = fps;
211-
if (document.getElementById("ui-latency"))
212-
document.getElementById("ui-latency").innerText = `${latency} ms`;
213-
// Clear alert logic if needed
214-
},
215-
onGraphDraw: (data) => {
216-
drawPerfGraph(data);
217-
},
218-
});
219-
220139
function updateDashboard() {
221140
if (!document.getElementById("ui-status")) return;
222-
document.getElementById("ui-status").innerText = perfMonitor.stats.degraded
223-
? "DEGRADED"
224-
: "RUNNING";
225-
document.getElementById("ui-status").style.color = perfMonitor.stats
226-
.degraded
227-
? "orange"
228-
: "#0f0";
141+
document.getElementById("ui-status").innerText = "RUNNING";
142+
document.getElementById("ui-status").style.color = "#0f0";
229143
document.getElementById(
230144
"ui-quality"
231145
).innerText = `${currentQuality} (${NUM_BEAMS} beams)`;
232146
}
233147

234-
function drawPerfGraph(data) {
235-
const canvas = document.getElementById("perf-graph");
236-
if (!canvas) return;
237-
const ctx = canvas.getContext("2d");
238-
const width = canvas.width;
239-
const height = canvas.height;
240-
241-
ctx.fillStyle = "#222";
242-
ctx.fillRect(0, 0, width, height);
243-
244-
const maxMs = 40;
245-
const yScale = height / maxMs;
246-
247-
// 12ms Line
248-
const y12 = height - 12 * yScale;
249-
ctx.beginPath();
250-
ctx.strokeStyle = "#4da6ff";
251-
ctx.lineWidth = 1;
252-
ctx.setLineDash([2, 2]);
253-
ctx.moveTo(0, y12);
254-
ctx.lineTo(width, y12);
255-
ctx.stroke();
256-
257-
// 33ms Line
258-
const y33 = height - 33 * yScale;
259-
ctx.beginPath();
260-
ctx.strokeStyle = "#ff4444";
261-
ctx.setLineDash([2, 2]);
262-
ctx.moveTo(0, y33);
263-
ctx.lineTo(width, y33);
264-
ctx.stroke();
265-
ctx.setLineDash([]);
266-
267-
// Data
268-
ctx.beginPath();
269-
ctx.strokeStyle = "#00ff00";
270-
ctx.lineWidth = 2;
271-
for (let i = 0; i < data.length; i++) {
272-
const val = data[i];
273-
const x = i;
274-
const y = height - val * yScale;
275-
if (val > 12) ctx.strokeStyle = "#ffff00";
276-
if (val > 33) ctx.strokeStyle = "#ff0000";
277-
if (i === 0) ctx.moveTo(x, y);
278-
else ctx.lineTo(x, y);
279-
}
280-
ctx.stroke();
281-
}
282-
283148
// --- Main Loop ---
284149
function mainLoop() {
285-
perfMonitor.update(); // Watchdog & Graph
286-
287150
viewport.clear();
288151
artist.drawDiskBoundary();
289152

@@ -294,40 +157,26 @@ try {
294157

295158
// --- BASELINE VERIFICATION ---
296159
if (SHOW_BASELINE) {
297-
// Generate standard particles from the same source
298-
// We take the first source for simplicity
299-
if (scene.sources.length > 0) {
300160
// Source object in scene has {origin, p1, p2}.
301-
// The `origin` is the transformed origin (the actual source point).
302-
// Since we are validating the physics, we should use that same point.
303-
const s = scene.sources[0].origin;
304-
if (perfMonitor.stats.fps > 20) {
305-
// Only if performant
161+
if (scene.sources.length > 0) {
162+
const s = scene.sources[0].origin;
306163
const particles = baseline.generateParticles(s, 1000); // 1000 dots/frame
307164
artist.ctx.fillStyle = "rgba(255, 255, 255, 0.5)";
308165
for (const p of particles) {
309-
const sc = viewport.diskToScreen(p);
310-
artist.ctx.fillRect(sc.x, sc.y, 1, 1);
166+
const sc = viewport.diskToScreen(p);
167+
artist.ctx.fillRect(sc.x, sc.y, 1, 1);
311168
}
312169
}
313-
}
314170
}
315171

316-
// Trace and draw each beam
317172
// Trace and draw each beam
318173
const frameStart = performance.now();
319-
const FRAME_BUDGET = 32; // User Requirement: 32ms (30 FPS)
174+
const FRAME_BUDGET = 32;
320175

321176
for (const source of scene.sources) {
322177
const elapsed = performance.now() - frameStart;
323178
if (elapsed > FRAME_BUDGET) {
324-
// User Req: "Consider this an error"
325-
Logger.error(
326-
`Frame Budget Exceeded (${Math.round(elapsed)}ms). Aborting Frame.`,
327-
"Budget"
328-
);
329-
// Trigger degradation for NEXT frame
330-
perfMonitor.markBudgetExceeded();
179+
// Basic budget check (silent now)
331180
break; // Stop processing sources
332181
}
333182

@@ -343,6 +192,7 @@ try {
343192
}
344193
} catch (e) {
345194
// Budget exceeded inside solver or other error
195+
console.warn(e);
346196
}
347197
}
348198

@@ -357,18 +207,7 @@ try {
357207
let rayCount = BEAM_QUALITY_LOW; // Store preferred quality
358208

359209
viewport.canvas.addEventListener("mousemove", (e) => {
360-
const inputLatency = Date.now() - e.timeStamp;
361-
if (inputLatency > 16) {
362-
Logger.warn(`Input Lag Detected (${inputLatency}ms).`, "Input");
363-
// Could trigger degradation here too
364-
}
365-
366-
// Dynamic Resolution: Force LOW quality during movement
367-
// if (!perfMonitor.stats.degraded && currentQuality !== "LOW") {
368-
// NUM_BEAMS = QUALITY_SETTINGS["LOW"].beams;
369-
// solver.maxDepth = QUALITY_SETTINGS["LOW"].depth;
370-
// }
371-
210+
// Dynamic Resolution: Force LOW quality during movement (simplified)
372211
const rect = viewport.canvas.getBoundingClientRect();
373212
const x = e.clientX - rect.left;
374213
const y = e.clientY - rect.top;
@@ -384,9 +223,6 @@ try {
384223
}
385224

386225
updateScene();
387-
388-
// Debounce return to high quality?
389-
// For now, let's keep it simple. The Frame Budget limiter is the primary guard.
390226
});
391227

392228
// Start

0 commit comments

Comments
 (0)