Description
The following program throws a FormatException when you press 'a' with another key simultaneously (e.g., press and 'a' and 's' at the same time).
import "package:console/console.dart";
void main() {
Keyboard.init();
Keyboard.bindKey("a").listen((_) {
final pos = Console.getCursorPosition();
print(pos);
});
}
Unhandled exception:
FormatException: Invalid radix-10 number
[21
#0 int._throwFormatException (dart:core-patch/integers_patch.dart:111)
#1 int._parse (dart:core-patch/integers_patch.dart:101)
#2 int.parse (dart:core-patch/integers_patch.dart:58)
#3 Console.getCursorPosition.<anonymous closure> (package:console/src/base.dart:226:97)
#4 MappedListIterable.elementAt (dart:_internal/iterable.dart:413)
#5 ListIterator.moveNext (dart:_internal/iterable.dart:341)
#6 List.List.from (dart:core-patch/array_patch.dart:40)
#7 Console.getCursorPosition (package:console/src/base.dart:226:27)
#8 main.<anonymous closure> (file:///Users/kseo/dart/console.dart/example/keyboard.dart:7:25)
Console.getCursorPosition()
synchronously writes ANSI 6h
and reads the position. The underlying assumption is that there is no other interfering character while you perform Console.getCursorPosition()
.
But the exception above is caused because there is 's' character in the buffer when the callback is invoked for 'a' key. It is a race condition because the exception won't happen if you type 's' slightly slower than 'a'.
The cause is clear, but I am not sure how to fix this. If you just skip 's' in the buffer and perform Console.getCursorPosition()
, the exception will disappear but 's' will be lost too. Once you read 's', there is no way to put it back at the front of the buffer.
I think the fundamental problem lies in that the API of console
package mixes both synchronous and asynchronous API in a non-compatible way. It seems we can't reliably use synchronous APIs like Console.getCursorPosition()
under the asynchronous key callback because "mixing synchronous and asynchronous reads is undefined".
Any suggestion?