DirectMyFile / console.dart

Console Library
Other
107 stars 24 forks source link

Console.getCursorPosition throws a FormatException #11

Open kseo opened 8 years ago

kseo commented 8 years ago

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?

azenla commented 8 years ago

I will look into this. I have considering making everything asynchronous.

kseo commented 8 years ago

Any progress?