VincentFoulon80 / console_engine

A simple terminal framework to draw things and manage user input
https://crates.io/crates/console_engine
MIT License
220 stars 7 forks source link

Is it possible to stop the buffer from overflowing if you re-draw the entire screen? #25

Closed lesleyrs closed 1 year ago

lesleyrs commented 1 year ago

This is not directly about console_engine, but I'm trying to do something similar with just crossterm.

But I noticed that if I try to draw too much at once with queue, MoveTo and Print it will always immediately flush before it reaches the flush function.

I was looking at how you did it https://github.com/VincentFoulon80/console_engine/blob/d56ea01e9c6d026d612ad90fc3878faad7a270d0/src/lib.rs#L572

but the main difference is that you just try to avoid drawing as often for unchanged chars. Is that the only workaround for this, or are you doing something else that I missed?

VincentFoulon80 commented 1 year ago

I wasn't aware of this kind of issue, I originally tried to avoid overdrawing because printing chars is notoriously slow on most terminals (sometimes worse on Windows)

lesleyrs commented 1 year ago

Yea all I'm doing right now is just filling a full screen (actual screen) with dots which is a lot. I think it takes about 4 ms if I saw correctly (debug mode).

However speed is not my problem right now, I set the frame rate at 1 per second but because it immediately flushes if I draw more than a few rows it's just ignored and flushes instantly. Then whatever is drawn on top either flickers or doesn't show.

The part that I don't understand is that avoiding overdrawing can't be the fix to my problem as the FIRST frame in console_engine already loads the way it should.

In console_engine if you call: let mut engine = console_engine::ConsoleEngine::init(160, 45, 1).unwrap();

It draws the entire screen (for me anyway) after waiting the full 1 second which is correct.

But my behavior on a simple project is when I draw the full screen this way it just flushes instantly, no waiting unless I draw a tiny area. I think I'll keep looking into this.

https://docs.rs/crossterm/latest/crossterm/macro.queue.html

Queued commands must be flushed to the underlying device to be executed. This generally happens in the following cases:

When flush is called manually on the given type implementing io::Write.
The terminal will flush automatically if the buffer is full.
Each line is flushed in case of stdout, because it is line buffered.

Edit: I see you have another draw function that uses execute!, but not sure about the difference in usage between them.

lesleyrs commented 1 year ago

Ok some friendly guy in the crossterm discord helped me solve the problem. I had to replace: let mut stdout = stdout(); with let mut stdout = BufWriter::with_capacity(640000, stdout());

I guess the reason you didn't need to do this is because you are using screens as the buffer and that magically solves it? Problem solved anyway :D

VincentFoulon80 commented 1 year ago

Interesting to know though, thank you for reporting back !