mirror of
				https://github.com/Dadido3/noita-mapcap.git
				synced 2025-10-31 03:09:35 +00:00 
			
		
		
		
	Fix all possible data races
- Update to go 1.19 for new atomic types - Use atomic for StitchedImage query counter - Make sure that we don't copy any tile objects
This commit is contained in:
		
							parent
							
								
									65f7cb4e60
								
							
						
					
					
						commit
						c9d2a37903
					
				| @ -28,8 +28,8 @@ type ImageTile struct { | ||||
| 
 | ||||
| 	scaleDivider int // Downscales the coordinates and images on the fly.
 | ||||
| 
 | ||||
| 	image      image.Image   // Either a rectangle or an RGBA image. The bounds of this image are determined by the filename.
 | ||||
| 	imageMutex *sync.RWMutex //
 | ||||
| 	image      image.Image // Either a rectangle or an RGBA image. The bounds of this image are determined by the filename.
 | ||||
| 	imageMutex *sync.RWMutex | ||||
| 
 | ||||
| 	invalidationChan chan struct{} // Used to send invalidation requests to the tile's goroutine.
 | ||||
| 	timeoutChan      chan struct{} // Used to determine whether the tile is still being accessed or not.
 | ||||
|  | ||||
| @ -39,7 +39,8 @@ func LoadImageTiles(path string, scaleDivider int) (ImageTiles, error) { | ||||
| 
 | ||||
| // InvalidateAboveY invalidates all cached images that have no pixel at the given y coordinate or below.
 | ||||
| func (it ImageTiles) InvalidateAboveY(y int) { | ||||
| 	for _, tile := range it { | ||||
| 	for i := range it { | ||||
| 		tile := &it[i] // Need to copy a reference.
 | ||||
| 		if tile.Bounds().Max.Y <= y { | ||||
| 			tile.Invalidate() | ||||
| 		} | ||||
|  | ||||
| @ -54,10 +54,10 @@ func (sic *StitchedImageCache) Regenerate() *image.RGBA { | ||||
| 
 | ||||
| 	// List of tiles that intersect with the to be generated cache image.
 | ||||
| 	intersectingTiles := []*ImageTile{} | ||||
| 	for i, tile := range si.tiles { | ||||
| 	for i := range si.tiles { | ||||
| 		tile := &si.tiles[i] | ||||
| 		if tile.Bounds().Overlaps(sic.rect) { | ||||
| 			tilePtr := &si.tiles[i] | ||||
| 			intersectingTiles = append(intersectingTiles, tilePtr) | ||||
| 			intersectingTiles = append(intersectingTiles, tile) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -9,6 +9,7 @@ import ( | ||||
| 	"fmt" | ||||
| 	"image" | ||||
| 	"image/color" | ||||
| 	"sync/atomic" | ||||
| ) | ||||
| 
 | ||||
| // StitchedImageCacheGridSize defines the worker chunk size when the cache image is regenerated.
 | ||||
| @ -37,7 +38,7 @@ type StitchedImage struct { | ||||
| 	cacheRowYOffset int // Defines the pixel offset of the first cache row.
 | ||||
| 
 | ||||
| 	oldCacheRowIndex int | ||||
| 	queryCounter     int | ||||
| 	queryCounter     atomic.Int64 | ||||
| } | ||||
| 
 | ||||
| // NewStitchedImage creates a new image from several single image tiles.
 | ||||
| @ -98,7 +99,7 @@ func (si *StitchedImage) At(x, y int) color.Color { | ||||
| //	At(Bounds().Max.X-1, Bounds().Max.Y-1) // returns the bottom-right pixel.
 | ||||
| func (si *StitchedImage) RGBAAt(x, y int) color.RGBA { | ||||
| 	// Assume that every pixel is only queried once.
 | ||||
| 	si.queryCounter++ | ||||
| 	si.queryCounter.Add(1) | ||||
| 
 | ||||
| 	// Determine the cache rowIndex index.
 | ||||
| 	rowIndex := (y + si.cacheRowYOffset) / si.cacheRowHeight | ||||
| @ -142,5 +143,5 @@ func (si *StitchedImage) Opaque() bool { | ||||
| func (si *StitchedImage) Progress() (value, max int) { | ||||
| 	size := si.Bounds().Size() | ||||
| 
 | ||||
| 	return si.queryCounter, size.X * size.Y | ||||
| 	return int(si.queryCounter.Load()), size.X * size.Y | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user