Buffer is thread safe
This commit is contained in:
parent
85994112cf
commit
3a3fb66db8
33
buffer.go
33
buffer.go
@ -1,5 +1,7 @@
|
|||||||
package stone
|
package stone
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
// Color represents all the different colors a cell can be.
|
// Color represents all the different colors a cell can be.
|
||||||
type Color uint8
|
type Color uint8
|
||||||
|
|
||||||
@ -65,6 +67,10 @@ type Buffer struct {
|
|||||||
x int
|
x int
|
||||||
y int
|
y int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This should be write locked when resizing the buffer, and read locked
|
||||||
|
// when writing to cells or reading information about the buffer.
|
||||||
|
lock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (buffer *Buffer) isOutOfBounds (x, y int) (outOfBounds bool) {
|
func (buffer *Buffer) isOutOfBounds (x, y int) (outOfBounds bool) {
|
||||||
@ -78,6 +84,9 @@ 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 *Buffer) Size () (width, height int) {
|
||||||
|
buffer.lock.RLock()
|
||||||
|
defer buffer.lock.RUnlock()
|
||||||
|
|
||||||
width = buffer.width
|
width = buffer.width
|
||||||
height = buffer.height
|
height = buffer.height
|
||||||
return
|
return
|
||||||
@ -93,6 +102,9 @@ func (buffer *Buffer) SetDot (x, y int) {
|
|||||||
// 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 *Buffer) Cell (x, y int) (cell Cell) {
|
||||||
|
buffer.lock.RLock()
|
||||||
|
defer buffer.lock.RUnlock()
|
||||||
|
|
||||||
if buffer.isOutOfBounds(x, y) { return }
|
if buffer.isOutOfBounds(x, y) { return }
|
||||||
cell = buffer.content[x + y * buffer.width]
|
cell = buffer.content[x + y * buffer.width]
|
||||||
return
|
return
|
||||||
@ -100,6 +112,9 @@ 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) {
|
||||||
|
buffer.lock.RLock()
|
||||||
|
defer buffer.lock.RUnlock()
|
||||||
|
|
||||||
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].color == color
|
buffer.clean[index] = buffer.content[index].color == color
|
||||||
@ -109,6 +124,9 @@ 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 *Buffer) SetSize (width, height int) {
|
||||||
|
buffer.lock.Lock()
|
||||||
|
defer buffer.lock.Unlock()
|
||||||
|
|
||||||
if width < 0 || height < 0 { return }
|
if width < 0 || height < 0 { return }
|
||||||
buffer.width = width
|
buffer.width = width
|
||||||
buffer.height = height
|
buffer.height = height
|
||||||
@ -121,6 +139,9 @@ 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 *Buffer) SetStyle (x, y int, style Style) {
|
||||||
|
buffer.lock.RLock()
|
||||||
|
defer buffer.lock.RUnlock()
|
||||||
|
|
||||||
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].style == style
|
buffer.clean[index] = buffer.content[index].style == style
|
||||||
@ -129,6 +150,9 @@ 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 *Buffer) SetRune (x, y int, content rune) {
|
||||||
|
buffer.lock.RLock()
|
||||||
|
defer buffer.lock.RUnlock()
|
||||||
|
|
||||||
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
|
||||||
@ -138,6 +162,9 @@ 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 *Buffer) Write (bytes []byte) (bytesWritten int, err error) {
|
||||||
|
buffer.lock.RLock()
|
||||||
|
defer buffer.lock.RUnlock()
|
||||||
|
|
||||||
text := string(bytes)
|
text := string(bytes)
|
||||||
bytesWritten = len(bytes)
|
bytesWritten = len(bytes)
|
||||||
|
|
||||||
@ -153,6 +180,9 @@ 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 *Buffer) Clean (x, y int) (clean bool) {
|
||||||
|
buffer.lock.RLock()
|
||||||
|
defer buffer.lock.RUnlock()
|
||||||
|
|
||||||
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
|
||||||
@ -160,6 +190,9 @@ 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 *Buffer) MarkClean (x, y int) {
|
||||||
|
buffer.lock.RLock()
|
||||||
|
defer buffer.lock.RUnlock()
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user