From 09551a6e71eef2c65f78dfd1ba9cc9d261139c1a Mon Sep 17 00:00:00 2001 From: root Date: Thu, 5 May 2022 00:23:26 +0100 Subject: [PATCH] Scrolling performance improvement. Every time the user scrolls, DrawLine is called many times. Each time this happens, termbox.Flush is called, leading to unnecessary cpu usage. This is eliminated by only calling termbox.Flush at the end of all the DrawLine calls. --- screen.go | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/screen.go b/screen.go index 7909592..28c1dac 100644 --- a/screen.go +++ b/screen.go @@ -92,7 +92,7 @@ func (screen *Screen) ClearLine(x int, y int) *Screen { // Increase the offset for scrolling feature by n // Takes number of tickers as max, so not scrolling down forever func (screen *Screen) IncreaseOffset(n int, max int) { - if screen.offset+n+1 < max { + if screen.offset + n +1 < max { screen.offset += n } } @@ -142,6 +142,8 @@ func (screen *Screen) Draw(objects ...interface{}) *Screen { } } + termbox.Flush() + return screen } @@ -170,6 +172,31 @@ func (screen *Screen) DrawLine(x int, y int, str string) { termbox.Flush() } +// Identical to DrawLine, no flush at the end perhaps should be a part +// of DrawLine, with a flush parameter, or a wrapper function could be +// used +func (screen *Screen) DrawLineWithoutFlush(x int, y int, str string) { + start, column := 0, 0 + + for _, token := range screen.markup.Tokenize(str) { + // First check if it's a tag. Tags are eaten up and not displayed. + if screen.markup.IsTag(token) { + continue + } + + // Here comes the actual text: display it one character at a time. + for i, char := range token { + if !screen.markup.RightAligned { + start = x + column + column++ + } else { + start = screen.width - len(token) + i + } + termbox.SetCell(start, y, char, screen.markup.Foreground, screen.markup.Background) + } + } +} + // Underlying workhorse function that takes multiline string, splits it into // lines, and displays them row by row. func (screen *Screen) draw(str string, offset bool) { @@ -197,7 +224,7 @@ func (screen *Screen) draw(str string, offset bool) { strings.Contains(allLines[row], "Change") { drewHeading = true screen.headerLine = row - screen.DrawLine(0, row, allLines[row]) + screen.DrawLineWithoutFlush(0, row, allLines[row]) // move on to the point to offset to row += screen.offset } @@ -205,13 +232,13 @@ func (screen *Screen) draw(str string, offset bool) { // only write the necessary lines if row <= len(allLines) && row > screen.headerLine { - screen.DrawLine(0, row-screen.offset, allLines[row]) + screen.DrawLineWithoutFlush(0, row-screen.offset, allLines[row]) } else if row > len(allLines) { row = len(allLines) } } } else { - screen.DrawLine(0, row, allLines[row]) + screen.DrawLineWithoutFlush(0, row, allLines[row]) } } // If the quotes lines in this cycle are shorter than in the previous @@ -227,8 +254,10 @@ func (screen *Screen) draw(str string, offset bool) { // cycle. In that case, padding with blank lines would overwrite the // stocks list.) if drewHeading { - for i := len(allLines) - 1 - screen.offset; i < screen.height; i++ { - screen.DrawLine(0, i, blankLine) + for i := len(allLines) - 1 - screen.offset ; i < screen.height; i++ { + if i > screen.headerLine { + screen.DrawLine(0, i, blankLine) + } } } }