mirror of
https://github.com/Dadido3/noita-mapcap.git
synced 2024-11-18 17:17:31 +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.
|
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.
|
image image.Image // Either a rectangle or an RGBA image. The bounds of this image are determined by the filename.
|
||||||
imageMutex *sync.RWMutex //
|
imageMutex *sync.RWMutex
|
||||||
|
|
||||||
invalidationChan chan struct{} // Used to send invalidation requests to the tile's goroutine.
|
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.
|
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.
|
// InvalidateAboveY invalidates all cached images that have no pixel at the given y coordinate or below.
|
||||||
func (it ImageTiles) InvalidateAboveY(y int) {
|
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 {
|
if tile.Bounds().Max.Y <= y {
|
||||||
tile.Invalidate()
|
tile.Invalidate()
|
||||||
}
|
}
|
||||||
|
@ -54,10 +54,10 @@ func (sic *StitchedImageCache) Regenerate() *image.RGBA {
|
|||||||
|
|
||||||
// List of tiles that intersect with the to be generated cache image.
|
// List of tiles that intersect with the to be generated cache image.
|
||||||
intersectingTiles := []*ImageTile{}
|
intersectingTiles := []*ImageTile{}
|
||||||
for i, tile := range si.tiles {
|
for i := range si.tiles {
|
||||||
|
tile := &si.tiles[i]
|
||||||
if tile.Bounds().Overlaps(sic.rect) {
|
if tile.Bounds().Overlaps(sic.rect) {
|
||||||
tilePtr := &si.tiles[i]
|
intersectingTiles = append(intersectingTiles, tile)
|
||||||
intersectingTiles = append(intersectingTiles, tilePtr)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StitchedImageCacheGridSize defines the worker chunk size when the cache image is regenerated.
|
// 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.
|
cacheRowYOffset int // Defines the pixel offset of the first cache row.
|
||||||
|
|
||||||
oldCacheRowIndex int
|
oldCacheRowIndex int
|
||||||
queryCounter int
|
queryCounter atomic.Int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStitchedImage creates a new image from several single image tiles.
|
// 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.
|
// At(Bounds().Max.X-1, Bounds().Max.Y-1) // returns the bottom-right pixel.
|
||||||
func (si *StitchedImage) RGBAAt(x, y int) color.RGBA {
|
func (si *StitchedImage) RGBAAt(x, y int) color.RGBA {
|
||||||
// Assume that every pixel is only queried once.
|
// Assume that every pixel is only queried once.
|
||||||
si.queryCounter++
|
si.queryCounter.Add(1)
|
||||||
|
|
||||||
// Determine the cache rowIndex index.
|
// Determine the cache rowIndex index.
|
||||||
rowIndex := (y + si.cacheRowYOffset) / si.cacheRowHeight
|
rowIndex := (y + si.cacheRowYOffset) / si.cacheRowHeight
|
||||||
@ -142,5 +143,5 @@ func (si *StitchedImage) Opaque() bool {
|
|||||||
func (si *StitchedImage) Progress() (value, max int) {
|
func (si *StitchedImage) Progress() (value, max int) {
|
||||||
size := si.Bounds().Size()
|
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