A
Adam Shelly
Is there a way to perform a non-blocking gets or getc? As in a method
that reads a character from stdin if there is one in the buffer or
returns nil otherwise?
If I was programming a Windows console app in C, I would use kbhit()
to check if there was a character in the buffer. So I decided this
was a good time to try writing my first ruby c extension.
on Windows, save and complie conio.c into conio.dll, and then the
following example should work.
-Adam
--- test_conio.rb ---
require 'conio'
#background work:
Thread.new { print('.') or sleep(1) while true }
#check for input in this thread
Thread.new do
while 1
while !CONIO::kbhit?; end #--wait for key, nonblocking
#s = STDIN::getc #--this blocks until return pressed
s = CONIO::getch #--this doesn't
p "#{s} (#{s.chr})"
exit if s==?q
end
end
#do some foreground work
puts("waiting") or sleep(10) while 1
---
---conio.c---
/* conio.c -- Windows conio functions
3 Oct 2007, Adam Shelly
Ruby license applies
*/
#include "ruby.h"
#include <conio.h>
static VALUE c_kbhit(VALUE self)
{
return _kbhit()? Qtrue : Qfalse;
}
static VALUE c_getch(VALUE self)
{
int n = _getch();
return INT2FIX(n);
}
static VALUE c_ungetch(VALUE self, VALUE cv)
{
int c = FIX2INT(cv);
int n = _ungetch(c);
return INT2FIX(n);
}
VALUE mConio;
__declspec( dllexport ) void Init_conio()
{
mConio = rb_define_module("CONIO");
rb_define_module_function(mConio, "kbhit?", c_kbhit, 0);
rb_define_module_function(mConio, "getch", c_getch, 0);
rb_define_module_function(mConio, "ungetch", c_ungetch, 1);
}