mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
Reduce panics (#196)
This commit is contained in:
parent
e93982ffb5
commit
5a379cb7cb
@ -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++ {
|
||||
@ -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++ {
|
||||
|
@ -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
|
||||
|
6
init.go
6
init.go
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ type context struct {
|
||||
lastCompositeMode CompositeMode
|
||||
}
|
||||
|
||||
func NewContext() *Context {
|
||||
func NewContext() (*Context, error) {
|
||||
c := &Context{
|
||||
Nearest: gl.NEAREST,
|
||||
Linear: gl.LINEAR,
|
||||
@ -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() {
|
||||
@ -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) {
|
||||
@ -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
|
||||
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
@ -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).
|
||||
@ -117,7 +117,7 @@ func NewContext() *Context {
|
||||
c.locationCache = newLocationCache()
|
||||
c.lastCompositeMode = CompositeModeUnknown
|
||||
c.init()
|
||||
return c
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (c *Context) init() {
|
||||
@ -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()
|
||||
|
@ -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 {
|
||||
|
@ -18,7 +18,6 @@ package ui
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
@ -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)
|
||||
@ -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 {
|
||||
|
@ -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()
|
||||
|
24
run.go
24
run.go
@ -15,6 +15,7 @@
|
||||
package ebiten
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -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.
|
||||
@ -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
|
||||
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user