feat: Add FPS toggle shortcut and corresponding input handling in CLI

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-23 17:12:27 +01:00
parent b88475882b
commit ea6825341e
3 changed files with 38 additions and 0 deletions
+7
View File
@@ -162,6 +162,13 @@ class CliGameLoop {
return; return;
} }
if (input.matchesFpsToggleShortcut(bytes)) {
engine.toggleFpsCounter();
_syncRendererFromEngine();
unawaited(persistence?.save(engine.rendererSettings));
return;
}
input.handleKey(bytes); input.handleKey(bytes);
} }
@@ -12,6 +12,9 @@ class CliInput extends Wolf3dInput {
/// Keyboard shortcut used by the CLI host to cycle ASCII themes. /// Keyboard shortcut used by the CLI host to cycle ASCII themes.
String asciiThemeCycleKey = 't'; String asciiThemeCycleKey = 't';
/// Keyboard shortcut used by the CLI host to toggle the FPS counter.
String fpsToggleKey = '`';
/// Human-friendly label for [rendererToggleKey] shown in CLI hints. /// Human-friendly label for [rendererToggleKey] shown in CLI hints.
String get rendererToggleKeyLabel => _formatShortcutLabel(rendererToggleKey); String get rendererToggleKeyLabel => _formatShortcutLabel(rendererToggleKey);
@@ -19,6 +22,9 @@ class CliInput extends Wolf3dInput {
String get asciiThemeCycleKeyLabel => String get asciiThemeCycleKeyLabel =>
_formatShortcutLabel(asciiThemeCycleKey); _formatShortcutLabel(asciiThemeCycleKey);
/// Human-friendly label for [fpsToggleKey] shown in CLI hints.
String get fpsToggleKeyLabel => _formatShortcutLabel(fpsToggleKey);
/// Returns true when [bytes] triggers the renderer-toggle shortcut. /// Returns true when [bytes] triggers the renderer-toggle shortcut.
bool matchesRendererToggleShortcut(List<int> bytes) => bool matchesRendererToggleShortcut(List<int> bytes) =>
_matchesShortcut(bytes, rendererToggleKey); _matchesShortcut(bytes, rendererToggleKey);
@@ -27,6 +33,10 @@ class CliInput extends Wolf3dInput {
bool matchesAsciiThemeCycleShortcut(List<int> bytes) => bool matchesAsciiThemeCycleShortcut(List<int> bytes) =>
_matchesShortcut(bytes, asciiThemeCycleKey); _matchesShortcut(bytes, asciiThemeCycleKey);
/// Returns true when [bytes] triggers the FPS-toggle shortcut.
bool matchesFpsToggleShortcut(List<int> bytes) =>
_matchesShortcut(bytes, fpsToggleKey);
String _formatShortcutLabel(String key) { String _formatShortcutLabel(String key) {
final String trimmed = key.trim(); final String trimmed = key.trim();
if (trimmed.isEmpty) { if (trimmed.isEmpty) {
@@ -0,0 +1,21 @@
import 'package:test/test.dart';
import 'package:wolf_3d_dart/wolf_3d_input.dart';
void main() {
group('CliInput shortcuts', () {
test('matches default FPS toggle shortcut with backtick', () {
final input = CliInput();
expect(input.matchesFpsToggleShortcut(const [96]), isTrue);
expect(input.matchesFpsToggleShortcut(const [126]), isFalse);
expect(input.matchesFpsToggleShortcut(const [114]), isFalse);
});
test('matches renderer shortcut case-insensitively', () {
final input = CliInput();
expect(input.matchesRendererToggleShortcut(const [114]), isTrue);
expect(input.matchesRendererToggleShortcut(const [82]), isTrue);
});
});
}