Loop Timing and Constant Input

A few quick questions:

How can I make a loop that runs at, say, 8Hz? That is, every 1/8 of a
second, it executes the loop. I could put a pause at the end of the loop
(what is the syntax for making the script wait a certain amount of time
before continuing?) but this is rather imprecise - I want the loop to take
1/8 of a second, including all processing time.

Secondly, how can I get input from the keyboard without the user pressing
enter? Say, the user is holding "R" and presses "K" while still holding down
"R". Can I get these key presses ("R"s, a "K", and more "R"s), dump them
into a buffer, sort out the unique ones (I know how to do this part) and
pass each of the unique key presses to the appropriate handlers?

Thanks,
Picklegnome

Picklegnome wrote:

A few quick questions:

How can I make a loop that runs at, say, 8Hz? That is, every 1/8 of a
second, it executes the loop. I could put a pause at the end of the loop
(what is the syntax for making the script wait a certain amount of time
before continuing?) but this is rather imprecise - I want the loop to take
1/8 of a second, including all processing time.

span = 1.0 / 8

99.times {
  start_time = Time.now
  print "."
  sleep span - (Time.now - start_time)
}

Secondly, how can I get input from the keyboard without the user pressing
enter?

"What should I feed my pet?" The answer would depend upon what
kind of pet you have.

"What sort of glue should I use to repair my broken chess piece?"
That may depend upon the material of which the piece is made.

For windoze:

require 'Win32API'
Kbhit = Win32API.new("msvcrt", "_kbhit", , 'I')
Getch = Win32API.new("msvcrt", "_getch", , 'I')
def get_key
  sleep 0.02
  return nil if Kbhit.call.zero?
  c = Getch.call
  c = Getch.call + 256 if c.zero? || c == 0xE0
  c
end

Picklegnome wrote:

how can I get input from the keyboard without the user pressing enter?

>
For a platform independent operation, I recently
began investigating "Curses":

   require 'curses'
   include Curses

operations to play with:
    clear -- clear the screen
    addstr -- append text to the buffer
    refresh -- display the text in the buffer
    getch -- get a character
               (compare to ?x, for example, to
                test for the letter "x")

I have a getting-started template, but neglected
to push it to the web. Ask me again tomorrow...

So far, I've found two problems with curses:

   a) There doesn't seem to be any equivalent for the
      windows Kbhit. That's the nice little operation
      that lets you ask whether there is a character
      in the buffer, and proceed if there isn't any.

   b) Examining the Curses API at
      RDoc Documentation, I found what
      can only be described as an embarassing lack of
      commentary. Not even one word! And since it's
      a wrapper, the implementation code is of no help.
      (And curses isn't even mentioned here:
      http://www.rubymanual.org/list/classes\)

      I can only assume that some form of standard
      operational documentation exists on the web.
      If so the API doc should point to it, at least.
      (It's difficult to find, assuming it exists,
      because of all the references to NCURSES. That
      seems to be good, but the APIs are a wrapper
      for an ncurses.lib, which raises the ugly spectre
      of installation issues in my non-standard
      location. When I tried that with htree, I got
      horrible ".so" not found errors that no one
      could help with--so I abandoned htree for another
      day.)

Searching on "curses API", I did find these papers:

Curses in Python

Tutorial on Python Curses Programming

On my solaris box there is also man page for curses,
but it lists dozens of APIs that aren't in the ruby library--and to find out what they do, you have to look
them up individually.

Still, *nix users have a way to find out what the
APIs are expected to do. Windows users are SOL, unless
someone can point me to a good man-page => html conversion
tool. (The utility I wrote goes in the other direction,
unfortunately.)

I, too, have been looking into Curses. And I agree with what you say about the difficulty in finding reliable tutorials and documentation.

  b) Examining the Curses API at
     RDoc Documentation, I found what
     can only be described as an embarrassing lack of
     commentary. Not even one word! And since it's
     a wrapper, the implementation code is of no help.
     (And curses isn't even mentioned here:
     http://www.rubymanual.org/list/classes\)

I have issues with this web documentation. I'm using ruby 1.8.2 on OS X and what I see returned from

    Curses.methods(false).sort
    Curses::Window.instance_methods(false).sort

is not the same as the methods described on the ruby-doc site. I don't know if the web documentation describes a newer or an older version than the one I'm using, but it certainly describes a different version.

On my solaris box there is also man page for curses, but it lists
dozens of APIs that aren't in the ruby library--and to find out
what they do, you have to look them up individually.

You can always use multiple terminal windows or emacs to view multiple man pages simultaneously.
Emacs lets you save or print formatted man pages for future reference. On OS X, XCode converts man pages to good-looking HTML.

Regards, Morton

···

On Jul 31, 2006, at 11:51 PM, Eric Armstrong wrote:

Would the standard io/wait library work for this? It adds a ready?() method to IO objects.

James Edward Gray II

···

On Jul 31, 2006, at 10:51 PM, Eric Armstrong wrote:

  a) There doesn't seem to be any equivalent for the
     windows Kbhit. That's the nice little operation
     that lets you ask whether there is a character
     in the buffer, and proceed if there isn't any.

Eric Armstrong wrote:

Picklegnome wrote:

how can I get input from the keyboard without the user pressing enter?

>
For a platform independent operation, I recently
began investigating "Curses":

  require 'curses'
  include Curses

operations to play with:
   clear -- clear the screen
   addstr -- append text to the buffer
   refresh -- display the text in the buffer
   getch -- get a character
              (compare to ?x, for example, to
               test for the letter "x")

I have a getting-started template, but neglected
to push it to the web. Ask me again tomorrow...

So far, I've found two problems with curses:

  a) There doesn't seem to be any equivalent for the
     windows Kbhit. That's the nice little operation
     that lets you ask whether there is a character
     in the buffer, and proceed if there isn't any.

  b) Examining the Curses API at
     RDoc Documentation, I found what
     can only be described as an embarassing lack of
     commentary. Not even one word! And since it's
     a wrapper, the implementation code is of no help.
     (And curses isn't even mentioned here:
     http://www.rubymanual.org/list/classes\)

     I can only assume that some form of standard
     operational documentation exists on the web.
     If so the API doc should point to it, at least.
     (It's difficult to find, assuming it exists,
     because of all the references to NCURSES. That
     seems to be good, but the APIs are a wrapper
     for an ncurses.lib, which raises the ugly spectre
     of installation issues in my non-standard
     location. When I tried that with htree, I got
     horrible ".so" not found errors that no one
     could help with--so I abandoned htree for another
     day.)

Searching on "curses API", I did find these papers:

O'Reilly published "Programming with curses" in 1991 if you can find a copy of the book.

···

Curses in Python
ActiveState Community - Boosting coder and team productivity with ready-to-use open source languages and tools.

Tutorial on Python Curses Programming
http://heather.cs.ucdavis.edu/~matloff/Python/PyCurses.pdf

On my solaris box there is also man page for curses,
but it lists dozens of APIs that aren't in the ruby library--and to find out what they do, you have to look
them up individually.

Still, *nix users have a way to find out what the
APIs are expected to do. Windows users are SOL, unless
someone can point me to a good man-page => html conversion
tool. (The utility I wrote goes in the other direction,
unfortunately.)

James Edward Gray II wrote:

  a) There doesn't seem to be any equivalent for the
     windows Kbhit. That's the nice little operation
     that lets you ask whether there is a character
     in the buffer, and proceed if there isn't any.

Would the standard io/wait library work for this?

> It adds a ready?() method to IO objects.

ooohhhh. Dude! You're giving me chills!

Found the API docs here:
http://stdlib.rubyonrails.org/libdoc/io/wait/rdoc/index.html

What do I do to use it? This:

   require 'io/wait'

Or is it something like this:

   require 'io/wait/lib/nonblock'

Once I get the require clause right, that adds
the methods to the IO class.

Then it's a matter of figuring out how to use it
with Curses. I suppose I can do this:

   if $stdin.ready? then
      c = stdscr.getch
      ...

Yes?

And speaking of curses...

I found this nicely formatted rdoc site in New Zealand:
http://www.cs.auckland.ac.nz/references/ruby/stdlib/libdoc/curses/rdoc/

The fascinating thing is, it mentions about twice as
many APIs as the standard site: RDoc Documentation

The NZ TOC page says it was generated in Summer of 2004,
so it's doubtful that it's for 1.9 (unless the date is
wrong).

I wonder what's going on?

···

On Jul 31, 2006, at 10:51 PM, Eric Armstrong wrote:

$stdin.eof? == maybe

fyi.

-a

···

On Wed, 2 Aug 2006, Eric Armstrong wrote:

if $stdin.ready? then

--
we can never obtain peace in the outer world until we make peace with
ourselves.
- h.h. the 14th dali lama

James Edward Gray II wrote:

  a) There doesn't seem to be any equivalent for the
     windows Kbhit. That's the nice little operation
     that lets you ask whether there is a character
     in the buffer, and proceed if there isn't any.

Would the standard io/wait library work for this?

> It adds a ready?() method to IO objects.
ooohhhh. Dude! You're giving me chills!

Found the API docs here:
http://stdlib.rubyonrails.org/libdoc/io/wait/rdoc/index.html

What do I do to use it? This:

  require 'io/wait'

That's the one, yes.

Once I get the require clause right, that adds
the methods to the IO class.

Then it's a matter of figuring out how to use it
with Curses. I suppose I can do this:

  if $stdin.ready? then
     c = stdscr.getch
     ...

Yes?

I would think so, though I have never used curses.

James Edward Gray II

···

On Aug 1, 2006, at 4:51 PM, Eric Armstrong wrote:

On Jul 31, 2006, at 10:51 PM, Eric Armstrong wrote: