mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +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) {
|
func add(lhs, rhs, result affine) {
|
||||||
dim := lhs.dim()
|
dim := lhs.dim()
|
||||||
if dim != rhs.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++ {
|
for i := 0; i < dim-1; i++ {
|
||||||
@ -52,7 +52,7 @@ func add(lhs, rhs, result affine) {
|
|||||||
func mul(lhs, rhs, result affine) {
|
func mul(lhs, rhs, result affine) {
|
||||||
dim := lhs.dim()
|
dim := lhs.dim()
|
||||||
if dim != rhs.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++ {
|
for i := 0; i < dim-1; i++ {
|
||||||
|
@ -86,7 +86,7 @@ type textureQuads struct {
|
|||||||
func (t *textureQuads) vertices(vertices []int16) int {
|
func (t *textureQuads) vertices(vertices []int16) int {
|
||||||
l := t.parts.Len()
|
l := t.parts.Len()
|
||||||
if len(vertices) < l*16 {
|
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
|
p := t.parts
|
||||||
w, h := t.width, t.height
|
w, h := t.width, t.height
|
||||||
|
6
init.go
6
init.go
@ -22,5 +22,9 @@ import (
|
|||||||
var glContext *opengl.Context
|
var glContext *opengl.Context
|
||||||
|
|
||||||
func init() {
|
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
|
lastCompositeMode CompositeMode
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewContext() *Context {
|
func NewContext() (*Context, error) {
|
||||||
c := &Context{
|
c := &Context{
|
||||||
Nearest: gl.NEAREST,
|
Nearest: gl.NEAREST,
|
||||||
Linear: gl.LINEAR,
|
Linear: gl.LINEAR,
|
||||||
@ -74,7 +74,7 @@ func NewContext() *Context {
|
|||||||
c.locationCache = newLocationCache()
|
c.locationCache = newLocationCache()
|
||||||
c.funcs = make(chan func())
|
c.funcs = make(chan func())
|
||||||
c.lastCompositeMode = CompositeModeUnknown
|
c.lastCompositeMode = CompositeModeUnknown
|
||||||
return c
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) Loop() {
|
func (c *Context) Loop() {
|
||||||
@ -96,18 +96,24 @@ func (c *Context) RunOnContextThread(f func()) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) Init() {
|
func (c *Context) Init() error {
|
||||||
|
var err error
|
||||||
c.RunOnContextThread(func() {
|
c.RunOnContextThread(func() {
|
||||||
// This initialization must be done after Loop is called.
|
// This initialization must be done after Loop is called.
|
||||||
// This is why Init is separated from NewContext.
|
// This is why Init is separated from NewContext.
|
||||||
|
|
||||||
if err := gl.Init(); err != nil {
|
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.
|
// Textures' pixel formats are alpha premultiplied.
|
||||||
gl.Enable(gl.BLEND)
|
gl.Enable(gl.BLEND)
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
c.BlendFunc(CompositeModeSourceOver)
|
c.BlendFunc(CompositeModeSourceOver)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) BlendFunc(mode CompositeMode) {
|
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) {
|
func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (texture Texture, err error) {
|
||||||
c.RunOnContextThread(func() {
|
c.RunOnContextThread(func() {
|
||||||
var t uint32
|
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 {
|
func (c *Context) getAttribLocation(p Program, location string) attribLocation {
|
||||||
attrib := attribLocation(gl.GetAttribLocation(uint32(p), gl.Str(location+"\x00")))
|
attrib := attribLocation(gl.GetAttribLocation(uint32(p), gl.Str(location+"\x00")))
|
||||||
if attrib == -1 {
|
if attrib == -1 {
|
||||||
panic("invalid attrib location: " + location)
|
panic("opengl: invalid attrib location: " + location)
|
||||||
}
|
}
|
||||||
return attrib
|
return attrib
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ type context struct {
|
|||||||
lastCompositeMode CompositeMode
|
lastCompositeMode CompositeMode
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewContext() *Context {
|
func NewContext() (*Context, error) {
|
||||||
var gl *webgl.Context
|
var gl *webgl.Context
|
||||||
|
|
||||||
if js.Global.Get("require") == js.Undefined {
|
if js.Global.Get("require") == js.Undefined {
|
||||||
@ -82,7 +82,7 @@ func NewContext() *Context {
|
|||||||
PremultipliedAlpha: true,
|
PremultipliedAlpha: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: Now Ebiten with headless-gl doesn't work well (#141).
|
// TODO: Now Ebiten with headless-gl doesn't work well (#141).
|
||||||
@ -117,7 +117,7 @@ func NewContext() *Context {
|
|||||||
c.locationCache = newLocationCache()
|
c.locationCache = newLocationCache()
|
||||||
c.lastCompositeMode = CompositeModeUnknown
|
c.lastCompositeMode = CompositeModeUnknown
|
||||||
c.init()
|
c.init()
|
||||||
return c
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) init() {
|
func (c *Context) init() {
|
||||||
@ -138,13 +138,6 @@ func (c *Context) BlendFunc(mode CompositeMode) {
|
|||||||
gl.BlendFunc(int(s), int(d))
|
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) {
|
func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (Texture, error) {
|
||||||
gl := c.gl
|
gl := c.gl
|
||||||
t := gl.CreateTexture()
|
t := gl.CreateTexture()
|
||||||
|
@ -107,12 +107,6 @@ func (c *Context) RunOnContextThread(f func()) {
|
|||||||
return
|
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) {
|
func (c *Context) NewTexture(width, height int, pixels []uint8, filter Filter) (Texture, error) {
|
||||||
t := gl.CreateTexture()
|
t := gl.CreateTexture()
|
||||||
if t.Value <= 0 {
|
if t.Value <= 0 {
|
||||||
|
@ -18,7 +18,6 @@ package ui
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -48,12 +47,12 @@ func CurrentUI() *UserInterface {
|
|||||||
return currentUI
|
return currentUI
|
||||||
}
|
}
|
||||||
|
|
||||||
func Init() *opengl.Context {
|
func Init() (*opengl.Context, error) {
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
|
||||||
err := glfw.Init()
|
err := glfw.Init()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("glfw.Init() fails: %v", err))
|
return nil, err
|
||||||
}
|
}
|
||||||
glfw.WindowHint(glfw.Visible, glfw.False)
|
glfw.WindowHint(glfw.Visible, glfw.False)
|
||||||
glfw.WindowHint(glfw.Resizable, 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.
|
// As start, create an window with temporary size to create OpenGL context thread.
|
||||||
window, err := glfw.CreateWindow(16, 16, "", nil, nil)
|
window, err := glfw.CreateWindow(16, 16, "", nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
u := &UserInterface{
|
u := &UserInterface{
|
||||||
window: window,
|
window: window,
|
||||||
}
|
}
|
||||||
ch := make(chan struct{})
|
ch := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
u.window.MakeContextCurrent()
|
u.window.MakeContextCurrent()
|
||||||
glfw.SwapInterval(1)
|
glfw.SwapInterval(1)
|
||||||
u.context = opengl.NewContext()
|
var err error
|
||||||
|
u.context, err = opengl.NewContext()
|
||||||
|
if err != nil {
|
||||||
|
ch <- err
|
||||||
|
}
|
||||||
close(ch)
|
close(ch)
|
||||||
u.context.Loop()
|
u.context.Loop()
|
||||||
}()
|
}()
|
||||||
currentUI = u
|
currentUI = u
|
||||||
<-ch
|
if err := <-ch; err != nil {
|
||||||
u.context.Init()
|
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 {
|
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.
|
// Do nothing in node.js.
|
||||||
if js.Global.Get("require") != js.Undefined {
|
if js.Global.Get("require") != js.Undefined {
|
||||||
return opengl.NewContext()
|
return opengl.NewContext()
|
||||||
|
24
run.go
24
run.go
@ -15,6 +15,7 @@
|
|||||||
package ebiten
|
package ebiten
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -104,29 +105,31 @@ func (c *runContext) updateScreenSize(g *graphicsContext) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *runContext) SetScreenSize(width, height int) {
|
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.isRunning {
|
||||||
panic("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 {
|
||||||
panic("ebiten: width and height must be positive")
|
return errors.New("ebiten: width and height must be positive")
|
||||||
}
|
}
|
||||||
c.newScreenWidth = width
|
c.newScreenWidth = width
|
||||||
c.newScreenHeight = height
|
c.newScreenHeight = height
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *runContext) SetScreenScale(scale int) {
|
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.isRunning {
|
||||||
panic("ebiten: SetScreenScale must be called during Run")
|
return errors.New("ebiten: SetScreenScale must be called during Run")
|
||||||
}
|
}
|
||||||
if scale <= 0 {
|
if scale <= 0 {
|
||||||
panic("ebiten: scale must be positive")
|
return errors.New("ebiten: scale must be positive")
|
||||||
}
|
}
|
||||||
c.newScreenScale = scale
|
c.newScreenScale = scale
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FPS represents how many times game updating happens in a second.
|
// 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()
|
defer ui.CurrentUI().Terminate()
|
||||||
|
|
||||||
glContext.Check()
|
|
||||||
graphicsContext, err := newGraphicsContext(width, height, ui.CurrentUI().ActualScreenScale())
|
graphicsContext, err := newGraphicsContext(width, height, ui.CurrentUI().ActualScreenScale())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -238,14 +240,18 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
|
|||||||
//
|
//
|
||||||
// This function is concurrent-safe.
|
// This function is concurrent-safe.
|
||||||
func SetScreenSize(width, height int) {
|
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.
|
// SetScreenSize changes the scale of the screen.
|
||||||
//
|
//
|
||||||
// This function is concurrent-safe.
|
// This function is concurrent-safe.
|
||||||
func SetScreenScale(scale int) {
|
func SetScreenScale(scale int) {
|
||||||
currentRunContext.SetScreenScale(scale)
|
if err := currentRunContext.SetScreenScale(scale); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScreenScale returns the current screen scale.
|
// ScreenScale returns the current screen scale.
|
||||||
|
Loading…
Reference in New Issue
Block a user