Use a byte buffer for textBuf

This commit is contained in:
bloeys
2022-07-16 21:01:29 +04:00
parent 3fb4ce4c06
commit 6f1fc396cb

68
main.go
View File

@ -10,6 +10,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"time" "time"
"unicode/utf8"
"github.com/bloeys/gglm/gglm" "github.com/bloeys/gglm/gglm"
"github.com/bloeys/nmage/engine" "github.com/bloeys/nmage/engine"
@ -55,7 +56,7 @@ type program struct {
gridMesh *meshes.Mesh gridMesh *meshes.Mesh
gridMat *materials.Material gridMat *materials.Material
textBuf *ring.Buffer[rune] textBuf *ring.Buffer[byte]
cmdBuf []rune cmdBuf []rune
cmdBufLen int64 cmdBufLen int64
@ -97,6 +98,11 @@ var (
func main() { func main() {
// x := `Hi \x1b[31Hello \x1b[31mthere`
// beforeArr, code, afterArr := nextAnsiCode([]rune(x))
// fmt.Printf("x=%s; beforeArr=%s; code=%s; afterArr=%s\n", x, string(beforeArr), string(code), string(afterArr))
// return
err := engine.Init() err := engine.Init()
if err != nil { if err != nil {
panic("Failed to init engine. Err: " + err.Error()) panic("Failed to init engine. Err: " + err.Error())
@ -116,7 +122,7 @@ func main() {
imguiInfo: nmageimgui.NewImGUI(), imguiInfo: nmageimgui.NewImGUI(),
FontSize: 40, FontSize: 40,
textBuf: ring.NewBuffer[rune](defaultTextBufSize), textBuf: ring.NewBuffer[byte](defaultTextBufSize),
cursorCharIndex: 0, cursorCharIndex: 0,
lastCmdCharPos: gglm.NewVec3(0, 0, 0), lastCmdCharPos: gglm.NewVec3(0, 0, 0),
@ -231,7 +237,7 @@ func (p *program) Update() {
} }
// @TODO: These probably need a mutex // @TODO: These probably need a mutex
func (p *program) WriteToTextBuf(text []rune) { func (p *program) WriteToTextBuf(text []byte) {
p.textBuf.Write(text...) p.textBuf.Write(text...)
p.scrollPos = clamp(p.textBuf.Len-p.maxCharsToShow, 0, p.textBuf.Len-1) p.scrollPos = clamp(p.textBuf.Len-p.maxCharsToShow, 0, p.textBuf.Len-1)
} }
@ -295,14 +301,14 @@ func (p *program) MainUpdate() {
from := clamp(p.scrollPos, 0, int64(len(v1)-1)) from := clamp(p.scrollPos, 0, int64(len(v1)-1))
to := clamp(p.scrollPos+p.maxCharsToShow, 0, int64(len(v1)-1)) to := clamp(p.scrollPos+p.maxCharsToShow, 0, int64(len(v1)-1))
p.lastCmdCharPos.Data = p.DrawTextAnsiCodes(v1[from:to], *gglm.NewVec3(0, float32(p.GlyphRend.ScreenHeight)-p.GlyphRend.Atlas.LineHeight, 0)).Data p.lastCmdCharPos.Data = p.DrawTextAnsiCodes(bytesToRunes(v1[from:to]), *gglm.NewVec3(0, float32(p.GlyphRend.ScreenHeight)-p.GlyphRend.Atlas.LineHeight, 0)).Data
// p.lastCmdCharPos.Data = p.GlyphRend.DrawTextOpenGLAbs(v1[from:to], gglm.NewVec3(0, float32(p.GlyphRend.ScreenHeight)-p.GlyphRend.Atlas.LineHeight, 0), &p.Settings.DefaultColor).Data // p.lastCmdCharPos.Data = p.GlyphRend.DrawTextOpenGLAbs(v1[from:to], gglm.NewVec3(0, float32(p.GlyphRend.ScreenHeight)-p.GlyphRend.Atlas.LineHeight, 0), &p.Settings.DefaultColor).Data
if p.scrollPos >= int64(len(v1)) { if p.scrollPos >= int64(len(v1)) {
from := clamp(p.scrollPos-int64(len(v1)), 0, int64(len(v2)-1)) from := clamp(p.scrollPos-int64(len(v1)), 0, int64(len(v2)-1))
to := clamp(p.scrollPos+p.maxCharsToShow, 0, int64(len(v2)-1)) to := clamp(p.scrollPos+p.maxCharsToShow, 0, int64(len(v2)-1))
p.lastCmdCharPos.Data = p.DrawTextAnsiCodes(v2[from:to], *p.lastCmdCharPos).Data p.lastCmdCharPos.Data = p.DrawTextAnsiCodes(bytesToRunes(v2[from:to]), *p.lastCmdCharPos).Data
} }
sepLinePos.Data = p.lastCmdCharPos.Data sepLinePos.Data = p.lastCmdCharPos.Data
@ -313,6 +319,29 @@ func (p *program) MainUpdate() {
p.lastCmdCharPos.Data = p.SyntaxHighlightAndDraw(p.cmdBuf[:p.cmdBufLen], *p.lastCmdCharPos).Data p.lastCmdCharPos.Data = p.SyntaxHighlightAndDraw(p.cmdBuf[:p.cmdBufLen], *p.lastCmdCharPos).Data
} }
func bytesToRunes(b []byte) []rune {
runeCount := utf8.RuneCount(b)
if runeCount == 0 {
return []rune{}
}
// @PERF We should use a pre-allocated buffer here
out := make([]rune, 0, runeCount)
for {
r, size := utf8.DecodeRune(b)
if r == utf8.RuneError {
break
}
out = append(out, r)
b = b[size:]
}
return out
}
const ( const (
Ansi_Fg_Black = 30 Ansi_Fg_Black = 30
Ansi_Fg_Red = 31 Ansi_Fg_Red = 31
@ -576,7 +605,8 @@ func (p *program) HandleReturn() {
return return
} }
p.WriteToTextBuf(cmdRunes) // @PERF
p.WriteToTextBuf([]byte(string(cmdRunes)))
cmdStr := strings.TrimSpace(string(cmdRunes)) cmdStr := strings.TrimSpace(string(cmdRunes))
cmdSplit := strings.Split(cmdStr, " ") cmdSplit := strings.Split(cmdStr, " ")
@ -689,7 +719,7 @@ func (p *program) ClearActiveCmd() {
} }
func (p *program) PrintToTextBuf(s string) { func (p *program) PrintToTextBuf(s string) {
p.WriteToTextBuf([]rune(s)) p.WriteToTextBuf([]byte(s))
} }
func (p *program) DrawCursor() { func (p *program) DrawCursor() {
@ -758,19 +788,21 @@ func (p *program) DebugRender() {
p.DrawGrid() p.DrawGrid()
} }
str := textToShow if len(textToShow) > 0 {
charCount := len([]rune(str)) str := textToShow
fps := int(timing.GetAvgFPS()) charCount := len([]rune(str))
if drawManyLines { fps := int(timing.GetAvgFPS())
const charsPerFrame = 500_000 if drawManyLines {
for i := 0; i < charsPerFrame/charCount; i++ { const charsPerFrame = 500_000
for i := 0; i < charsPerFrame/charCount; i++ {
p.GlyphRend.DrawTextOpenGLAbsString(str, gglm.NewVec3(xOff, float32(p.GlyphRend.Atlas.LineHeight)*5+yOff, 0), &p.Settings.DefaultColor)
}
p.win.SDLWin.SetTitle(fmt.Sprint("FPS: ", fps, " Draws/f: ", math.Ceil(charsPerFrame/glyphs.MaxGlyphsPerBatch), " chars/f: ", charsPerFrame, " chars/s: ", fps*charsPerFrame))
} else {
charsPerFrame := float64(charCount)
p.GlyphRend.DrawTextOpenGLAbsString(str, gglm.NewVec3(xOff, float32(p.GlyphRend.Atlas.LineHeight)*5+yOff, 0), &p.Settings.DefaultColor) p.GlyphRend.DrawTextOpenGLAbsString(str, gglm.NewVec3(xOff, float32(p.GlyphRend.Atlas.LineHeight)*5+yOff, 0), &p.Settings.DefaultColor)
p.win.SDLWin.SetTitle(fmt.Sprint("FPS: ", fps, " Draws/f: ", math.Ceil(charsPerFrame/glyphs.MaxGlyphsPerBatch), " chars/f: ", int(charsPerFrame), " chars/s: ", fps*int(charsPerFrame)))
} }
p.win.SDLWin.SetTitle(fmt.Sprint("FPS: ", fps, " Draws/f: ", math.Ceil(charsPerFrame/glyphs.MaxGlyphsPerBatch), " chars/f: ", charsPerFrame, " chars/s: ", fps*charsPerFrame))
} else {
charsPerFrame := float64(charCount)
p.GlyphRend.DrawTextOpenGLAbsString(str, gglm.NewVec3(xOff, float32(p.GlyphRend.Atlas.LineHeight)*5+yOff, 0), &p.Settings.DefaultColor)
p.win.SDLWin.SetTitle(fmt.Sprint("FPS: ", fps, " Draws/f: ", math.Ceil(charsPerFrame/glyphs.MaxGlyphsPerBatch), " chars/f: ", int(charsPerFrame), " chars/s: ", fps*int(charsPerFrame)))
} }
} }