diff --git a/application.go b/application.go index 3d5b63b..8ca021f 100644 --- a/application.go +++ b/application.go @@ -4,7 +4,7 @@ import "image" // Application represents an application. type Application struct { - DamageBuffer + Buffer title string icons []image.Image @@ -22,7 +22,7 @@ func (application *Application) Run () ( width, height := application.Size() if width < 1 { width = 80 } if height < 1 { height = 20 } - application.DamageBuffer.SetSize(width, height) + application.Buffer.SetSize(width, height) application.config.load() diff --git a/backends/x/event.go b/backends/x/event.go index 1291f23..e55c61e 100644 --- a/backends/x/event.go +++ b/backends/x/event.go @@ -33,10 +33,6 @@ func (backend *Backend) handleConfigureNotify ( configureEvent = backend.compressConfigureNotify(configureEvent) - // we should not resize the canvas while drawing is taking place - backend.drawLock.Lock() - defer backend.drawLock.Unlock() - // resize buffer width, height := backend.calculateBufferSize() backend.application.SetSize(width, height) diff --git a/buffer.go b/buffer.go index 35b13c1..616ebd1 100644 --- a/buffer.go +++ b/buffer.go @@ -51,9 +51,14 @@ func (cell Cell) Rune () (content rune) { 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 { content []Cell + clean []bool + width int height int Dot struct { @@ -78,16 +83,11 @@ func (buffer *Buffer) Size () (width, height int) { return } -// 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) - for index := 0; index < len(buffer.content); index ++ { - buffer.content[index].color = ColorForeground - } +// 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 } // 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. func (buffer *Buffer) SetColor (x, y int, color Color) { 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. func (buffer *Buffer) SetStyle (x, y int, style Style) { 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. func (buffer *Buffer) SetRune (x, y int, content rune) { 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 @@ -131,78 +150,16 @@ func (buffer *Buffer) Write (bytes []byte) (bytesWritten int, err error) { 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. -func (buffer *DamageBuffer) Clean (x, y int) (clean bool) { +func (buffer *Buffer) Clean (x, y int) (clean bool) { if buffer.isOutOfBounds(x, y) { return } clean = buffer.clean[x + y * buffer.width] return } // 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 } buffer.clean[x + y * buffer.width] = true } diff --git a/config.go b/config.go index 74765ba..d08a7c9 100644 --- a/config.go +++ b/config.go @@ -42,7 +42,6 @@ func (config *Config) FontName () (fontName string) { } func (config *Config) load () { - // TODO: load these from a file config.colors = [8]color.Color { // background color.RGBA { R: 0, G: 0, B: 0, A: 0 },