graphics: Bug fix: Concurrent-safe check in (*Image).At

This commit is contained in:
Hajime Hoshi 2016-05-12 11:36:09 +09:00
parent 9d569e3e49
commit f1f3bcc257
2 changed files with 19 additions and 18 deletions

View File

@ -63,10 +63,6 @@ func (t *delayedImageTasks) exec() error {
return nil return nil
} }
func (t *delayedImageTasks) isExecCalled() bool {
t.execCalled
}
// Image represents an image. // Image represents an image.
// The pixel format is alpha-premultiplied. // The pixel format is alpha-premultiplied.
// Image implements image.Image. // Image implements image.Image.
@ -203,12 +199,11 @@ func (i *Image) ColorModel() color.Model {
// //
// This function is concurrent-safe. // This function is concurrent-safe.
func (i *Image) At(x, y int) color.Color { func (i *Image) At(x, y int) color.Color {
// TODO: What if At is called internaly (like from image parts?) if !currentRunContext.isRunning() {
imageM.Lock()
defer imageM.Unlock()
if !theDelayedImageTasks.isExecCalled() {
panic("ebiten: At can't be called when the GL context is not initialized (this panic happens as of version 1.4.0-alpha)") panic("ebiten: At can't be called when the GL context is not initialized (this panic happens as of version 1.4.0-alpha)")
} }
imageM.Lock()
defer imageM.Unlock()
if i.isDisposed() { if i.isDisposed() {
return color.Transparent return color.Transparent
} }

26
run.go
View File

@ -23,12 +23,12 @@ import (
) )
type runContext struct { type runContext struct {
isRunning bool running bool
fps float64 fps float64
newScreenWidth int newScreenWidth int
newScreenHeight int newScreenHeight int
newScreenScale int newScreenScale int
isRunningSlowly bool runningSlowly bool
m sync.RWMutex m sync.RWMutex
} }
@ -37,19 +37,25 @@ var currentRunContext runContext
func (c *runContext) startRunning() { func (c *runContext) startRunning() {
c.m.Lock() c.m.Lock()
defer c.m.Unlock() defer c.m.Unlock()
c.isRunning = true c.running = true
}
func (c *runContext) isRunning() bool {
c.m.Lock()
defer c.m.Unlock()
return c.running
} }
func (c *runContext) endRunning() { func (c *runContext) endRunning() {
c.m.Lock() c.m.Lock()
defer c.m.Unlock() defer c.m.Unlock()
c.isRunning = false c.running = false
} }
func (c *runContext) FPS() float64 { func (c *runContext) FPS() float64 {
c.m.RLock() c.m.RLock()
defer c.m.RUnlock() defer c.m.RUnlock()
if !c.isRunning { if !c.running {
// TODO: Should panic here? // TODO: Should panic here?
return 0 return 0
} }
@ -65,17 +71,17 @@ func (c *runContext) updateFPS(fps float64) {
func (c *runContext) IsRunningSlowly() bool { func (c *runContext) IsRunningSlowly() bool {
c.m.RLock() c.m.RLock()
defer c.m.RUnlock() defer c.m.RUnlock()
if !c.isRunning { if !c.running {
// TODO: Should panic here? // TODO: Should panic here?
return false return false
} }
return c.isRunningSlowly return c.runningSlowly
} }
func (c *runContext) setRunningSlowly(isRunningSlowly bool) { func (c *runContext) setRunningSlowly(isRunningSlowly bool) {
c.m.Lock() c.m.Lock()
defer c.m.Unlock() defer c.m.Unlock()
c.isRunningSlowly = isRunningSlowly c.runningSlowly = isRunningSlowly
} }
func (c *runContext) updateScreenSize(g *graphicsContext) error { func (c *runContext) updateScreenSize(g *graphicsContext) error {
@ -108,7 +114,7 @@ func (c *runContext) updateScreenSize(g *graphicsContext) error {
func (c *runContext) SetScreenSize(width, height int) error { func (c *runContext) SetScreenSize(width, height int) error {
c.m.Lock() c.m.Lock()
defer c.m.Unlock() defer c.m.Unlock()
if !c.isRunning { if !c.running {
return errors.New("ebiten: SetScreenSize must be called during Run") return errors.New("ebiten: SetScreenSize must be called during Run")
} }
if width <= 0 || height <= 0 { if width <= 0 || height <= 0 {
@ -122,7 +128,7 @@ func (c *runContext) SetScreenSize(width, height int) error {
func (c *runContext) SetScreenScale(scale int) error { func (c *runContext) SetScreenScale(scale int) error {
c.m.Lock() c.m.Lock()
defer c.m.Unlock() defer c.m.Unlock()
if !c.isRunning { if !c.running {
return errors.New("ebiten: SetScreenScale must be called during Run") return errors.New("ebiten: SetScreenScale must be called during Run")
} }
if scale <= 0 { if scale <= 0 {