Added Buffer interface, and clear method

This commit is contained in:
Sasha Koshka 2022-11-16 21:20:48 -05:00
parent 0ee58d22f6
commit 754017a2db
3 changed files with 45 additions and 21 deletions

View File

@ -4,7 +4,7 @@ import "image"
// Application represents an application. // Application represents an application.
type Application struct { type Application struct {
Buffer DamageBuffer
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.Buffer.SetSize(width, height) application.DamageBuffer.SetSize(width, height)
application.config.load() application.config.load()

View File

@ -53,11 +53,22 @@ func (cell Cell) Rune () (content rune) {
return return
} }
// Buffer is a two dimensional text buffer that stores a grid of cells, as well // Buffer represents a two dimensional text buffer.
// as information stating whether each cell is clean or dirty. Cells are dirty type Buffer interface {
// by default, are only clean when marked as clean, and become dirty again when Size () (with, height int)
// they are altered in some way. Cell (x, y int) (cell Cell)
type Buffer struct { SetColor (x, y int, color Color)
SetSize (with, height int)
SetStyle (x, y int, style Style)
SetRune (x, y int, content rune)
Clear ()
}
// DamageBuffer 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 DamageBuffer struct {
content []Cell content []Cell
clean []bool clean []bool
@ -73,7 +84,7 @@ type Buffer struct {
lock sync.RWMutex lock sync.RWMutex
} }
func (buffer *Buffer) isOutOfBounds (x, y int) (outOfBounds bool) { func (buffer *DamageBuffer) isOutOfBounds (x, y int) (outOfBounds bool) {
outOfBounds = outOfBounds =
x < 0 || x < 0 ||
y < 0 || y < 0 ||
@ -83,7 +94,7 @@ func (buffer *Buffer) isOutOfBounds (x, y int) (outOfBounds bool) {
} }
// Size returns the width and height of the buffer. // Size returns the width and height of the buffer.
func (buffer *Buffer) Size () (width, height int) { func (buffer *DamageBuffer) Size () (width, height int) {
buffer.lock.RLock() buffer.lock.RLock()
defer buffer.lock.RUnlock() defer buffer.lock.RUnlock()
@ -94,14 +105,14 @@ func (buffer *Buffer) Size () (width, height int) {
// SetDot sets the buffer's text insertion position relative to the buffer // SetDot sets the buffer's text insertion position relative to the buffer
// origin point (0, 0). // origin point (0, 0).
func (buffer *Buffer) SetDot (x, y int) { func (buffer *DamageBuffer) SetDot (x, y int) {
buffer.dot.x = x buffer.dot.x = x
buffer.dot.y = y buffer.dot.y = y
} }
// 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
// coordinates are out of bounds, this method will return a blank cell. // coordinates are out of bounds, this method will return a blank cell.
func (buffer *Buffer) Cell (x, y int) (cell Cell) { func (buffer *DamageBuffer) Cell (x, y int) (cell Cell) {
buffer.lock.RLock() buffer.lock.RLock()
defer buffer.lock.RUnlock() defer buffer.lock.RUnlock()
@ -111,7 +122,7 @@ 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 *DamageBuffer) SetColor (x, y int, color Color) {
buffer.lock.RLock() buffer.lock.RLock()
defer buffer.lock.RUnlock() defer buffer.lock.RUnlock()
@ -123,7 +134,7 @@ func (buffer *Buffer) SetColor (x, y int, color Color) {
// SetSize sets the width and height of the buffer. This clears all data in the // 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. // buffer. If the width or height is negative, this method does nothing.
func (buffer *Buffer) SetSize (width, height int) { func (buffer *DamageBuffer) SetSize (width, height int) {
buffer.lock.Lock() buffer.lock.Lock()
defer buffer.lock.Unlock() defer buffer.lock.Unlock()
@ -138,7 +149,7 @@ func (buffer *Buffer) SetSize (width, height int) {
} }
// 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 *DamageBuffer) SetStyle (x, y int, style Style) {
buffer.lock.RLock() buffer.lock.RLock()
defer buffer.lock.RUnlock() defer buffer.lock.RUnlock()
@ -149,14 +160,27 @@ func (buffer *Buffer) SetStyle (x, y int, 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 *DamageBuffer) SetRune (x, y int, content rune) {
buffer.lock.RLock() buffer.lock.RLock()
defer buffer.lock.RUnlock() defer buffer.lock.RUnlock()
buffer.setRune(x, y, content) buffer.setRune(x, y, content)
} }
func (buffer *Buffer) setRune (x, y int, content rune) { // Clear resets the entire buffer.
func (buffer *DamageBuffer) Clear () {
buffer.lock.RLock()
defer buffer.lock.RUnlock()
for index := 0; index < len(buffer.content); index ++ {
buffer.clean[index] = false
buffer.content[index] = Cell {
color: ColorForeground,
}
}
}
func (buffer *DamageBuffer) setRune (x, y int, content rune) {
if buffer.isOutOfBounds(x, y) { return } if buffer.isOutOfBounds(x, y) { return }
index := x + y * buffer.width index := x + y * buffer.width
buffer.clean[index] = buffer.content[index].content == content buffer.clean[index] = buffer.content[index].content == content
@ -165,7 +189,7 @@ func (buffer *Buffer) setRune (x, y int, content rune) {
// 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
// position. This makes Buffer an io.Writer. // position. This makes Buffer an io.Writer.
func (buffer *Buffer) Write (bytes []byte) (bytesWritten int, err error) { func (buffer *DamageBuffer) Write (bytes []byte) (bytesWritten int, err error) {
buffer.lock.RLock() buffer.lock.RLock()
defer buffer.lock.RUnlock() defer buffer.lock.RUnlock()
@ -183,7 +207,7 @@ func (buffer *Buffer) Write (bytes []byte) (bytesWritten int, err error) {
// 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 *Buffer) Clean (x, y int) (clean bool) { func (buffer *DamageBuffer) Clean (x, y int) (clean bool) {
buffer.lock.RLock() buffer.lock.RLock()
defer buffer.lock.RUnlock() defer buffer.lock.RUnlock()
@ -193,7 +217,7 @@ func (buffer *Buffer) Clean (x, y int) (clean bool) {
} }
// 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 *Buffer) MarkClean (x, y int) { func (buffer *DamageBuffer) MarkClean (x, y int) {
buffer.lock.RLock() buffer.lock.RLock()
defer buffer.lock.RUnlock() defer buffer.lock.RUnlock()

View File

@ -64,9 +64,9 @@ func (config *Config) load () {
// green // green
color.RGBA { R: 0x00, G: 0xFF, B: 0x00, A: 0xFF }, color.RGBA { R: 0x00, G: 0xFF, B: 0x00, A: 0xFF },
// blue // blue
color.RGBA { R: 0x00, G: 0x00, B: 0xFF, A: 0xFF }, color.RGBA { R: 0x00, G: 0x80, B: 0xFF, A: 0xFF },
// purple // purple
color.RGBA { R: 0x80, G: 0x00, B: 0xFF, A: 0xFF }, color.RGBA { R: 0x80, G: 0x40, B: 0xFF, A: 0xFF },
} }
config.fontName = "" config.fontName = ""
config.fontSize = 11 config.fontSize = 11