jquast / blessed

Blessed is an easy, practical library for making python terminal apps
http://pypi.python.org/pypi/blessed
MIT License
1.18k stars 71 forks source link

An equivalent of `curses.flushinp` #254

Open Kodiologist opened 1 year ago

Kodiologist commented 1 year ago

I'm making good progress on a game using blessed, but I noticed that keys pressed while an animation is playing (i.e. during time.sleep) or during slow processing will be queued up for delivery by the next Terminal.inkey, instead of inkey blocking for a new key as intended. I can prevent this by calling curses.flushinp() before each inkey. Perhaps blessed should have an equivalent of flushinp, as its own method or as a parameter of inkey.

Kodiologist commented 1 year ago

Actually, termios.tcflush(sys.stdin, termios.TCIFLUSH) might be a better choice than curses.flushinp() if you don't already have curses initialized.

avylove commented 1 year ago

@jquast Any thoughts on this?

jquast commented 1 year ago

keys pressed while an animation is playing [...] will be queued up for delivery by the next Terminal.inkey, instead of inkey blocking for a new key as intended

I think we disagree, here! I think this default behavior is best :)

I can prevent this by calling curses.flushinp() before each inkey. Perhaps blessed should have an equivalent of flushinp, as its own method or as a parameter of inkey.

flushinp would be trivial to implement as a loop by calling Terminal.inkey(timeout=0):

import blessed, time

def flushinp(t):
        gathered = []
        while toss := t.inkey(timeout=0):
            gathered.append(toss)
        return gathered

t = blessed.Terminal()

print('Go ahead, type some input, Ill wait for 3 seconds')
with t.raw():
    time.sleep(3)
    gathered = flushinp(t)
    print("\r\nHere's what I flushed", gathered)
    print("\r\nNow... press any key to exit")
    t.inkey()

We could implement that as method Terminal.flushinp() (or as keyword argument flush=True to inkey, if you rather), if it is helpful to avoid importing curses. But I just wanted to show it is also very easy to do with the inkey method, using timeout=0 argument.

jquast commented 1 year ago

I really like the game, by the way !!!

Kodiologist commented 1 year ago

flushinp would be trivial to implement as a loop by calling Terminal.inkey(timeout=0)

Oh, cool. I didn't think of that. Thanks.

I think adding a flush = True would make sense and help other users, but I'm happy to use an inkey(timeout=0) loop for now.

I really like the game, by the way !!!

Glad to hear it! I hope to make the first playable release around the end of the month.