/ proof-of-concept / steelsim21
Sign in
proof-of-concept / steelsim21
Stop button: end a run and unlock the parameter fields
Jeremy Magland <jmagland@flatironinstitute.org> committed commit 176c8fba0caa parent 10998ac Browse files
3 changed files+29−4
README.mdmodified+1−0View file
@@ -17,6 +17,7 @@ Press Start. With the default excitation the sheet is pushed at the bottom-right
1717
1818 - The sheet has a stress-free initial bow (default 3 mm across the width; set the shape to Flat for the ideal plate). A negative push amount pushes against the bow.
1919 - Plate, initial shape, excitation, and numerics parameters take effect at the next Start. Damping, listener position, and the radiation model can be changed while a simulation runs.
20+- Pause halts the run temporarily; Stop ends it, keeps the audio and movie, and unlocks the parameter fields for the next Start.
2021 - After the simulation completes, drag the time slider to explore the movie; Play starts audio from the slider position and moves the movie and the spectrogram cursor with it. Live returns to the running view.
2122 - To extend a finished simulation, raise the duration and press Continue; the state is kept on the GPU.
2223 - Any parameter can be preset in the URL in SI units, for example `?spacing=0.006&duration=2&autostart=1`.
src/main.tsmodified+14−3View file
@@ -244,6 +244,7 @@ let duration = params.duration;
244244
245245 const btnStart = mkButton("Start", "primary");
246246 const btnPause = mkButton("Pause");
247+const btnStop = mkButton("Stop");
247248 const btnContinue = mkButton("Continue");
248249 const durInput = document.createElement("input");
249250
@@ -278,7 +279,17 @@ function buildControls(): void {
278279 u.className = "unit";
279280 u.textContent = "s";
280281 durRow.append(l, durInput, u);
281- c.append(durRow, btnStart, btnPause, btnContinue);
282+ c.append(durRow, btnStart, btnPause, btnStop, btnContinue);
283+ btnStop.addEventListener("click", () => {
284+ if (!sim) return;
285+ sim.stop();
286+ paused = false;
287+ btnPause.textContent = "Pause";
288+ if (!running) {
289+ setFormEnabled(true);
290+ updateButtons();
291+ }
292+ });
282293 btnStart.addEventListener("click", () => void start());
283294 btnPause.addEventListener("click", () => {
284295 paused = !paused;
@@ -297,8 +308,8 @@ function buildControls(): void {
297308 function updateButtons(): void {
298309 const s = sim?.status();
299310 btnPause.disabled = !sim || s?.phase === "done" || (!running && !paused);
300- btnContinue.disabled = !sim || running || !s || s.phase !== "done" || s.samples >= Math.round(duration * params.fs) - 1;
301- if (sim && sim.phase === "done" && sim.samples < sim.targetSamples()) btnContinue.disabled = false;
311+ btnStop.disabled = !sim || s?.phase === "done";
312+ btnContinue.disabled = !sim || running || !sim.canContinue();
302313 }
303314
304315 // ---------- View toolbars ----------
src/sim/simulation.tsmodified+14−1View file
@@ -309,6 +309,7 @@ export class Simulation {
309309 if (params.excitation === "strike") {
310310 // No push phase: the sheet is at rest in its natural shape when the stick arrives.
311311 this.phase = "recording";
312+ this.released = true;
312313 this.frames.push(new Float32Array(n));
313314 }
314315 }
@@ -358,9 +359,20 @@ export class Simulation {
358359
359360 setDuration(duration: number): void {
360361 this.params.duration = duration;
361- if (this.phase === "done" && this.samples < this.targetSamples()) this.phase = "recording";
362+ if (this.phase === "done" && this.released && this.samples < this.targetSamples()) this.phase = "recording";
362363 }
363364
365+ /** True when a finished or stopped run can be extended. */
366+ canContinue(): boolean {
367+ return this.phase === "done" && this.released && this.samples < this.targetSamples();
368+ }
369+
370+ /** Ends the run; the state, audio, and movie are kept. */
371+ stop(): void {
372+ this.phase = "done";
373+ }
374+ private released = false;
375+
364376 targetSamples(): number {
365377 return Math.round(this.params.duration * this.params.fs);
366378 }
@@ -583,6 +595,7 @@ export class Simulation {
583595
584596 private release(): void {
585597 this.phase = "recording";
598+ this.released = true;
586599 this.stepCount = 0;
587600 this.totalSteps = 0;
588601 // The finger force and the distributed holding reaction relax together:
↑↓ move↵openescclose