generic interface implementation. ready for generic update

This commit is contained in:
Tordarus 2021-01-15 21:40:09 +01:00
parent fbf90504b8
commit 7d18149008
4 changed files with 50 additions and 20 deletions

View File

@ -1,12 +1,13 @@
package buf2d package buf2d
import ( import (
"fmt"
"strings" "strings"
) )
// Buffer is a 2-dimensional rune buffer // Buffer is a 2-dimensional rune buffer
type Buffer struct { type Buffer struct {
data [][]rune data [][]fmt.Stringer
width int width int
height int height int
parent *Buffer parent *Buffer
@ -14,11 +15,11 @@ type Buffer struct {
// NewBuffer makes a new buffer with the given dimensions // NewBuffer makes a new buffer with the given dimensions
func NewBuffer(width, height int) *Buffer { func NewBuffer(width, height int) *Buffer {
b := make([][]rune, height) b := make([][]fmt.Stringer, height)
for y := range b { for y := range b {
b[y] = make([]rune, width) b[y] = make([]fmt.Stringer, width)
for x := range b[y] { for x := range b[y] {
b[y][x] = ' ' b[y][x] = spaceStringer
} }
} }
@ -38,13 +39,18 @@ func (b *Buffer) y(y int) int {
return limit(y, 0, b.height-1) return limit(y, 0, b.height-1)
} }
// Set sets the rune at position (x,y) to c // Set sets the fmt.Stringer at position (x,y) to c
func (b *Buffer) Set(x, y int, c rune) { func (b *Buffer) Set(x, y int, c fmt.Stringer) {
b.data[b.y(y)][b.x(x)] = c b.data[b.y(y)][b.x(x)] = c
} }
// Get returns the rune at position (x,y) // SetRune sets the fmt.Stringer at position (x,y) to rn
func (b *Buffer) Get(x, y int) rune { func (b *Buffer) SetRune(x, y int, rn rune) {
b.data[b.y(y)][b.x(x)] = newStringerFromRune(rn)
}
// Get returns the fmt.Stringer at position (x,y)
func (b *Buffer) Get(x, y int) fmt.Stringer {
return b.data[y][x] return b.data[y][x]
} }
@ -63,11 +69,11 @@ func (b *Buffer) Height() int {
return b.height return b.height
} }
// Draw calls drawFunc for every rune in this buffer // ForEach calls f for every rune in this buffer
func (b *Buffer) Draw(drawFunc func(x, y int, c rune)) { func (b *Buffer) ForEach(f func(x, y int, c fmt.Stringer)) {
for y, col := range b.data { for y, col := range b.data {
for x, char := range col { for x, v := range col {
drawFunc(x, y, char) f(x, y, v)
} }
} }
} }
@ -75,8 +81,8 @@ func (b *Buffer) Draw(drawFunc func(x, y int, c rune)) {
func (b *Buffer) String() string { func (b *Buffer) String() string {
s := new(strings.Builder) s := new(strings.Builder)
for ci, col := range b.data { for ci, col := range b.data {
for _, char := range col { for _, v := range col {
s.WriteRune(char) s.WriteString(fmt.Sprintf("%v", v))
} }
if ci != len(b.data)-1 { if ci != len(b.data)-1 {
s.WriteRune('\n') s.WriteRune('\n')
@ -97,7 +103,7 @@ func (b *Buffer) Sub(x, y, w, h int) *Buffer {
h = limit(h, 1, b.height-y) h = limit(h, 1, b.height-y)
// make slice references // make slice references
data := make([][]rune, h) data := make([][]fmt.Stringer, h)
for dy := 0; dy < h; dy++ { for dy := 0; dy < h; dy++ {
col := b.data[y+dy] col := b.data[y+dy]
data[dy] = col[x : x+w] data[dy] = col[x : x+w]

View File

@ -9,8 +9,8 @@ import (
func TestSub(t *testing.T) { func TestSub(t *testing.T) {
b := NewBuffer(10, 10) b := NewBuffer(10, 10)
s := b.Sub(1, 1, b.Width()-1, b.Height()-1) s := b.Sub(1, 1, b.Width()-1, b.Height()-1)
b.Set(5, 1, 'a') b.SetRune(5, 1, 'a')
s.Set(5, 5, 'b') s.SetRune(5, 5, 'b')
b.WriteString("Hello world", 1, 2) b.WriteString("Hello world", 1, 2)
fmt.Println(b) fmt.Println(b)

View File

@ -1,5 +1,7 @@
package buf2d package buf2d
import "fmt"
func limit(v, min, max int) int { func limit(v, min, max int) int {
return getmax(getmin(v, max), min) return getmax(getmin(v, max), min)
} }
@ -17,3 +19,22 @@ func getmin(x, y int) int {
} }
return y return y
} }
type stringerImpl string
func (s *stringerImpl) String() string {
return string(*s)
}
func newStringer(str string) fmt.Stringer {
var impl stringerImpl = stringerImpl(str)
return &impl
}
func newStringerFromRune(rn rune) fmt.Stringer {
return newStringer(string(rn))
}
var (
spaceStringer = newStringer(" ")
)

View File

@ -1,6 +1,9 @@
package buf2d package buf2d
import "strings" import (
"fmt"
"strings"
)
// WriteString writes a whole string to the buffer at position (x,y) // WriteString writes a whole string to the buffer at position (x,y)
// no word wrap is applied at all. If the string does not fit, it will be truncated // no word wrap is applied at all. If the string does not fit, it will be truncated
@ -10,7 +13,7 @@ func (b *Buffer) WriteString(str string, x, y int) {
if dx >= b.width { if dx >= b.width {
return return
} }
b.Set(dx, y, r) b.Set(dx, y, newStringerFromRune(r))
dx++ dx++
} }
} }
@ -30,7 +33,7 @@ func (b *Buffer) WriteMultiLineString(str string, x, y int) {
} }
// Fill fills the whole buffer with c // Fill fills the whole buffer with c
func (b *Buffer) Fill(c rune) { func (b *Buffer) Fill(c fmt.Stringer) {
for _, col := range b.data { for _, col := range b.data {
for ri := range col { for ri := range col {
col[ri] = c col[ri] = c