diff --git a/audio/audio.go b/audio/audio.go index 1af03c037..fa9f4cef0 100644 --- a/audio/audio.go +++ b/audio/audio.go @@ -320,7 +320,7 @@ func NewPlayerFromBytes(context *Context, src []byte) (*Player, error) { p, err := NewPlayer(context, b) if err != nil { // Errors should never happen. - panic(err) + panic(fmt.Sprintf("audio: %v at NewPlayerFromBytes", err)) } return p, nil } @@ -418,7 +418,7 @@ func (p *playerImpl) readLoop() { case s := <-p.seekCh: seeker, ok := p.src.(io.Seeker) if !ok { - panic("not reached") + panic("audio: the source must be io.Seeker when seeking") } pos, err := seeker.Seek(s.offset, s.whence) p.buf = nil diff --git a/audio/loop.go b/audio/loop.go index 8e07e85f1..fee14e4a8 100644 --- a/audio/loop.go +++ b/audio/loop.go @@ -75,7 +75,7 @@ func (i *InfiniteLoop) Read(b []byte) (int, error) { n, err := i.src.Read(b) i.pos += int64(n) if i.pos > i.length() { - panic("not reached") + panic(fmt.Sprintf("audio: position must be <= length but not at (*InfiniteLoop).Read: pos: %d, length: %d", i.pos, i.length())) } if err != nil && err != io.EOF { diff --git a/audio/vorbis/internal/stb/decode.go b/audio/vorbis/internal/stb/decode.go index 9b54cd43f..03dcc1340 100644 --- a/audio/vorbis/internal/stb/decode.go +++ b/audio/vorbis/internal/stb/decode.go @@ -69,7 +69,7 @@ func (s *Samples) Read(buf []float32) (int, error) { start = 0 } if len(s.samples[idx]) == 0 { - panic("not reached") + panic(fmt.Sprintf("stb: len(samples[%d]) must be > 0", idx)) } n := copy(buf, s.samples[idx][start:]) s.posInSamples += int64(n) / int64(s.channels) diff --git a/graphicscontext.go b/graphicscontext.go index 95e22913c..484ce076d 100644 --- a/graphicscontext.go +++ b/graphicscontext.go @@ -15,6 +15,7 @@ package ebiten import ( + "fmt" "math" "github.com/hajimehoshi/ebiten/internal/clock" @@ -121,7 +122,7 @@ func (c *graphicsContext) Update(afterFrameUpdate func()) error { op := &DrawImageOptions{} - switch graphicscommand.Driver().VDirection() { + switch vd := graphicscommand.Driver().VDirection(); vd { case graphicsdriver.VDownward: // c.screen is special: its Y axis is down to up, // and the origin point is lower left. @@ -130,7 +131,7 @@ func (c *graphicsContext) Update(afterFrameUpdate func()) error { case graphicsdriver.VUpward: op.GeoM.Scale(c.screenScale, c.screenScale) default: - panic("not reached") + panic(fmt.Sprintf("ebiten: invalid v-direction: %d", vd)) } op.GeoM.Translate(c.offsetX, c.offsetY) diff --git a/image.go b/image.go index 38eeca93a..575b95f3d 100644 --- a/image.go +++ b/image.go @@ -44,7 +44,7 @@ func (m *mipmap) original() *shareable.Image { func (m *mipmap) level(r image.Rectangle, level int) *shareable.Image { if level == 0 { - panic("not reached") + panic("ebiten: level must not be 0 (original image) at level") } imgs, ok := m.imgs[r] @@ -182,7 +182,7 @@ func (i *Image) Fill(clr color.Color) error { // TODO: Implement this. if i.isSubimage() { - panic("render to a subimage is not implemented") + panic("ebiten: render to a subimage is not implemented (Fill)") } i.resolvePixelsToSet(false) @@ -196,7 +196,7 @@ func (i *Image) Fill(clr color.Color) error { func (i *Image) disposeMipmaps() { if i.isDisposed() { - panic("not reached") + panic("ebiten: the image is already disposed at disposeMipmap") } i.mipmap.disposeMipmaps() } @@ -254,7 +254,7 @@ func (i *Image) drawImage(img *Image, options *DrawImageOptions) { // TODO: Implement this. if i.isSubimage() { - panic("render to a subimage is not implemented") + panic("ebiten: render to a subimage is not implemented (drawImage)") } img.resolvePixelsToSet(true) @@ -326,7 +326,7 @@ func (i *Image) drawImage(img *Image, options *DrawImageOptions) { } level = graphics.MipmapLevel(det) if level < 0 { - panic("not reached") + panic(fmt.Sprintf("ebiten: level must be >= 0 but %d", level)) } } if level > 6 { @@ -443,7 +443,7 @@ func (i *Image) DrawTriangles(vertices []Vertex, indices []uint16, img *Image, o } if i.isSubimage() { - panic("render to a subimage is not implemented") + panic("ebiten: render to a subimage is not implemented (DrawTriangles)") } img.resolvePixelsToSet(true) @@ -663,7 +663,7 @@ func (i *Image) ReplacePixels(p []byte) error { } // TODO: Implement this. if i.isSubimage() { - panic("render to a subimage is not implemented") + panic("ebiten: render to a subimage is not implemented (ReplacePixels)") } i.resolvePixelsToSet(false) s := i.Bounds().Size() diff --git a/internal/graphics/compositemode.go b/internal/graphics/compositemode.go index c649aa966..d3a1d4845 100644 --- a/internal/graphics/compositemode.go +++ b/internal/graphics/compositemode.go @@ -14,6 +14,10 @@ package graphics +import ( + "fmt" +) + type CompositeMode int const ( @@ -75,6 +79,6 @@ func (c CompositeMode) Operations() (src Operation, dst Operation) { case CompositeModeLighter: return One, One default: - panic("not reached") + panic(fmt.Sprintf("graphics: invalid composite mode: %d", c)) } } diff --git a/internal/graphics/vertices.go b/internal/graphics/vertices.go index 48dd1fbd7..d26a2abb9 100644 --- a/internal/graphics/vertices.go +++ b/internal/graphics/vertices.go @@ -15,6 +15,7 @@ package graphics import ( + "fmt" "sync" ) @@ -36,7 +37,7 @@ const ( func (v *verticesBackend) slice(n int) []float32 { const num = 1024 if n > num { - panic("not reached") + panic(fmt.Sprintf("graphics: n must be <= num but not: n: %d, num: %d", n, num)) } v.m.Lock() @@ -67,10 +68,10 @@ func isPowerOf2(x int) bool { func QuadVertices(width, height int, sx0, sy0, sx1, sy1 int, a, b, c, d, tx, ty float32, cr, cg, cb, ca float32) []float32 { if !isPowerOf2(width) { - panic("not reached") + panic(fmt.Sprintf("graphics: width must be power of 2 but not at QuadVertices: %d", width)) } if !isPowerOf2(height) { - panic("not reached") + panic(fmt.Sprintf("graphics: height must be power of 2 but not at QuadVertices: %d", height)) } if sx0 >= sx1 || sy0 >= sy1 { @@ -166,10 +167,10 @@ func QuadIndices() []uint16 { func PutVertex(vs []float32, width, height int, dx, dy, su, sv float32, u0, v0, u1, v1 float32, cr, cg, cb, ca float32) { if !isPowerOf2(width) { - panic("not reached") + panic(fmt.Sprintf("graphics: width must be power of 2 but not at PutVertices: %d", width)) } if !isPowerOf2(height) { - panic("not reached") + panic(fmt.Sprintf("graphics: height must be power of 2 but not at PutVertices: %d", height)) } vs[0] = dx diff --git a/internal/graphicscommand/command.go b/internal/graphicscommand/command.go index 8532ffae5..d36fface0 100644 --- a/internal/graphicscommand/command.go +++ b/internal/graphicscommand/command.go @@ -89,7 +89,7 @@ func (q *commandQueue) appendIndices(indices []uint16, offset uint16) { func (q *commandQueue) doEnqueueDrawImageCommand(dst, src *Image, nvertices, nindices int, color *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address, forceNewCommand bool) { if nindices > graphics.IndicesNum { - panic("not reached") + panic(fmt.Sprintf("graphicscommand: nindices must be <= graphics.IndicesNum but not at doEnqueueDrawImageCommand: nindices: %d, graphics.IndicesNum: %d", nindices, graphics.IndicesNum)) } if !forceNewCommand && 0 < len(q.commands) { if last := q.commands[len(q.commands)-1]; last.CanMerge(dst, src, color, mode, filter, address) { @@ -114,7 +114,7 @@ func (q *commandQueue) doEnqueueDrawImageCommand(dst, src *Image, nvertices, nin // EnqueueDrawImageCommand enqueues a drawing-image command. func (q *commandQueue) EnqueueDrawImageCommand(dst, src *Image, vertices []float32, indices []uint16, color *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) { if len(indices) > graphics.IndicesNum { - panic("not reached") + panic(fmt.Sprintf("graphicscommand: len(indices) must be <= graphics.IndicesNum but not at EnqueueDrawImageCommand: len(indices): %d, graphics.IndicesNum: %d", len(indices), graphics.IndicesNum)) } split := false @@ -156,7 +156,7 @@ func (q *commandQueue) Flush() { nc := 0 for _, c := range q.commands { if c.NumIndices() > graphics.IndicesNum { - panic("not reached") + panic(fmt.Sprintf("graphicscommand: c.NumIndices() must be <= graphics.IndicesNum but not at Flush: c.NumIndices(): %d, graphics.IndicesNum: %d", c.NumIndices(), graphics.IndicesNum)) } if ne+c.NumIndices() > graphics.IndicesNum { break diff --git a/internal/graphicsdriver/metal/driver.go b/internal/graphicsdriver/metal/driver.go index 61802c802..97b865fc3 100644 --- a/internal/graphicsdriver/metal/driver.go +++ b/internal/graphicsdriver/metal/driver.go @@ -460,7 +460,7 @@ func (d *Driver) Reset() error { case graphics.OneMinusDstAlpha: return mtl.BlendFactorOneMinusDestinationAlpha default: - panic("not reached") + panic(fmt.Sprintf("metal: invalid operation: %d", c)) } } @@ -627,7 +627,7 @@ func (i *Image) IsInvalidated() bool { func (i *Image) syncTexture() { mainthread.Run(func() error { if i.driver.cb != (mtl.CommandBuffer{}) { - panic("not reached") + panic("metal: command buffer must be empty at syncTexture: flush is not called yet?") } cb := i.driver.cq.MakeCommandBuffer() diff --git a/internal/graphicsdriver/opengl/context.go b/internal/graphicsdriver/opengl/context.go index 6ef3da970..e56572855 100644 --- a/internal/graphicsdriver/opengl/context.go +++ b/internal/graphicsdriver/opengl/context.go @@ -15,6 +15,8 @@ package opengl import ( + "fmt" + "github.com/hajimehoshi/ebiten/internal/graphics" ) @@ -33,7 +35,7 @@ func convertOperation(op graphics.Operation) operation { case graphics.OneMinusDstAlpha: return oneMinusDstAlpha default: - panic("not reached") + panic(fmt.Sprintf("opengl: invalid operation %d at convertOperation", op)) } } diff --git a/internal/graphicsdriver/opengl/context_desktop.go b/internal/graphicsdriver/opengl/context_desktop.go index 4b8ec2e12..f2dbbdc92 100644 --- a/internal/graphicsdriver/opengl/context_desktop.go +++ b/internal/graphicsdriver/opengl/context_desktop.go @@ -391,7 +391,7 @@ func (c *context) uniformFloats(p program, location string, v []float32) { case 16: gl.UniformMatrix4fv(l, 1, false, (*float32)(gl.Ptr(v))) default: - panic("not reached") + panic(fmt.Sprintf("opengl: invalid uniform floats num: %d", len(v))) } return nil }) diff --git a/internal/graphicsdriver/opengl/context_js.go b/internal/graphicsdriver/opengl/context_js.go index 817a8edf7..ddd13f3cc 100644 --- a/internal/graphicsdriver/opengl/context_js.go +++ b/internal/graphicsdriver/opengl/context_js.go @@ -374,7 +374,7 @@ func (c *context) uniformFloats(p program, location string, v []float32) { gl.Call("uniformMatrix4fv", js.Value(l), false, arr) arr.Release() default: - panic("not reached") + panic(fmt.Sprintf("opengl: invalid uniform floats num: %d", len(v))) } } diff --git a/internal/graphicsdriver/opengl/context_mobile.go b/internal/graphicsdriver/opengl/context_mobile.go index e609144b6..f514ef58d 100644 --- a/internal/graphicsdriver/opengl/context_mobile.go +++ b/internal/graphicsdriver/opengl/context_mobile.go @@ -75,7 +75,7 @@ type contextImpl struct { func (c *context) doWork(chDone <-chan struct{}) error { if c.worker == nil { - panic("not reached") + panic("opengl: worker must be initialized but not") } // TODO: Check this is called on the rendering thread workAvailable := c.worker.WorkAvailable() @@ -307,7 +307,7 @@ func (c *context) uniformFloats(p program, location string, v []float32) { case 16: gl.UniformMatrix4fv(l, v) default: - panic("not reached") + panic(fmt.Sprintf("opengl: invalid uniform floats num: %d", len(v))) } } diff --git a/internal/graphicsdriver/opengl/image.go b/internal/graphicsdriver/opengl/image.go index b3b6dd828..0bb5e58a2 100644 --- a/internal/graphicsdriver/opengl/image.go +++ b/internal/graphicsdriver/opengl/image.go @@ -87,8 +87,7 @@ func (i *Image) ensureFramebuffer() error { func (i *Image) ReplacePixels(p []byte, x, y, width, height int) { if i.screen { - // The screen image doesn't have a texture to replace pixels. - panic("not reached") + panic("opengl: ReplacePixels cannot be called on the screen, that doesn't have a texture") } // glFlush is necessary on Android. diff --git a/internal/graphicsdriver/opengl/shader.go b/internal/graphicsdriver/opengl/shader.go index 9808847ff..934348c09 100644 --- a/internal/graphicsdriver/opengl/shader.go +++ b/internal/graphicsdriver/opengl/shader.go @@ -80,7 +80,7 @@ func shaderStr(id shaderID) string { src = strings.Replace(src, k, v, -1) } default: - panic("not reached") + panic(fmt.Sprintf("opengl: invalid shader id: %d", id)) } checkGLSL(src) diff --git a/internal/graphicsdriver/opengl/types.go b/internal/graphicsdriver/opengl/types.go index 8ca2d01f5..86692efd4 100644 --- a/internal/graphicsdriver/opengl/types.go +++ b/internal/graphicsdriver/opengl/types.go @@ -14,6 +14,10 @@ package opengl +import ( + "fmt" +) + type ( shaderType int bufferType int @@ -30,6 +34,6 @@ func (d dataType) SizeInBytes() int { case float: return 4 default: - panic("not reached") + panic(fmt.Sprintf("opengl: invalid data type: %d", d)) } } diff --git a/internal/packing/packing.go b/internal/packing/packing.go index d2488ce08..596f683d8 100644 --- a/internal/packing/packing.go +++ b/internal/packing/packing.go @@ -130,7 +130,7 @@ func (p *Page) alloc(n *Node, width, height int) *Node { return p.alloc(n.child0, width, height) } if n.child0 == nil || n.child1 == nil { - panic("not reached") + panic("packing: both two children must not be nil at alloc") } if node := p.alloc(n.child0, width, height); node != nil { return node @@ -174,7 +174,7 @@ func (p *Page) Free(node *Node) { return } if node.parent.child0 == nil || node.parent.child1 == nil { - panic("not reached: double free?") + panic("packing: both two children must not be nil at Free: double free happened?") } if node.parent.child0.canFree() && node.parent.child1.canFree() { node.parent.child0 = nil diff --git a/internal/restorable/image.go b/internal/restorable/image.go index 0a325c474..89653845c 100644 --- a/internal/restorable/image.go +++ b/internal/restorable/image.go @@ -102,7 +102,7 @@ func NewScreenFramebufferImage(width, height int) *Image { func (i *Image) clear() { if i.priority { - panic("not reached") + panic("restorable: clear cannot be called on a priority image") } // There are not 'drawImageHistoryItem's for this image and dummyImage. @@ -250,7 +250,7 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) { // DrawImage draws a given image img to the image. func (i *Image) DrawImage(img *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) { if i.priority { - panic("not reached") + panic("restorable: DrawImage cannot be called on a priority image") } if len(vertices) == 0 { return @@ -412,9 +412,8 @@ func (i *Image) restore() error { gimg.ReplacePixels(pix, 0, 0, w, h) } for _, c := range i.drawImageHistory { - // All dependencies must be already resolved. if c.image.hasDependency() { - panic("not reached") + panic("restorable: all dependencies must be already resolved but not") } gimg.DrawImage(c.image.image, c.vertices, c.indices, c.colorm, c.mode, c.filter, c.address) } diff --git a/internal/restorable/images.go b/internal/restorable/images.go index 6b7df54bb..42e2348d6 100644 --- a/internal/restorable/images.go +++ b/internal/restorable/images.go @@ -131,7 +131,7 @@ func (i *images) makeStaleIfDependingOn(target *Image) { func (i *images) makeStaleIfDependingOnImpl(target *Image) { if target == nil { - panic("not reached") + panic("restorable: target must not be nil at makeStaleIfDependingOnImpl") } if i.lastTarget == target { return @@ -147,7 +147,7 @@ func (i *images) makeStaleIfDependingOnImpl(target *Image) { // Restoring means to make all *graphicscommand.Image objects have their textures and framebuffers. func (i *images) restore() error { if !IsRestoringEnabled() { - panic("not reached") + panic("restorable: restore cannot be called when restoring is disabled") } // Dispose image explicitly diff --git a/internal/shareable/shareable.go b/internal/shareable/shareable.go index a1a2ca06b..9058d9743 100644 --- a/internal/shareable/shareable.go +++ b/internal/shareable/shareable.go @@ -15,6 +15,7 @@ package shareable import ( + "fmt" "image" "runtime" "sync" @@ -71,7 +72,7 @@ func (b *backend) TryAlloc(width, height int) (*packing.Node, bool) { n := b.page.Alloc(width, height) if n == nil { - panic("not reached") + panic("shareable: Alloc result must not be nil at TryAlloc") } return n, true } @@ -150,7 +151,7 @@ func (i *Image) forceShared() { } if !i.shareable() { - panic("not reached") + panic("shareable: forceShared cannot be called on a non-shareable image") } newI := NewImage(i.width, i.height) @@ -171,7 +172,7 @@ func (i *Image) forceShared() { func (i *Image) region() (x, y, width, height int) { if i.backend == nil { - panic("not reached") + panic("shareable: backend must not be nil: not allocated yet?") } if !i.isShared() { w, h := i.backend.restorable.Size() @@ -304,7 +305,7 @@ func (i *Image) replacePixels(p []byte) { x, y, w, h := i.region() if p != nil { if l := 4 * w * h; len(p) != l { - panic("not reached") + panic(fmt.Sprintf("shareable: len(p) must be %d but %d", l, len(p))) } } i.backend.restorable.ReplacePixels(p, x, y, w, h) @@ -379,7 +380,7 @@ func (i *Image) dispose(markDisposed bool) { } } if index == -1 { - panic("not reached") + panic("shareable: backend not found at an image being disposed") } theBackends = append(theBackends[:index], theBackends[index+1:]...) } @@ -418,7 +419,7 @@ func (i *Image) shareable() bool { func (i *Image) allocate(shareable bool) { if i.backend != nil { - panic("not reached") + panic("shareable: the image is already allocated") } if !shareable || !i.shareable() { @@ -440,7 +441,7 @@ func (i *Image) allocate(shareable bool) { size := initSize for i.width > size || i.height > size { if size == maxSize { - panic("not reached") + panic(fmt.Sprintf("shareable: the image being shared is too big: width: %d, height: %d", i.width, i.height)) } size *= 2 } @@ -453,7 +454,7 @@ func (i *Image) allocate(shareable bool) { n := b.page.Alloc(i.width, i.height) if n == nil { - panic("not reached") + panic("shareable: Alloc result must not be nil at allocate") } i.backend = b i.node = n diff --git a/internal/ui/ui_glfw.go b/internal/ui/ui_glfw.go index e18cc4f2b..fd135af13 100644 --- a/internal/ui/ui_glfw.go +++ b/internal/ui/ui_glfw.go @@ -280,7 +280,7 @@ func SetScreenSize(width, height int) { panic("ui: Run is not called yet") } _ = mainthread.Run(func() error { - u.setScreenSize(width, height, u.scale, u.fullscreen(), u.vsync) + u.setScreenSize(width, height, u.scale, u.isFullscreen(), u.vsync) return nil }) } @@ -292,7 +292,7 @@ func SetScreenScale(scale float64) bool { } r := false _ = mainthread.Run(func() error { - r = u.setScreenSize(u.width, u.height, scale, u.fullscreen(), u.vsync) + r = u.setScreenSize(u.width, u.height, scale, u.isFullscreen(), u.vsync) return nil }) return r @@ -311,10 +311,10 @@ func ScreenScale() float64 { return s } -// fullscreen must be called from the main thread. -func (u *userInterface) fullscreen() bool { +// isFullscreen must be called from the main thread. +func (u *userInterface) isFullscreen() bool { if !u.isRunning() { - panic("not reached") + panic("ui: the game must be running at isFullscreen") } return u.window.GetMonitor() != nil } @@ -326,7 +326,7 @@ func IsFullscreen() bool { } b := false _ = mainthread.Run(func() error { - b = u.fullscreen() + b = u.isFullscreen() return nil }) return b @@ -367,7 +367,7 @@ func SetVsyncEnabled(enabled bool) { } _ = mainthread.Run(func() error { u := currentUI - u.setScreenSize(u.width, u.height, u.scale, u.fullscreen(), enabled) + u.setScreenSize(u.width, u.height, u.scale, u.isFullscreen(), enabled) return nil }) } @@ -646,7 +646,7 @@ func Run(width, height int, scale float64, title string, g GraphicsContext, main s := glfwScale() w := int(float64(width) / u.scale / s) h := int(float64(height) / u.scale / s) - if u.fullscreen() { + if u.isFullscreen() { return } u.reqWidth = w @@ -673,7 +673,7 @@ func (u *userInterface) glfwSize() (int, int) { // getScale must be called from the main thread. func (u *userInterface) getScale() float64 { - if !u.fullscreen() { + if !u.isFullscreen() { return u.scale } if u.fullscreenScale == 0 { @@ -711,7 +711,7 @@ func (u *userInterface) updateGraphicsContext(g GraphicsContext) { _ = mainthread.Run(func() error { actualScale = u.actualScreenScale() if u.lastActualScale != actualScale { - u.forceSetScreenSize(u.width, u.height, u.scale, u.fullscreen(), u.vsync) + u.forceSetScreenSize(u.width, u.height, u.scale, u.isFullscreen(), u.vsync) } u.lastActualScale = actualScale @@ -777,7 +777,7 @@ func (u *userInterface) update(g GraphicsContext) error { _ = mainthread.Run(func() error { w, h := u.reqWidth, u.reqHeight if w != 0 || h != 0 { - u.setScreenSize(w, h, u.scale, u.fullscreen(), u.vsync) + u.setScreenSize(w, h, u.scale, u.isFullscreen(), u.vsync) } u.reqWidth = 0 u.reqHeight = 0 @@ -822,7 +822,7 @@ func (u *userInterface) swapBuffers() { // setScreenSize must be called from the main thread. func (u *userInterface) setScreenSize(width, height int, scale float64, fullscreen bool, vsync bool) bool { - if u.width == width && u.height == height && u.scale == scale && u.fullscreen() == fullscreen && u.vsync == vsync { + if u.width == width && u.height == height && u.scale == scale && u.isFullscreen() == fullscreen && u.vsync == vsync { return false } u.forceSetScreenSize(width, height, scale, fullscreen, vsync) diff --git a/mobile/touches_ios.go b/mobile/touches_ios.go index 3f0afaa3a..b644dd8de 100644 --- a/mobile/touches_ios.go +++ b/mobile/touches_ios.go @@ -16,6 +16,10 @@ package mobile +import ( + "fmt" +) + // #cgo CFLAGS: -x objective-c // #cgo LDFLAGS: -framework Foundation -framework UIKit // @@ -55,6 +59,6 @@ func updateTouchesOnIOSImpl(phase int, ptr int64, x, y int) { delete(touches, id) updateTouches() default: - panic("not reached") + panic(fmt.Sprintf("mobile: invalid phase: %d", phase)) } }