generic interface implementation. ready for generic update
This commit is contained in:
parent
fbf90504b8
commit
7d18149008
36
buffer.go
36
buffer.go
@ -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]
|
||||||
|
@ -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)
|
||||||
|
21
utils.go
21
utils.go
@ -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(" ")
|
||||||
|
)
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user