Timer controlled process, influenced by "simultaneous" (decoupled)keyboard keypresses

J

John Reye

Hello,

how can one create a program, that runs some "timer controlled
process", which is influenced by keypresses?

Example:
============
The program reads a file like:
1.5 car
3.4 kitchen
10.7 fish

and then accordingly the program will :
* prints "car", waits for 1.5 seconds
* prints "kitchen", waits for 3.4 seconds
etc.

And while this is running, I want the user to be able to skip forward
or backwards by hitting the keyboard keys
* hit 'n' for next -- immediately print the next word
* hit 'p' for previous -- print the previous word (or the same word
again, if we're already on the first word)

===============

My questions:
1) can this be done is standard c, or will the code be platform-
specific? (I'm running Linux)
2) does one need threads, in order to handle the keypress-detection
running in parallel with the "timer controlled process", or can it be
done without threads?
3) Can one harness some interrupt mechanism (or related mechanism) to
solve this? E.g. can the keypresses be detected as interrupts in a
userland linux program?

Thanks for hints and your help.
Pointers to related code-snippets are welcome. :)

J.
 
J

John Reye

I just realized that I'm basically asking something like "how does one
realize tetris with keyboard control in C".
Right?
 
P

Prathamesh Kulkarni

Hello,



how can one create a program, that runs some "timer controlled

process", which is influenced by keypresses?



Example:

============

The program reads a file like:

1.5 car

3.4 kitchen

10.7 fish



and then accordingly the program will :

* prints "car", waits for 1.5 seconds

* prints "kitchen", waits for 3.4 seconds

etc.



And while this is running, I want the user to be able to skip forward

or backwards by hitting the keyboard keys

* hit 'n' for next -- immediately print the next word

* hit 'p' for previous -- print the previous word (or the same word

again, if we're already on the first word)



===============



My questions:

1) can this be done is standard c, or will the code be platform-

specific? (I'm running Linux)

2) does one need threads, in order to handle the keypress-detection

running in parallel with the "timer controlled process", or can it be

done without threads?

3) Can one harness some interrupt mechanism (or related mechanism) to

solve this? E.g. can the keypresses be detected as interrupts in a

userland linux program?



Thanks for hints and your help.

Pointers to related code-snippets are welcome. :)



J.

The timer part, can be done using ansi-c.
look at difftime(3) function:
http://linux.die.net/man/3/difftime

The keypress part would require platform dependent
library.
On linux, you could do it
using ncurses library:
http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/intro.html#WHATIS
 
E

Eric Sosman

Hello,

how can one create a program, that runs some "timer controlled
process", which is influenced by keypresses?

Example:
============
The program reads a file like:
1.5 car
3.4 kitchen
10.7 fish

and then accordingly the program will :
* prints "car", waits for 1.5 seconds
* prints "kitchen", waits for 3.4 seconds
etc.

And while this is running, I want the user to be able to skip forward
or backwards by hitting the keyboard keys
* hit 'n' for next -- immediately print the next word
* hit 'p' for previous -- print the previous word (or the same word
again, if we're already on the first word)

===============

My questions:
1) can this be done is standard c, or will the code be platform-
specific? (I'm running Linux)

I don't think it can be done at all in unaided C99 or before.
The I/O functions are all "blocking," in the sense that they don't
return until their operation finishes or fails. If you've called
a function to read a key and the next deadline arrives, too bad:
The function will just sit there waiting for a key, deadline be
damned. Meanwhile, the only Standard delay mechanism is to busy-
wait until a call to time() indicates that the deadline has arrived.

You might be able to do it in C11 with a pair of threads: One
would read keystrokes and add them to a queue, while the other
would drain the queue and act on the keystrokes. The magical bit
is that the consumer could use cnd_timedwait() instead of plain
cnd_wait(), with a timeout that awakens at the next deadline time
even if no keystrokes have appeared on the queue. (Even with C11
you're out of luck if __STDC_NO_THREADS__ is defined.)

In any version of C, you'll probably need platform-specific
magic to read an isolated keystroke without needing ENTER or the
equivalent. See the FAQ.

Also, the resolution of time() and of C11's struct timespec
are unspecified. In most implementations time() has a resolution
of one second, but as far as the Standard is concerned it might
have a resolution of forty fortnights. C11's struct timespec
can *express* a time in nanoseconds, but again: The resolution
actually achieved by the functions that use it is unspecified.
2) does one need threads, in order to handle the keypress-detection
running in parallel with the "timer controlled process", or can it be
done without threads?

I can't think of a way to do it in (semi-)Standard C without
using threads. If you're willing to use POSIX facilities, you can
do it without threads. See comp.unix.programmer for advice.
3) Can one harness some interrupt mechanism (or related mechanism) to
solve this? E.g. can the keypresses be detected as interrupts in a
userland linux program?

Not in Standard C. In POSIX, yes -- but there are easier ways.
 
P

Prathamesh Kulkarni

This is a stripped down version
of your program that only handles
the timer part:
http://pastebin.com/1ZRtnT2i

I have taken a few liberties:
1] I assume that the text that follows
the time does not contain whitespaces
and has a maximum of length 100
look at:
fscanf(fp, "%lf%100s", &wait_time, buf);


2] Used error() function present
in glibc, but not in ansi c.
 
P

Prathamesh Kulkarni

This is a stripped down version

of your program that only handles

the timer part:

http://pastebin.com/1ZRtnT2i



I have taken a few liberties:

1] I assume that the text that follows

the time does not contain whitespaces

and has a maximum of length 100

look at:

fscanf(fp, "%lf%100s", &wait_time, buf);





2] Used error() function present

in glibc, but not in ansi c.

I have slightly modified the code:
(added ferror() at end)
http://pastebin.com/dcpJ2fv5
 
A

Adam Wysocki

John Reye said:
1) can this be done is standard c, or will the code be platform-
specific? (I'm running Linux)
2) does one need threads, in order to handle the keypress-detection
running in parallel with the "timer controlled process", or can it be
done without threads?
3) Can one harness some interrupt mechanism (or related mechanism) to
solve this? E.g. can the keypresses be detected as interrupts in a
userland linux program?

Thanks for hints and your help.

Two ways came to my mind.

1. What latency do you accept? Maybe you can slice timeslots to slots of
maximum 50ms (example) and handle keys in between?

2. You can use select() to poll on fd 0 with a specified timeout. It is
platform-specific, but it will work.

In both ways you have to configure the terminal input (directly descriptor,
without using stdio), so it does not buffer the input. You can use stty raw
(and then stty cooked) or appropriate tcsetattr (disabling ICANON flag).

See this link:

http://stackoverflow.com/questions/1798511/how-to-avoid-press-enter-with-any-getchar
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,717
Messages
2,569,382
Members
44,705
Latest member
BerniePele

Latest Threads

Top