RawTextView Primitive? #88
Labels
No Label
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No Milestone
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: tslocum/cview#88
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
I've been wrestling with the performance of TextView for a few days. I'm working on a mud client and have a main window that scrolls the mud text which is originally rendered with ANSI color codes. These are translated when using tview/cview and as the main scroll buffer grows the application becomes extremely sluggish / unresponsive. I would really like to have a primitive that I can just pass the raw ANSI text to and that supports scrolling. Maybe I'm using the library wrong? Any advice is appreciated.
From what I can tell, ANSI escape sequences are not automatically converted into color tags (you must pass them through
ANSIWriter
orTranslateANSI
first). Because cview stores text as[]byte
, you should have noticed a performance gain when switching from tview.Will you please share a link to your source repository, or share a minimal example? I'm glad to take a closer look and do some profiling.
The repo is here: https://github.com/seandheath/go-mud-client
All of the cview code is in this file:
https://github.com/seandheath/go-mud-client/blob/cview/internal/tui/tui.go
The data is coming from the MUD here (ANSI encoded):
dceccaff1d/internal/client/connect.go (L77)
I create a window object and instantiate an ANSIWriter to the textview for each window. Every write passes through the ANSIWriter, check here:
dceccaff1d/internal/tui/tui.go (L119)
Everything works well but as the scroll buffer grows the UI gets very sluggish and eventually freezes ~1000 lines. I did some profiling with pprof and it's set up on localhost:6060 in main():
dceccaff1d/main.go (L39)
but nothing jumped out at me, the biggest processor consumers were regexes being run by cview. Same with tview. There was a big boost in performance on tview when I disabled regions and line wrapping, but still not where I want it to be. I'm working on an implementation with tcell directly so I can avoid all the color tag parsing.
Thanks, I will have a look when I have the time.
A possible workaround would be to handle the scrollback buffer yourself. You could create a struct which embeds a
*TextView
and overrides theMouseHandler
andInputHandler
methods (to facilitate internal scrolling). Instead of storing the entire buffer within theTextView
, only the currently visible portion would ever be stored within the widget at one time. This may or may not take less time than simply writing a tcell implementation.I tried something like that on tview. The best performance I have achieved was by storing all my MUD output into a long string and capturing the mouse/pageup handlers. When I detected a scroll up I would stop writing to the "main window" and print all of the content into the buffer and scroll around until I hit the bottom again and then go back into "live" mode. The only issue I had with that was that input was still coming in while I was scrolling and I didn't have a graceful way to append the input to the text of the TextView without bogging it down. Maybe I could just batch my writes to the TextView while scrolling and write once a second? I'll see if it works.
By long string do you mean an actual
string
variable? If so, storing text as[]byte
wherever possible will provide (at least slight) performance boosts, when that data must be shared/copied around the different areas of the program.I was using
string
but I'll switch to[]byte
and get the self-managed scroll buffer implemented and see how it goesI almost have this working.
Expected behaviour:
Main window max lines are set to
w.GetInnerRect()
height inside the appSetAfterResizeFunc
. Normal content scrolls without being cached in theTextView
buffer. I cache all[]bytes
in thewindow.content
buffer. If the user pressesPgUp
then we enter "scroll mode" and new content is not written to theTextView
until we leave "scroll mode" by scrolling to the bottom or pressingESC
.I'm restricting scrolling to PgUp and PgDn while I debug this. I call this function:
e3071f0948/internal/tui/tui.go (L116)
everything works perfectly the first time I scroll up. The second time I enter "scroll mode" the
TextView
starts at the very beginning/top of the content instead of the end. I've tried various combinations ofClear
,Write
,SetBytes
,ScrollToEnd
,ScrollTo
,t.app.Draw
, etc... but it always seems to jump all the way to the top every time I scroll up after the first time.I've taken a quick look.
GetBuffer
returns the number of lines in the text buffer, rather than the number of lines needed to display the content with word wrapping. This discrepancy might be part of the issue, I wanted to note it at least. Adding something likeGetInternalBufferSize
and some clarification to their docs might be needed.Will you confirm that the block inside the condition
if !w.scrolling && h <= trow {
does fire, and it is only theScrollToEnd
call which isn't having any effect?