From 95552235594b15d74922e606d2a3c54f7e05224a Mon Sep 17 00:00:00 2001 From: Benjamin Chausse Date: Fri, 12 Jul 2024 10:37:24 -0400 Subject: nil pointer management --- internal/pacman/pacman.go | 11 +++-- internal/render/instructions.go | 8 +++- internal/render/instructions_test.go | 85 +++++++++++++++++++++++------------- internal/render/renderer.go | 14 ++++-- main.go | 4 ++ 5 files changed, 84 insertions(+), 38 deletions(-) diff --git a/internal/pacman/pacman.go b/internal/pacman/pacman.go index cb663af..8972d12 100644 --- a/internal/pacman/pacman.go +++ b/internal/pacman/pacman.go @@ -40,9 +40,10 @@ func (p *Pacman) blink() { func (p *Pacman) drawInstruction() render.DrawInstruction { return render.DrawInstruction{ - X: int(p.x), - Y: int(p.y), - Content: p.Icon(), + X: int(p.x), + Y: int(p.y), + Content: p.Icon(), + Decorators: []string{"\033[38;2;250;249;8m"}, } } @@ -86,6 +87,10 @@ func (p *Pacman) Redirect(dir Direction) { func (p *Pacman) Icon() string { icns := map[Direction]map[bool]string{ + // UP: {true: "V", false: "v"}, + // DOWN: {true: "^", false: "A"}, + // RIGHT: {true: "{", false: "<"}, + // LEFT: {true: "}", false: ">"}, UP: {true: "", false: "󰬧"}, DOWN: {true: "", false: "󰬭"}, LEFT: {true: "", false: "󰬫"}, diff --git a/internal/render/instructions.go b/internal/render/instructions.go index b4823f2..27db5bd 100644 --- a/internal/render/instructions.go +++ b/internal/render/instructions.go @@ -35,6 +35,9 @@ type Instruction interface { } func overlap(over, under Instruction) overlapType { + if over == nil || under == nil { + return CoverNone + } ox, oy := over.Pos() ux, uy := under.Pos() os, us := over.Len(), under.Len() @@ -78,6 +81,9 @@ func overlap(over, under Instruction) overlapType { // No matter what, the over instruction never changes so only variations of // under needs to be returned. func squash(over Instruction, under Instruction, ot overlapType) []Instruction { + if over == nil || under == nil { + return nil + } ox, _ := over.Pos() ux, _ := under.Pos() os, us := over.Len(), under.Len() @@ -174,7 +180,7 @@ type ClearInstruction struct { func (c ClearInstruction) Write(w io.Writer) { // Erase as many characters as the size of the instruction. - msg := reach(c) + "\033[K" + strings.Repeat(" ", c.Size) + msg := reach(c) + "\033[0m" + strings.Repeat(" ", c.Size) // TODO: maybe implement a way to log stuff like writestring errors io.WriteString(w, msg) } diff --git a/internal/render/instructions_test.go b/internal/render/instructions_test.go index 837a143..b62320d 100644 --- a/internal/render/instructions_test.go +++ b/internal/render/instructions_test.go @@ -1,6 +1,7 @@ package render import ( + "bytes" "testing" ) @@ -9,63 +10,73 @@ const ( passFmt = "Passed: '%v'\n" ) -type testTrim struct { - title string - input Instruction - expectedReach string - n int // number of characters to trim - d trimDir // FROM which side to trim - expected Instruction +type testTrimWrite struct { + title string + input Instruction + n int // number of characters to trim + d trimDir // FROM which side to trim + expectedTrim Instruction + expectedBuf string } -var TrimCases []testTrim = []testTrim{ +var TrimWriteCases []testTrimWrite = []testTrimWrite{ { - "Trim 2 characters from the left", + "Trim 2 characters from left", DrawInstruction{X: 5, Y: 5, Content: "hello"}, - "\033[5;5H", 2, TrimLeft, DrawInstruction{X: 7, Y: 5, Content: "llo"}, + "\033[5;5Hhello", }, { - "Trim 2 characters from the right", - DrawInstruction{X: 43, Y: 6, Content: "hello"}, - "\033[6;43H", + "Trim 2 characters from the right of a bold Draw", + DrawInstruction{ + X: 43, + Y: 6, + Content: "hello", + Decorators: []string{"\033[1m"}, + }, 2, TrimRight, DrawInstruction{X: 43, Y: 6, Content: "hel"}, + "\033[6;43H\033[1mhello", }, { "Trim 2 characters from the left of a Clear", ClearInstruction{X: 8, Y: 4, Size: 5}, - "\033[4;8H", 2, TrimLeft, ClearInstruction{X: 10, Y: 4, Size: 3}, + "\033[4;8H\033[0m ", }, { "Trim 2 characters from the right of a Clear", ClearInstruction{X: 98, Y: 76, Size: 5}, - "\033[76;98H", 2, TrimRight, ClearInstruction{X: 98, Y: 76, Size: 3}, + "\033[76;98H\033[0m ", }, { "Trim 10 characters from the left of a Clear of size 5", ClearInstruction{X: 42, Y: 69, Size: 5}, - "\033[69;42H", 10, TrimLeft, nil, + "\033[69;42H\033[0m ", }, { - "Trim 10 characters from the right of a Draw of size 5", - DrawInstruction{X: 420, Y: 1337, Content: "hello"}, - "\033[1337;420H", + "Trim 10 characters from the right of a Colored Draw of size 5", + DrawInstruction{ + X: 420, + Y: 1337, + Content: "hello", + Decorators: []string{"\033[38;2;12;34;56m", "\033[48;2;98;76;54m"}, + }, 10, TrimRight, nil, + "\033[1337;420H\033[38;2;12;34;56m\033[48;2;98;76;54mhello", }, } @@ -144,6 +155,17 @@ var OverlapCases []testOverlap = []testOverlap{ }, }, + { + "Clear split in half by a single character", + DrawInstruction{X: 8, Y: 8, Content: "X"}, + ClearInstruction{X: 0, Y: 8, Size: 17}, + CoverWithin, + []Instruction{ + ClearInstruction{X: 0, Y: 8, Size: 8}, + ClearInstruction{X: 9, Y: 8, Size: 8}, + }, + }, + { "Two Draws that don't overlap but are on the same row", DrawInstruction{X: 5, Y: 5, Content: "hello"}, @@ -211,19 +233,10 @@ func InstructionEquals(a, b Instruction) bool { } func TestTrim(t *testing.T) { - for _, tc := range TrimCases { + for _, tc := range TrimWriteCases { result := tc.input.Trim(tc.n, tc.d) - if !InstructionEquals(result, tc.expected) { - t.Errorf(errFmt, tc.title, tc.expected, result) - } - t.Logf(passFmt, tc.title) - } -} - -func TestReach(t *testing.T) { - for _, tc := range TrimCases { - if r := reach(tc.input); r != tc.expectedReach { - t.Errorf(errFmt, tc.title, tc.expectedReach, r) + if !InstructionEquals(result, tc.expectedTrim) { + t.Errorf(errFmt, tc.title, tc.expectedTrim, result) } t.Logf(passFmt, tc.title) } @@ -252,3 +265,13 @@ func TestSquash(t *testing.T) { t.Logf(passFmt, tc.title) } } + +func TestWrite(t *testing.T) { + for _, tt := range TrimWriteCases { + var buf bytes.Buffer + tt.input.Write(&buf) + if buf.String() != tt.expectedBuf { + t.Errorf(errFmt, tt.title, tt.expectedBuf, buf.String()) + } + } +} diff --git a/internal/render/renderer.go b/internal/render/renderer.go index 265c3ab..088134a 100644 --- a/internal/render/renderer.go +++ b/internal/render/renderer.go @@ -126,6 +126,7 @@ func (r *Renderer) DrawFrame() { // Create buffers drwBuf := r.bufferize(r.drwStack) clrBuf := r.bufferize(r.clrStack) + var stack []Instruction // fmt.Println(len(drwBuf)) // fmt.Println(len(clrBuf)) // squash overlapping clear instructions @@ -164,10 +165,17 @@ func (r *Renderer) DrawFrame() { } } // Draw + for _, clr := range clrBuf { + if clr != nil { + stack = append(stack, clr) + } + } for _, drw := range drwBuf { - drw.Write(r.stream) + if drw != nil { + stack = append(stack, drw) + } } - for _, clr := range clrBuf { - clr.Write(r.stream) + for _, inst := range stack { + inst.Write(r.stream) } } diff --git a/main.go b/main.go index fb2aada..64ee0a6 100644 --- a/main.go +++ b/main.go @@ -16,4 +16,8 @@ func main() { time.Sleep(5 * time.Second) pm.Redirect(pacman.DOWN) time.Sleep(5 * time.Second) + pm.Redirect(pacman.LEFT) + time.Sleep(3 * time.Second) + pm.Redirect(pacman.UP) + time.Sleep(3 * time.Second) } -- cgit v1.2.3