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 | ||||
| 
 | ||||
| import "sync" | ||||
| 
 | ||||
| // Color represents all the different colors a cell can be. | ||||
| type Color uint8 | ||||
| 
 | ||||
| @ -65,6 +67,10 @@ type Buffer struct { | ||||
| 		x 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) { | ||||
| @ -78,6 +84,9 @@ func (buffer *Buffer) isOutOfBounds (x, y int) (outOfBounds bool) { | ||||
| 
 | ||||
| // Size returns the width and height of the buffer. | ||||
| func (buffer *Buffer) Size () (width, height int) { | ||||
| 	buffer.lock.RLock() | ||||
| 	defer buffer.lock.RUnlock() | ||||
| 	 | ||||
| 	width  = buffer.width | ||||
| 	height = buffer.height | ||||
| 	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 | ||||
| // coordinates are out of bounds, this method will return a blank cell. | ||||
| func (buffer *Buffer) Cell (x, y int) (cell Cell) { | ||||
| 	buffer.lock.RLock() | ||||
| 	defer buffer.lock.RUnlock() | ||||
| 	 | ||||
| 	if buffer.isOutOfBounds(x, y) { return } | ||||
| 	cell = buffer.content[x + y * buffer.width] | ||||
| 	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. | ||||
| func (buffer *Buffer) SetColor (x, y int, color Color) { | ||||
| 	buffer.lock.RLock() | ||||
| 	defer buffer.lock.RUnlock() | ||||
| 	 | ||||
| 	if buffer.isOutOfBounds(x, y) { return } | ||||
| 	index := x + y * buffer.width | ||||
| 	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 | ||||
| // buffer. If the width or height is negative, this method does nothing. | ||||
| func (buffer *Buffer) SetSize (width, height int) { | ||||
| 	buffer.lock.Lock() | ||||
| 	defer buffer.lock.Unlock() | ||||
| 	 | ||||
| 	if width < 0 || height < 0 { return } | ||||
| 	buffer.width   = width | ||||
| 	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. | ||||
| func (buffer *Buffer) SetStyle (x, y int, style Style) { | ||||
| 	buffer.lock.RLock() | ||||
| 	defer buffer.lock.RUnlock() | ||||
| 	 | ||||
| 	if buffer.isOutOfBounds(x, y) { return } | ||||
| 	index := x + y * buffer.width | ||||
| 	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. | ||||
| func (buffer *Buffer) SetRune (x, y int, content rune) { | ||||
| 	buffer.lock.RLock() | ||||
| 	defer buffer.lock.RUnlock() | ||||
| 	 | ||||
| 	if buffer.isOutOfBounds(x, y) { return } | ||||
| 	index := x + y * buffer.width | ||||
| 	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 | ||||
| // position. This makes Buffer an io.Writer. | ||||
| func (buffer *Buffer) Write (bytes []byte) (bytesWritten int, err error) { | ||||
| 	buffer.lock.RLock() | ||||
| 	defer buffer.lock.RUnlock() | ||||
| 	 | ||||
| 	text := string(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. | ||||
| func (buffer *Buffer) Clean (x, y int) (clean bool) { | ||||
| 	buffer.lock.RLock() | ||||
| 	defer buffer.lock.RUnlock() | ||||
| 	 | ||||
| 	if buffer.isOutOfBounds(x, y) { return } | ||||
| 	clean = buffer.clean[x + y * buffer.width] | ||||
| 	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. | ||||
| func (buffer *Buffer) MarkClean (x, y int) { | ||||
| 	buffer.lock.RLock() | ||||
| 	defer buffer.lock.RUnlock() | ||||
| 	 | ||||
| 	if buffer.isOutOfBounds(x, y) { return } | ||||
| 	buffer.clean[x + y * buffer.width] = true | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user