There is only one type of buffer now
This commit is contained in:
parent
abc9945ea1
commit
77cf88b856
@ -4,7 +4,7 @@ import "image"
|
|||||||
|
|
||||||
// Application represents an application.
|
// Application represents an application.
|
||||||
type Application struct {
|
type Application struct {
|
||||||
DamageBuffer
|
Buffer
|
||||||
|
|
||||||
title string
|
title string
|
||||||
icons []image.Image
|
icons []image.Image
|
||||||
@ -22,7 +22,7 @@ func (application *Application) Run () (
|
|||||||
width, height := application.Size()
|
width, height := application.Size()
|
||||||
if width < 1 { width = 80 }
|
if width < 1 { width = 80 }
|
||||||
if height < 1 { height = 20 }
|
if height < 1 { height = 20 }
|
||||||
application.DamageBuffer.SetSize(width, height)
|
application.Buffer.SetSize(width, height)
|
||||||
|
|
||||||
application.config.load()
|
application.config.load()
|
||||||
|
|
||||||
|
@ -33,10 +33,6 @@ func (backend *Backend) handleConfigureNotify (
|
|||||||
configureEvent =
|
configureEvent =
|
||||||
backend.compressConfigureNotify(configureEvent)
|
backend.compressConfigureNotify(configureEvent)
|
||||||
|
|
||||||
// we should not resize the canvas while drawing is taking place
|
|
||||||
backend.drawLock.Lock()
|
|
||||||
defer backend.drawLock.Unlock()
|
|
||||||
|
|
||||||
// resize buffer
|
// resize buffer
|
||||||
width, height := backend.calculateBufferSize()
|
width, height := backend.calculateBufferSize()
|
||||||
backend.application.SetSize(width, height)
|
backend.application.SetSize(width, height)
|
||||||
|
113
buffer.go
113
buffer.go
@ -51,9 +51,14 @@ func (cell Cell) Rune () (content rune) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer is a basic grid of cells.
|
// Buffer is a two dimensional text buffer that stores a grid of cells, as well
|
||||||
|
// as information stating whether each cell is clean or dirty. Cells are dirty
|
||||||
|
// by default, are only clean when marked as clean, and become dirty again when
|
||||||
|
// they are altered in some way.
|
||||||
type Buffer struct {
|
type Buffer struct {
|
||||||
content []Cell
|
content []Cell
|
||||||
|
clean []bool
|
||||||
|
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
Dot struct {
|
Dot struct {
|
||||||
@ -78,16 +83,11 @@ func (buffer *Buffer) Size () (width, height int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSize sets the width and height of the buffer. This clears all data in the
|
// ResetDot is a convenience method to reset the dot to the buffer origin point
|
||||||
// buffer. If the width or height is negative, this method does nothing.
|
// (0, 0).
|
||||||
func (buffer *Buffer) SetSize (width, height int) {
|
func (buffer *Buffer) ResetDot () {
|
||||||
if width < 0 || height < 0 { return }
|
buffer.Dot.X = 0
|
||||||
buffer.width = width
|
buffer.Dot.Y = 0
|
||||||
buffer.height = height
|
|
||||||
buffer.content = make([]Cell, width * height)
|
|
||||||
for index := 0; index < len(buffer.content); index ++ {
|
|
||||||
buffer.content[index].color = ColorForeground
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cell returns the cell at the specified x and y coordinates. If the
|
// Cell returns the cell at the specified x and y coordinates. If the
|
||||||
@ -101,19 +101,38 @@ func (buffer *Buffer) Cell (x, y int) (cell Cell) {
|
|||||||
// SetColor sets the color of the cell at the specified x and y coordinates.
|
// SetColor sets the color of the cell at the specified x and y coordinates.
|
||||||
func (buffer *Buffer) SetColor (x, y int, color Color) {
|
func (buffer *Buffer) SetColor (x, y int, color Color) {
|
||||||
if buffer.isOutOfBounds(x, y) { return }
|
if buffer.isOutOfBounds(x, y) { return }
|
||||||
buffer.content[x + y * buffer.width].color = color
|
index := x + y * buffer.width
|
||||||
|
buffer.clean[index] = buffer.content[index].color == color
|
||||||
|
buffer.content[index].color = color
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSize sets the width and height of the buffer. This clears all data in the
|
||||||
|
// buffer. If the width or height is negative, this method does nothing.
|
||||||
|
func (buffer *Buffer) SetSize (width, height int) {
|
||||||
|
if width < 0 || height < 0 { return }
|
||||||
|
buffer.width = width
|
||||||
|
buffer.height = height
|
||||||
|
buffer.content = make([]Cell, width * height)
|
||||||
|
buffer.clean = make([]bool, width * height)
|
||||||
|
for index := 0; index < len(buffer.content); index ++ {
|
||||||
|
buffer.content[index].color = ColorForeground
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetStyle sets the style of the cell at the specified x and y coordinates.
|
// SetStyle sets the style of the cell at the specified x and y coordinates.
|
||||||
func (buffer *Buffer) SetStyle (x, y int, style Style) {
|
func (buffer *Buffer) SetStyle (x, y int, style Style) {
|
||||||
if buffer.isOutOfBounds(x, y) { return }
|
if buffer.isOutOfBounds(x, y) { return }
|
||||||
buffer.content[x + y * buffer.width].style = style
|
index := x + y * buffer.width
|
||||||
|
buffer.clean[index] = buffer.content[index].style == style
|
||||||
|
buffer.content[index].style = style
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetRune sets the rune of the cell at the specified x and y coordinates.
|
// SetRune sets the rune of the cell at the specified x and y coordinates.
|
||||||
func (buffer *Buffer) SetRune (x, y int, content rune) {
|
func (buffer *Buffer) SetRune (x, y int, content rune) {
|
||||||
if buffer.isOutOfBounds(x, y) { return }
|
if buffer.isOutOfBounds(x, y) { return }
|
||||||
buffer.content[x + y * buffer.width].content = content
|
index := x + y * buffer.width
|
||||||
|
buffer.clean[index] = buffer.content[index].content == content
|
||||||
|
buffer.content[index].content = content
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write writes data stored in a byte slice to the buffer at the current dot
|
// Write writes data stored in a byte slice to the buffer at the current dot
|
||||||
@ -131,78 +150,16 @@ func (buffer *Buffer) Write (bytes []byte) (bytesWritten int, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetDot is a convenience method to reset the dot to the buffer origin point
|
|
||||||
// (0, 0).
|
|
||||||
func (buffer *Buffer) ResetDot () {
|
|
||||||
buffer.Dot.X = 0
|
|
||||||
buffer.Dot.Y = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// DamageBuffer is a special buffer that keeps track of damage information.
|
|
||||||
// Cells are dirty by default, are only clean when marked as clean, and become
|
|
||||||
// dirty again when they are altered in some way.
|
|
||||||
type DamageBuffer struct {
|
|
||||||
Buffer
|
|
||||||
clean []bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSize sets the width and height of the buffer. This clears all data in the
|
|
||||||
// buffer. If the width or height is negative, this method does nothing.
|
|
||||||
func (buffer *DamageBuffer) SetSize (width, height int) {
|
|
||||||
if width < 0 || height < 0 { return }
|
|
||||||
buffer.Buffer.SetSize(width, height)
|
|
||||||
buffer.clean = make([]bool, width * height)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetColor sets the color of the cell at the specified x and y coordinates.
|
|
||||||
func (buffer *DamageBuffer) SetColor (x, y int, color Color) {
|
|
||||||
if buffer.isOutOfBounds(x, y) { return }
|
|
||||||
index := x + y * buffer.width
|
|
||||||
buffer.clean[index] = buffer.content[index].color == color
|
|
||||||
buffer.Buffer.SetColor(x, y, color)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetStyle sets the style of the cell at the specified x and y coordinates.
|
|
||||||
func (buffer *DamageBuffer) SetStyle (x, y int, style Style) {
|
|
||||||
if buffer.isOutOfBounds(x, y) { return }
|
|
||||||
index := x + y * buffer.width
|
|
||||||
buffer.clean[index] = buffer.content[index].style == style
|
|
||||||
buffer.Buffer.SetStyle(x, y, style)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetRune sets the rune of the cell at the specified x and y coordinates.
|
|
||||||
func (buffer *DamageBuffer) SetRune (x, y int, content rune) {
|
|
||||||
if buffer.isOutOfBounds(x, y) { return }
|
|
||||||
index := x + y * buffer.width
|
|
||||||
buffer.clean[index] = buffer.content[index].content == content
|
|
||||||
buffer.Buffer.SetRune(x, y, content)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write writes data stored in a byte slice to the buffer at the current dot
|
|
||||||
// position. This makes DamageBuffer an io.Writer.
|
|
||||||
func (buffer *DamageBuffer) Write (bytes []byte) (bytesWritten int, err error) {
|
|
||||||
text := string(bytes)
|
|
||||||
bytesWritten = len(bytes)
|
|
||||||
|
|
||||||
for _, character := range text {
|
|
||||||
buffer.SetRune(buffer.Dot.X, buffer.Dot.Y, character)
|
|
||||||
buffer.Dot.X ++
|
|
||||||
if buffer.Dot.X > buffer.width { break }
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean returns whether or not the cell at the specified x and y coordinates is
|
// Clean returns whether or not the cell at the specified x and y coordinates is
|
||||||
// clean.
|
// clean.
|
||||||
func (buffer *DamageBuffer) Clean (x, y int) (clean bool) {
|
func (buffer *Buffer) Clean (x, y int) (clean bool) {
|
||||||
if buffer.isOutOfBounds(x, y) { return }
|
if buffer.isOutOfBounds(x, y) { return }
|
||||||
clean = buffer.clean[x + y * buffer.width]
|
clean = buffer.clean[x + y * buffer.width]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkClean marks the cell at the specified x and y coordinates as clean.
|
// MarkClean marks the cell at the specified x and y coordinates as clean.
|
||||||
func (buffer *DamageBuffer) MarkClean (x, y int) {
|
func (buffer *Buffer) MarkClean (x, y int) {
|
||||||
if buffer.isOutOfBounds(x, y) { return }
|
if buffer.isOutOfBounds(x, y) { return }
|
||||||
buffer.clean[x + y * buffer.width] = true
|
buffer.clean[x + y * buffer.width] = true
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,6 @@ func (config *Config) FontName () (fontName string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (config *Config) load () {
|
func (config *Config) load () {
|
||||||
// TODO: load these from a file
|
|
||||||
config.colors = [8]color.Color {
|
config.colors = [8]color.Color {
|
||||||
// background
|
// background
|
||||||
color.RGBA { R: 0, G: 0, B: 0, A: 0 },
|
color.RGBA { R: 0, G: 0, B: 0, A: 0 },
|
||||||
|
Loading…
Reference in New Issue
Block a user