Non-blocking 'gets'?

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

···

On 10/3/07, Stephen Ware <sgware@gmail.com> wrote:

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?

---
---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);
}

Err... does anyone have an answer to my original question?

···

--
Posted via http://www.ruby-forum.com/.

Wow, that is quite complex. Thank you!

I also managed to discover another usable method: run a 'system' command
in a new thread. That seems to release the blocking on gets by creating
a second process, and as far as I can tell will work on both Windows and
*nix. The downside is that the two processes can't really communicate
with each other much, but in my case I don't need them to.

Thanks everyone for you help :slight_smile:

···

--
Posted via http://www.ruby-forum.com/.

Stephen Ware wrote:

Wow, that is quite complex. Thank you!

I also managed to discover another usable method: run a 'system' command
in a new thread. That seems to release the blocking on gets by creating
a second process, and as far as I can tell will work on both Windows and
*nix. The downside is that the two processes can't really communicate
with each other much, but in my case I don't need them to.

Thanks everyone for you help :slight_smile:

Stephen,

Can you please provide a very simple 'system' command example as I'm
having the same problem.

···

--
Posted via http://www.ruby-forum.com/\.

Why don't you just bind a keypress event? That would capture any given
keystroke in a non blocking way.

···

--
Posted via http://www.ruby-forum.com/.

Lloyd Linklater wrote:

Why don't you just bind a keypress event? That would capture any given
keystroke in a non blocking way.

Can you provide an example?

···

--
Posted via http://www.ruby-forum.com/\.

Wurzel Cidermaker wrote:

Lloyd Linklater wrote:

Why don't you just bind a keypress event? That would capture any given
keystroke in a non blocking way.

Can you provide an example?

I got the idea from the pickaxe book starting on page 246.

···

--
Posted via http://www.ruby-forum.com/\.