From: Svjatoslav Agejenko Date: Sun, 15 Mar 2026 04:22:54 +0000 (+0200) Subject: feat(benchmark): add keyboard shortcut to skip tests X-Git-Url: http://www2.svjatoslav.eu/gitweb/?a=commitdiff_plain;h=eeb3d31736986e7103e4cd5c8f424ea97a5805a3;p=sixth-3d-demos.git feat(benchmark): add keyboard shortcut to skip tests Allow pressing Space to skip to the next benchmark test immediately. Also improve cleanup by properly removing listeners and stopping the render loop when the benchmark finishes. --- diff --git a/doc/index.org b/doc/index.org index 2ad0fd7..c6606cb 100644 --- a/doc/index.org +++ b/doc/index.org @@ -212,6 +212,7 @@ three tests sequentially, each for 30 seconds: The camera follows a deterministic orbital path around the scene, ensuring reproducible results across runs. +Example benchmark results: #+begin_example ================================================================================ GRAPHICS BENCHMARK RESULTS diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/benchmark/GraphicsBenchmark.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/benchmark/GraphicsBenchmark.java index 14e4d1b..d336dee 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/benchmark/GraphicsBenchmark.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/benchmark/GraphicsBenchmark.java @@ -10,8 +10,11 @@ import eu.svjatoslav.sixth.e3d.gui.Camera; import eu.svjatoslav.sixth.e3d.gui.FrameListener; import eu.svjatoslav.sixth.e3d.gui.ViewFrame; import eu.svjatoslav.sixth.e3d.gui.ViewPanel; +import eu.svjatoslav.sixth.e3d.gui.humaninput.KeyboardInputHandler; import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection; +import javax.swing.SwingUtilities; +import java.awt.event.KeyEvent; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -23,7 +26,9 @@ import java.util.List; * reproducible benchmark results to standard output. * *

The benchmark creates a 16x16x16 grid of cubes (4096 total) with the camera - * following a deterministic orbital path. Each test runs for 30 seconds.

+ * following a deterministic orbital path. Each test runs for 30 seconds by default.

+ * + *

Press Space to skip to the next test immediately.

* *

Available tests:

* */ -public class GraphicsBenchmark implements FrameListener { +public class GraphicsBenchmark implements FrameListener, KeyboardInputHandler { private static final int WINDOW_WIDTH = 1920; private static final int WINDOW_HEIGHT = 1080; @@ -52,6 +57,7 @@ public class GraphicsBenchmark implements FrameListener { private long frameCount; private BenchmarkTest currentTest; private boolean testFinished = false; + private boolean benchmarkFinished = false; private final List results = new ArrayList<>(); private final List tests = new ArrayList<>(); @@ -78,6 +84,7 @@ public class GraphicsBenchmark implements FrameListener { viewPanel.setFrameRate(0); shapes = viewPanel.getRootShapeCollection(); viewPanel.addFrameListener(this); + viewPanel.getKeyboardFocusStack().pushFocusOwner(this); camera = viewPanel.getCamera(); } @@ -90,7 +97,7 @@ public class GraphicsBenchmark implements FrameListener { private void startNextTest() { int nextIndex = results.size(); if (nextIndex >= tests.size()) { - finishBenchmark(); + scheduleBenchmarkFinish(); return; } @@ -103,8 +110,30 @@ public class GraphicsBenchmark implements FrameListener { currentTest.setup(shapes); } + private void finishCurrentTest() { + if (currentTest == null || testFinished) { + return; + } + + testFinished = true; + long elapsed = System.currentTimeMillis() - testStartTime; + double durationSeconds = elapsed / 1000.0; + results.add(new TestResult(currentTest.getName(), frameCount, durationSeconds)); + + currentTest.teardown(shapes); + startNextTest(); + } + + private void scheduleBenchmarkFinish() { + benchmarkFinished = true; + SwingUtilities.invokeLater(this::finishBenchmark); + } + private void finishBenchmark() { currentTest = null; + viewPanel.getKeyboardFocusStack().popFocusOwner(); + viewPanel.removeFrameListener(this); + viewPanel.stop(); viewFrame.dispose(); printResults(); } @@ -138,6 +167,10 @@ public class GraphicsBenchmark implements FrameListener { @Override public boolean onFrame(ViewPanel viewPanel, int millisecondsSinceLastFrame) { + if (benchmarkFinished) { + return false; + } + if (currentTest == null) { return true; } @@ -155,14 +188,33 @@ public class GraphicsBenchmark implements FrameListener { long elapsed = System.currentTimeMillis() - testStartTime; if (elapsed >= TEST_DURATION_MS && !testFinished) { - testFinished = true; - double durationSeconds = elapsed / 1000.0; - results.add(new TestResult(currentTest.getName(), frameCount, durationSeconds)); - - currentTest.teardown(shapes); - startNextTest(); + finishCurrentTest(); } return true; } + + @Override + public boolean keyPressed(KeyEvent event, ViewPanel viewPanel) { + if (event.getKeyChar() == ' ') { + finishCurrentTest(); + return true; + } + return false; + } + + @Override + public boolean keyReleased(KeyEvent event, ViewPanel viewPanel) { + return false; + } + + @Override + public boolean focusLost(ViewPanel viewPanel) { + return false; + } + + @Override + public boolean focusReceived(ViewPanel viewPanel) { + return false; + } } \ No newline at end of file