jquast / blessed

Blessed is an easy, practical library for making python terminal apps

Home Page:http://pypi.python.org/pypi/blessed

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Screen buffering

Kodiologist opened this issue · comments

One of the things that's nice about curses is its buffer, and its algorithm for painting the buffer to the screen: it will only modify the parts of the screen that have actually changed. This considerably speeds up screen updates and reduces flickering.

I'm a beginner to blessed, so perhaps I'm missing something, but it looks like despite being a curses wrapper, blessed provides no interface to the curses buffer nor a substitute for it. The documentation examples print escape codes right to standard output, and the example worms.py seems to painstakingly redraw only the characters that are supposed to change each frame. This problem is presumably what led to e.g. this 2016 StackOverflow question complaining about flickering.

So, what's the right way to handle frequent screen updates in blessed? Intermix calls to Python's standard curses module? Implement your own buffer and screen-refreshing algorithm? Just clear the actual terminal as often as you want and hope that the user's terminal emulator is fast enough that no flickering is visible?

It is not a goal of blessed to provide an interface to curses features like the windows and buffers, and all of those functions like addch(), addstr(), waddch, waddstr(), mvaddstr(), and refresh(). If you wish to use them, then it is best to just directly use curses.

I totally understand your concern.

With careful programming there is no problem with flickering with blessed. You can see the examples in the bin/ folder, such as worms.py, x11_colorpicker, plasma.py that there doesn't appear to be any flickering. In worms.py, the "tail" of the worm is erased over while the "head" is drawn, there isn't any "redraw the entire screen every frame" there, and where there is, such as in plasma.py, simply take care to draw to the end of the screen, move position to (0,0), and draw over the screen again, this technique is also used in a silly "max headroom demo" running at telnet 1984.ws, a 24-bit full-color movie using unicode block characters in terminal graphics without flickering. I just avoid any clear_screen, clear_eol, clear_eos kind of sequences. I find the windowing interface of curses to be difficult and exhausting to program for, these demos were easier to program without them, and the curses interface directly uses stdin/stdout and can't be used in an ssh or telnet server, which is a problem that I originally worked on blessed to solve.

If somebody wrote a really nice replacement of the curses windowing interface without importing curses, I might accept it into the library if you're looking to include it.

where there is ["redraw the entire screen every frame"], such as in plasma.py, simply take care to draw to the end of the screen, move position to (0,0), and draw over the screen again

Interesting. I didn't realize this suffices. I also didn't appreciate that curses's buffer doesn't work with SSH. Thanks for the explanation.

No problem, I'm a big fan of your hylang project by the way, thanks for keeping up the great work!

Aww, thanks. Currently I have a game using Hy and blessed at a very early, pre-GitHub state of development.