Refactor game loop to await start and enhance Sixel rasterizer terminal support detection

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-18 02:43:39 +01:00
parent 7fe9a8bc40
commit 28938f7301
3 changed files with 187 additions and 27 deletions

View File

@@ -9,7 +9,13 @@ class CliGameLoop {
CliGameLoop({
required this.engine,
required this.onExit,
}) : input = CliInput(),
}) : input = engine.input is CliInput
? engine.input as CliInput
: throw ArgumentError.value(
engine.input,
'engine.input',
'CliGameLoop requires a CliInput instance.',
),
primaryRasterizer = SixelRasterizer(),
secondaryRasterizer = AsciiRasterizer(isTerminal: true) {
_rasterizer = primaryRasterizer;
@@ -22,23 +28,37 @@ class CliGameLoop {
final void Function(int code) onExit;
final Stopwatch _stopwatch = Stopwatch();
final Stream<List<int>> _stdinStream = stdin.asBroadcastStream();
late CliRasterizer _rasterizer;
StreamSubscription<List<int>>? _stdinSubscription;
Timer? _timer;
bool _isRunning = false;
Duration _lastTick = Duration.zero;
void start() {
Future<void> start() async {
if (_isRunning) {
return;
}
stdin.echoMode = false;
stdin.lineMode = false;
if (primaryRasterizer is SixelRasterizer) {
final sixel = primaryRasterizer as SixelRasterizer;
sixel.isSixelSupported = await SixelRasterizer.checkTerminalSixelSupport(
inputStream: _stdinStream,
);
}
if (stdin.hasTerminal) {
try {
stdin.echoMode = false;
stdin.lineMode = false;
} catch (_) {
// Keep running without raw mode when stdin is not mutable.
}
}
stdout.write('\x1b[?25l\x1b[2J');
_stdinSubscription = stdin.listen(_handleInput);
_stdinSubscription = _stdinStream.listen(_handleInput);
_stopwatch.start();
_timer = Timer.periodic(const Duration(milliseconds: 33), _tick);
_isRunning = true;
@@ -59,8 +79,12 @@ class CliGameLoop {
}
if (stdin.hasTerminal) {
stdin.echoMode = true;
stdin.lineMode = true;
try {
stdin.echoMode = true;
stdin.lineMode = true;
} catch (_) {
// Ignore cleanup failures if stdin is no longer a mutable TTY.
}
}
if (stdout.hasTerminal) {