Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to check whether a key has been pressed without blocking the flow of the program? #42

Open
Lodealodea opened this issue Apr 8, 2022 · 4 comments

Comments

@Lodealodea
Copy link

Some function similar to the C# function Keyboard.IsKeyPressed(...).

If not. How would you go about, for example. printing a message every second until a key is pressed?

@JoCat
Copy link

JoCat commented May 8, 2022

I set myself a similar task (to catch the TAB keystroke) and found this library. But the only problem is that, as it turned out, it works synchronously.
So far I've come to this solution:

  • Disable echoMode and lineMode (in general, only lineMode should be disabled in this case, but the dart API documentation states the following "On Windows this mode can only be disabled if echoMode is disabled as well", so I had to disable both modes)
  • Get BroadcastStream from stdin
  • Make 2 subscriptions, one as before through transform(utf8.decoder).transform(LineSplitter()) and the second already for direct listening from the stream and when you receive a press on tab (keyCode=9) perform any actions, otherwise write to stdout stdout.writeCharCode(keyCode[0]) (remember I had to disable echoMode)
    image

@JoCat
Copy link

JoCat commented May 8, 2022

UPD

I wrote a helper class

import 'dart:convert';

import 'dart:io';

class Console {
  Console(Function(List<int>) onKeyListener, Function(String) onLineListener) {
    stdin.echoMode = false;
    stdin.lineMode = false;

    stdin.asBroadcastStream()
      ..listen(onKeyListener)
      ..transform(Utf8Decoder())
          .transform(LineSplitter())
          .listen(onLineListener);
  }
}

there was a little more code, but I cut out the excess

use:

Console((charCodes) {
  // On key press event
  stdout.write(charCodes);
}, (line) {
  // On line print event
  stdout.write(line);
});

@xErik
Copy link

xErik commented Nov 8, 2023

I would need the same feature.

Running a periodic timer next to a game loop but the readKey() blocks exectution.

Timer.periodic(Duration(seconds: 1), (timer) {
  print(timer); // fails
});

while(true) {
  console.readKey();
}

@bsutton
Copy link
Collaborator

bsutton commented Nov 8, 2023

stdin is a stream with a listen method, if you combine this with placing stdin into non-line mode I think you might have a solution.

I've not tried it but something like

 stdin.lineMode = false;
stdin.listen((data) -> print(data));

remember to place stdin back into lineMode before you exit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants