Re: Read from terminal when enter is pressed, but do other stuff in the mean time...
On Thursday, 13 July 2017 at 15:52:57 UTC, Dustmight wrote: How do I read in input from the terminal without sitting there waiting for it? I've got code I want to run while there's no input, and then code I want to act on input when it comes in. How do I do both these things? As Stefan mentions, the single threaded version is basically OS specific (and as others have said there are some wrappers available) the multithreaded solution is fairly simple (have one thread blocked on read(stdin), the other working, synchronize as necessary). If you are interested, on Linux one low level (single threaded) version would essentially consist of: - check on program startup whether the stdin file descriptor refers to something that (sanely) supports readiness events (tty, sockets, pipes, etc. - *not* regular files) using calls like `isatty`[1] and co. - if it's a tty, put it into "raw" mode - get yourself an epoll instance and register stdin with it - get a file descriptor, e.g. an eventfd, for "there's work to be done now" and register it with the epoll instance - have the thread wait for readiness events on the epoll instance and deal with stdin being readable and "there's work to be done now" events for their respective fd. - Queue work on the eventfd as necessary (e.g. from within the readiness handling of the previous step) [1] http://man7.org/linux/man-pages/man3/isatty.3.html
Re: Read from terminal when enter is pressed, but do other stuff in the mean time...
On 07/13/2017 08:52 AM, Dustmight wrote: How do I read in input from the terminal without sitting there waiting for it? I've got code I want to run while there's no input, and then code I want to act on input when it comes in. How do I do both these things? If you're fine with buffered input, i.e. the user has to press Enter before the input is visible to the program, then std.concurrency works pretty well. Enter lines to the following program. It will exit when you send the line "done". import std.concurrency; import std.stdio; import core.thread; import std.range; struct Done { } struct Message { string line; } void worker() { bool done = false; while (!done) { receive( (Message message) { auto line = message.line; writefln("Received \"%s\"", line); while (!line.empty) { writeln(line.front); line.popFront(); Thread.sleep(500.msecs); } writefln("Done with \"%s\"", message); }, (Done message) { writefln("Bye..."); done = true; }); } } void main() { auto w = spawn(&worker); foreach (line; stdin.byLineCopy) { if (line == "done") { w.send(Done()); break; } w.send(Message(line)); } thread_joinAll(); } Ali
Re: Read from terminal when enter is pressed, but do other stuff in the mean time...
On Thursday, 13 July 2017 at 15:52:57 UTC, Dustmight wrote: How do I read in input from the terminal without sitting there waiting for it? I've got code I want to run while there's no input, and then code I want to act on input when it comes in. How do I do both these things? Might want to check Adam's Terminal.d https://code.dlang.org/packages/arsd-official%3Aterminal Docs at http://dpldocs.info/experimental-docs/arsd.terminal.html You can use a RealTimeConsoleInput with getch. You can use kbhit to check whether getch would block. However I found inconsistent behavior between platforms with kbhit, so might wanna test.
Re: Read from terminal when enter is pressed, but do other stuff in the mean time...
On Thursday, 13 July 2017 at 15:52:57 UTC, Dustmight wrote: How do I read in input from the terminal without sitting there waiting for it? I've got code I want to run while there's no input, and then code I want to act on input when it comes in. How do I do both these things? You have to ask the OS for this. All of this is platform specific functionality. check your operating-system-api search terms are unbufferd i/o and event-loop
Read from terminal when enter is pressed, but do other stuff in the mean time...
How do I read in input from the terminal without sitting there waiting for it? I've got code I want to run while there's no input, and then code I want to act on input when it comes in. How do I do both these things?