Skip to content

Commit

Permalink
refactor: better way of rendering cells
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabriel Musat committed Dec 26, 2022
1 parent 205c854 commit d802f6a
Show file tree
Hide file tree
Showing 12 changed files with 258 additions and 215 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
Expand Down
6 changes: 3 additions & 3 deletions internal/board/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ func (b *Block) Render(matrix *graphics.Matrix) error {
char := rune(b.Label[idIndex])
if char != ' ' {
cell.PlaceChar(char).
Tag(cellType, blockChar).
Tags(b.Tags)
WithTag(cellType, blockChar).
WithTags(b.Tags)
} else {
cell.PlaceEmpty().
Tag(cellType, blockSpace)
WithTag(cellType, blockSpace)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions internal/board/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ func (c *Connector) Render(matrix *graphics.Matrix) error {
cell = matrix.Cell(cur)
if cell != nil {
cell.PlaceArrow(reverseX).
Tag(cellType, arrow).
Tags(c.tags)
WithTag(cellType, arrow).
WithTags(c.tags)
}
return nil
}
Expand Down
111 changes: 55 additions & 56 deletions internal/board/graphics/cell.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,80 +2,79 @@ package graphics

import "dep-tree/internal/utils"

const (
charCell = iota
linesCell
arrowCell
emptyCell
)
type Cell interface {
IsCell() bool
}

type LinesCell struct {
l bool
t bool
r bool
b bool
}

func (l *LinesCell) IsCell() bool {
return true
}

type CharCell rune

type Lines struct {
l bool
t bool
r bool
b bool
cross bool
func (c CharCell) IsCell() bool {
return true
}

type Cell struct {
t int
char rune
lines Lines
arrowInverted bool
type ArrowCell bool

func (c ArrowCell) IsCell() bool {
return true
}

type EmptyCell bool

func (c EmptyCell) IsCell() bool {
return true
}

type TaggedCell struct {
Cell
tags map[string]string
}

func (c *Cell) Tags(tags map[string]string) *Cell {
if c.tags == nil {
c.tags = tags
func NewTaggedCell(cell Cell) *TaggedCell {
switch t := cell.(type) {
case *TaggedCell:
return t
default:
return &TaggedCell{
Cell: cell,
}
}
}

func (tc *TaggedCell) WithTags(tags map[string]string) *TaggedCell {
if tc.tags == nil {
tc.tags = tags
} else {
utils.Merge(c.tags, tags)
utils.Merge(tc.tags, tags)
}
return c
return tc
}

func (c *Cell) Tag(key string, value string) *Cell {
if c.tags == nil {
c.tags = map[string]string{key: value}
func (tc *TaggedCell) WithTag(key string, value string) *TaggedCell {
if tc.tags == nil {
tc.tags = map[string]string{key: value}
} else {
c.tags[key] = value
tc.tags[key] = value
}
return c
return tc
}

func (c *Cell) Is(key string, value string) bool {
if c.tags == nil {
func (tc *TaggedCell) Is(key string, value string) bool {
if tc.tags == nil {
return false
} else if v, ok := c.tags[key]; ok {
} else if v, ok := tc.tags[key]; ok {
return value == v
} else {
return false
}
}

func LinesCell(lines Lines) *Cell {
return &Cell{
t: linesCell,
lines: lines,
}
}

func (c *Cell) mergeLines(lines Lines) {
if lines.l {
c.lines.l = true
}
if lines.t {
c.lines.t = true
}
if lines.r {
c.lines.r = true
}
if lines.b {
c.lines.b = true
}
// NOTE: there is probably a better way of handling crossed lines.
if (c.lines.t || c.lines.b) && (c.lines.r || c.lines.l) {
c.lines.cross = true
}
}
37 changes: 7 additions & 30 deletions internal/board/graphics/cell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,18 @@ import (
"github.com/stretchr/testify/require"
)

func TestCell_mergeLines(t *testing.T) {
func TestCell_WithTag(t *testing.T) {
a := require.New(t)
cell := LinesCell(Lines{
t: true,
})
cell.mergeLines(Lines{
b: true,
})
a.Equal(cell.lines.l, false)
a.Equal(cell.lines.t, true)
a.Equal(cell.lines.r, false)
a.Equal(cell.lines.b, true)
a.Equal(cell.lines.cross, false)

cell.mergeLines(Lines{
l: true,
})

a.Equal(cell.lines.l, true)
a.Equal(cell.lines.t, true)
a.Equal(cell.lines.r, false)
a.Equal(cell.lines.b, true)
a.Equal(cell.lines.cross, true)
}

func TestCell_Tag(t *testing.T) {
a := require.New(t)
c := Cell{}
c := TaggedCell{}

a.Equal(false, c.Is("key", "foo"))
c.Tag("key", "bar")
c.WithTag("key", "bar")
a.Equal(false, c.Is("key", "foo"))
a.Equal(true, c.Is("key", "bar"))
c.Tag("key", "foo")
c.Tag("otherKey", "bar")
c.WithTags(map[string]string{
"key": "foo",
"otherKey": "bar",
})
a.Equal(true, c.Is("key", "foo"))
a.Equal(true, c.Is("otherKey", "bar"))
}
88 changes: 88 additions & 0 deletions internal/board/graphics/lines.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package graphics

var lineCharMap = map[int]rune{
0b_0000: ' ',
0b_0001: '╷',
0b_0010: '╶',
0b_0011: '┌',
0b_0100: '╵',
0b_0101: '│',
0b_0110: '└',
0b_0111: '├',
0b_1000: '╴',
0b_1001: '┐',
0b_1010: '─',
0b_1011: '┬',
0b_1100: '┘',
0b_1101: '┤',
0b_1110: '┴',
0b_1111: '┼',
}

func hashLines(lines *LinesCell) int {
result := 0b_0000
if lines == nil {
return result
}
if lines.l {
result += 0b_1000
}
if lines.t {
result += 0b_0100
}
if lines.r {
result += 0b_0010
}
if lines.b {
result += 0b_0001
}
return result
}

type LineStack []*LinesCell

func (l *LineStack) add(cell *LinesCell) {
*l = append(*l, cell)
}

func areCrossing(first *LinesCell, last *LinesCell) bool {
if first != nil && last != nil {
if last.l && last.r && !last.t && !last.b {
if !first.l && !first.r && first.t && first.b {
// lines have crossed.
return true
}
} else if !last.l && !last.r && last.t && last.b {
if first.l && first.r && !first.t && !first.b {
// lines have crossed.
return true
}
}
}
return false
}

func (l *LineStack) Render() rune {
acc := LinesCell{}
var prev *LinesCell
for _, cell := range *l {
// TODO: honestly, there should be a more elegant way of handling crossed lines.
if areCrossing(prev, cell) {
acc = LinesCell{}
}
if cell.l {
acc.l = true
}
if cell.t {
acc.t = true
}
if cell.r {
acc.r = true
}
if cell.b {
acc.b = true
}
prev = cell
}
return lineCharMap[hashLines(&acc)]
}
38 changes: 38 additions & 0 deletions internal/board/graphics/lines_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package graphics

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestLineStack_Render(t *testing.T) {
a := require.New(t)
lineStack := LineStack{}
lineStack.add(&LinesCell{t: true, b: true})
a.Equal('│', lineStack.Render())
lineStack.add(&LinesCell{b: true})
a.Equal('│', lineStack.Render())
lineStack.add(&LinesCell{l: true})
a.Equal('┤', lineStack.Render())
}

func TestLineStack_Render_Crossed(t *testing.T) {
a := require.New(t)
lineStack := LineStack{}
lineStack.add(&LinesCell{t: true, b: true})
lineStack.add(&LinesCell{l: true, r: true})
a.Equal('─', lineStack.Render())
lineStack.add(&LinesCell{t: true, b: true})
a.Equal('│', lineStack.Render())
}

func TestLineStack_Render_Crossed_2(t *testing.T) {
a := require.New(t)
lineStack := LineStack{}
lineStack.add(&LinesCell{t: true, r: true})
lineStack.add(&LinesCell{l: true, r: true})
a.Equal('┴', lineStack.Render())
lineStack.add(&LinesCell{t: true, b: true})
a.Equal('┼', lineStack.Render())
}
6 changes: 3 additions & 3 deletions internal/board/graphics/matrix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ func TestMatrix_RayCastVertical(t *testing.T) {
tag1Y := 9
tag2Y := 7

matrix.Cell(utils.Vec(x, tag1Y)).PlaceEmpty().Tag(testKey, tag1)
matrix.Cell(utils.Vec(x, tag2Y)).PlaceEmpty().Tag(testKey, tag2)
matrix.Cell(utils.Vec(x, tag1Y)).PlaceEmpty().WithTag(testKey, tag1)
matrix.Cell(utils.Vec(x, tag2Y)).PlaceEmpty().WithTag(testKey, tag2)

hit, err := matrix.RayCastVertical(
utils.Vec(x, 3),
Expand Down Expand Up @@ -67,7 +67,7 @@ func TestMatrix_RayCastVertical_reverse(t *testing.T) {
x := 4
matrix := NewMatrix(10, 10)

matrix.Cell(utils.Vec(x, 4)).PlaceEmpty().Tag(testKey, tag1)
matrix.Cell(utils.Vec(x, 4)).PlaceEmpty().WithTag(testKey, tag1)

hit, err := matrix.RayCastVertical(
utils.Vec(x, 8),
Expand Down
Loading

0 comments on commit d802f6a

Please sign in to comment.