www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Desiring bool any_key_pressed()

reply Daren Scot Wilson <darenw darenscotwilson.com> writes:
Here is a very simple version of the program I'm working on.  Is 
there a way to write is_any_key_pressed() that doesn't block, 
doesn't require the Enter key, and doesn't require dragging in 
any complex libraries or dealing with low-level stuff like 
ioctl()? Is there nothing in Phobos that provides the needed 
functionality?

I won't go into the details, but I tried threading, putting the 
getchar() in a separate thread that sets a global bool 
g_keypressed variable. It was a disaster. Maybe there's a right 
way to use threading?  I am not talented at threads.

```
import core.thread;
import core.time;
import std.stdio;
import std.conv;


void light_on() {
     write("on "); stdout.flush;
}
void light_off() {
     write("off "); stdout.flush;
}

void wait()  {
     Duration dur = dur!("seconds")( to!int(1) );
     Thread.sleep(dur);
}


bool is_any_key_pressed()  {
     getchar();  // nope, requires Enter key to be pressed, and is 
blocking
     return true;
}

void main(string[] args)
{

     while (true)  {
         light_on();
         wait();
         light_off();
         wait();

         if (is_any_key_pressed())  {
             break;
         }
     }
}
```
Mar 02 2023
next sibling parent Andrew Lalis <andrewlalisofficial gmail.com> writes:
On Friday, 3 March 2023 at 03:38:56 UTC, Daren Scot Wilson wrote:
 Here is a very simple version of the program I'm working on.  
 Is there a way to write is_any_key_pressed() that doesn't 
 block, doesn't require the Enter key, and doesn't require 
 dragging in any complex libraries or dealing with low-level 
 stuff like ioctl()? Is there nothing in Phobos that provides 
 the needed functionality?
See this SO thread:https://stackoverflow.com/q/1798511 Essentially the os/terminal is buffering your input and that needs to be configured. getChar just reads from what's in stdin.
Mar 03 2023
prev sibling parent Adam D Ruppe <destructionator gmail.com> writes:
On Friday, 3 March 2023 at 03:38:56 UTC, Daren Scot Wilson wrote:
 Here is a very simple version of the program I'm working on.  
 Is there a way to write is_any_key_pressed() that doesn't 
 block, doesn't require the Enter key, and doesn't require 
 dragging in any complex libraries or dealing with low-level 
 stuff like ioctl()?
You have to do something since the normal behavior is the operating system holds on to the input until the user presses enter. You must tell it not to do that somehow. My terminal.d lib at least stands alone (for now, the next version will probably require two files instead of just one) and has things for this: http://arsd-official.dpldocs.info/arsd.terminal.html#single-key It is `input.kbhit()` just to test without getting the thing. Though... testing for input like this is a kinda iffy thing to do too, you might be able to adjust the program to be more event driven. Anyway, it is the "RealTimeConsoleInput" object in the library that tells the OS to stop buffering and send things directly. Its code isn't too complex - calls to tcgetattr and tcsetattr and similar for Windows - but still.
Mar 04 2023