Skip to content

Commit

Permalink
Reduce panics (hajimehoshi#196)
Browse files Browse the repository at this point in the history
  • Loading branch information
hajimehoshi committed Apr 10, 2016
1 parent e93982f commit 5a379cb
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 52 deletions.
4 changes: 2 additions & 2 deletions affine.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func isIdentity(ebiten affine) bool {
func add(lhs, rhs, result affine) {
dim := lhs.dim()
if dim != rhs.dim() {
panic("diffrent-sized matrices can't be multiplied")
panic("ebiten: diffrent-sized matrices can't be multiplied")
}

for i := 0; i < dim-1; i++ {
Expand All @@ -52,7 +52,7 @@ func add(lhs, rhs, result affine) {
func mul(lhs, rhs, result affine) {
dim := lhs.dim()
if dim != rhs.dim() {
panic("diffrent-sized matrices can't be multiplied")
panic("ebiten: diffrent-sized matrices can't be multiplied")
}

for i := 0; i < dim-1; i++ {
Expand Down
2 changes: 1 addition & 1 deletion imageparts.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ type textureQuads struct {
func (t *textureQuads) vertices(vertices []int16) int {
l := t.parts.Len()
if len(vertices) < l*16 {
panic(fmt.Sprintf("graphics: vertices size must be greater than %d but %d", l*16, len(vertices)))
panic(fmt.Sprintf("ebiten: vertices size must be greater than %d but %d", l*16, len(vertices)))
}
p := t.parts
w, h := t.width, t.height
Expand Down
6 changes: 5 additions & 1 deletion init.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,9 @@ import (
var glContext *opengl.Context

func init() {
glContext = ui.Init()
var err error
glContext, err = ui.Init()
if err != nil {
panic(err)
}
}
24 changes: 11 additions & 13 deletions internal/graphics/opengl/context_desktop.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ type context struct {
lastCompositeMode CompositeMode
}

func NewContext() *Context {
func NewContext() (*Context, error) {
c := &Context{
Nearest: gl.NEAREST,
Linear: gl.LINEAR,
Expand All @@ -74,7 +74,7 @@ func NewContext() *Context {
c.locationCache = newLocationCache()
c.funcs = make(chan func())
c.lastCompositeMode = CompositeModeUnknown
return c
return c, nil
}

func (c *Context) Loop() {
Expand All @@ -96,18 +96,24 @@ func (c *Context) RunOnContextThread(f func()) {
return
}

func (c *Context) Init() {
func (c *Context) Init() error {
var err error
c.RunOnContextThread(func() {
// This initialization must be done after Loop is called.
// This is why Init is separated from NewContext.

if err := gl.Init(); err != nil {
panic(fmt.Sprintf("opengl: initializing error %v", err))
err = fmt.Errorf("opengl: initializing error %v", err)
return
}
// Textures' pixel formats are alpha premultiplied.
gl.Enable(gl.BLEND)
})
if err != nil {
return err
}
c.BlendFunc(CompositeModeSourceOver)
return nil
}

func (c *Context) BlendFunc(mode CompositeMode) {
Expand All @@ -121,14 +127,6 @@ func (c *Context) BlendFunc(mode CompositeMode) {
})
}

func (c *Context) Check() {
c.RunOnContextThread(func() {
if e := gl.GetError(); e != gl.NO_ERROR {
panic(fmt.Sprintf("check failed: %d", e))
}
})
}

func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (texture Texture, err error) {
c.RunOnContextThread(func() {
var t uint32
Expand Down Expand Up @@ -364,7 +362,7 @@ func (c *Context) UniformFloats(p Program, location string, v []float32) {
func (c *Context) getAttribLocation(p Program, location string) attribLocation {
attrib := attribLocation(gl.GetAttribLocation(uint32(p), gl.Str(location+"\x00")))
if attrib == -1 {
panic("invalid attrib location: " + location)
panic("opengl: invalid attrib location: " + location)
}
return attrib
}
Expand Down
13 changes: 3 additions & 10 deletions internal/graphics/opengl/context_js.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ type context struct {
lastCompositeMode CompositeMode
}

func NewContext() *Context {
func NewContext() (*Context, error) {
var gl *webgl.Context

if js.Global.Get("require") == js.Undefined {
Expand All @@ -82,7 +82,7 @@ func NewContext() *Context {
PremultipliedAlpha: true,
})
if err != nil {
panic(err)
return nil, err
}
} else {
// TODO: Now Ebiten with headless-gl doesn't work well (#141).
Expand Down Expand Up @@ -117,7 +117,7 @@ func NewContext() *Context {
c.locationCache = newLocationCache()
c.lastCompositeMode = CompositeModeUnknown
c.init()
return c
return c, nil
}

func (c *Context) init() {
Expand All @@ -138,13 +138,6 @@ func (c *Context) BlendFunc(mode CompositeMode) {
gl.BlendFunc(int(s), int(d))
}

func (c *Context) Check() {
gl := c.gl
if e := gl.GetError(); e != gl.NO_ERROR {
panic(fmt.Sprintf("opengl: check failed: %d", e))
}
}

func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (Texture, error) {
gl := c.gl
t := gl.CreateTexture()
Expand Down
6 changes: 0 additions & 6 deletions internal/graphics/opengl/context_mobile.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,6 @@ func (c *Context) RunOnContextThread(f func()) {
return
}

func (c *Context) Check() {
if e := gl.GetError(); e != mgl.NO_ERROR {
panic(fmt.Sprintf("check failed: %d", e))
}
}

func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (Texture, error) {
t := gl.CreateTexture()
if t.Value <= 0 {
Expand Down
25 changes: 16 additions & 9 deletions internal/ui/ui_glfw.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package ui

import (
"errors"
"fmt"
"runtime"
"sync"
"time"
Expand Down Expand Up @@ -48,12 +47,12 @@ func CurrentUI() *UserInterface {
return currentUI
}

func Init() *opengl.Context {
func Init() (*opengl.Context, error) {
runtime.LockOSThread()

err := glfw.Init()
if err != nil {
panic(fmt.Sprintf("glfw.Init() fails: %v", err))
return nil, err
}
glfw.WindowHint(glfw.Visible, glfw.False)
glfw.WindowHint(glfw.Resizable, glfw.False)
Expand All @@ -63,26 +62,34 @@ func Init() *opengl.Context {
// As start, create an window with temporary size to create OpenGL context thread.
window, err := glfw.CreateWindow(16, 16, "", nil, nil)
if err != nil {
panic(err)
return nil, err
}

u := &UserInterface{
window: window,
}
ch := make(chan struct{})
ch := make(chan error)
go func() {
runtime.LockOSThread()
u.window.MakeContextCurrent()
glfw.SwapInterval(1)
u.context = opengl.NewContext()
var err error
u.context, err = opengl.NewContext()
if err != nil {
ch <- err
}
close(ch)
u.context.Loop()
}()
currentUI = u
<-ch
u.context.Init()
if err := <-ch; err != nil {
return nil, err
}
if err := u.context.Init(); err != nil {
return nil, err
}

return u.context
return u.context, nil
}

func (u *UserInterface) SetScreenSize(width, height int) bool {
Expand Down
2 changes: 1 addition & 1 deletion internal/ui/ui_js.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func (u *UserInterface) SwapBuffers() {
}
}

func Init() *opengl.Context {
func Init() (*opengl.Context, error) {
// Do nothing in node.js.
if js.Global.Get("require") != js.Undefined {
return opengl.NewContext()
Expand Down
24 changes: 15 additions & 9 deletions run.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package ebiten

import (
"errors"
"sync"
"time"

Expand Down Expand Up @@ -104,29 +105,31 @@ func (c *runContext) updateScreenSize(g *graphicsContext) error {
return nil
}

func (c *runContext) SetScreenSize(width, height int) {
func (c *runContext) SetScreenSize(width, height int) error {
c.m.Lock()
defer c.m.Unlock()
if !c.isRunning {
panic("ebiten: SetScreenSize must be called during Run")
return errors.New("ebiten: SetScreenSize must be called during Run")
}
if width <= 0 || height <= 0 {
panic("ebiten: width and height must be positive")
return errors.New("ebiten: width and height must be positive")
}
c.newScreenWidth = width
c.newScreenHeight = height
return nil
}

func (c *runContext) SetScreenScale(scale int) {
func (c *runContext) SetScreenScale(scale int) error {
c.m.Lock()
defer c.m.Unlock()
if !c.isRunning {
panic("ebiten: SetScreenScale must be called during Run")
return errors.New("ebiten: SetScreenScale must be called during Run")
}
if scale <= 0 {
panic("ebiten: scale must be positive")
return errors.New("ebiten: scale must be positive")
}
c.newScreenScale = scale
return nil
}

// FPS represents how many times game updating happens in a second.
Expand Down Expand Up @@ -172,7 +175,6 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
}
defer ui.CurrentUI().Terminate()

glContext.Check()
graphicsContext, err := newGraphicsContext(width, height, ui.CurrentUI().ActualScreenScale())
if err != nil {
return err
Expand Down Expand Up @@ -238,14 +240,18 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
//
// This function is concurrent-safe.
func SetScreenSize(width, height int) {
currentRunContext.SetScreenSize(width, height)
if err := currentRunContext.SetScreenSize(width, height); err != nil {
panic(err)
}
}

// SetScreenSize changes the scale of the screen.
//
// This function is concurrent-safe.
func SetScreenScale(scale int) {
currentRunContext.SetScreenScale(scale)
if err := currentRunContext.SetScreenScale(scale); err != nil {
panic(err)
}
}

// ScreenScale returns the current screen scale.
Expand Down

0 comments on commit 5a379cb

Please sign in to comment.