William Morgan
2/12/2005 5:33:00 PM
Hello all.
It looks like non-blocking getch (i.e. when nodelay = 1) with Ruby's
standard curses library blocks when there are other Threads running.
Once the other Thread dies, it resumes non-blocking operation once a key
is pressed. With the ncurses library, this problem doesn't happen.
I'm not a curses/ncurses expert, so maybe I'm doing something wrong.
Here's the code:
require "curses"
begin
Curses.init_screen
Curses.noecho
Curses.stdscr.nodelay = 1
start = Time.now
Thread.new { sleep 5; }
while true
Curses.stdscr.setpos(5, 5)
Curses.stdscr.addstr("#{(Time.now - start).round} waiting for input...")
Curses.refresh
x = Curses.stdscr.getch
Curses.stdscr.setpos(5, 5)
Curses.stdscr.addstr("#{(Time.now - start).round} got: #{x} ")
Curses.refresh
sleep 0.5
end
ensure
Curses.echo
Curses.close_screen
end
You'll see that getch blocks ("waiting for input" is displayed) until
after the first five seconds, when the thread dies. Then as soon as you
press a key, getch is back in non-blocking mode. If you remove the
Thread.new call, everything works as it should.
This is on ruby 1.8.2 (2005-01-10) [i386-linux].
For reference, here's the equivalent Ncurses code, which works fine:
require "ncurses"
begin
Ncurses.initscr
Ncurses.noecho
Ncurses.stdscr.nodelay true
start = Time.now
Thread.new { sleep 5; }
while true
Ncurses.stdscr.move(5, 5)
Ncurses.stdscr.addstr("#{(Time.now - start).round} waiting for input...")
Ncurses.refresh
x = Ncurses.stdscr.getch
Ncurses.stdscr.move(5, 5)
Ncurses.stdscr.addstr("#{(Time.now - start).round} got: #{x} ")
Ncurses.refresh
sleep 0.5
end
ensure
Ncurses.endwin
end
--
William <wmorgan-ruby-talk@masanjin.net>