ui: Add CurrentUI()

This commit is contained in:
Hajime Hoshi 2016-03-25 00:38:30 +09:00
parent 6ac6b8e7c0
commit fb3bf4e3b4
3 changed files with 67 additions and 98 deletions

View File

@ -30,7 +30,21 @@ func Now() int64 {
return time.Now().UnixNano() return time.Now().UnixNano()
} }
var currentUI *userInterface type UserInterface struct {
window *glfw.Window
width int
height int
scale int
deviceScale float64
framebufferScale int
context *opengl.Context
}
var currentUI *UserInterface
func CurrentUI() *UserInterface {
return currentUI
}
func Init() *opengl.Context { func Init() *opengl.Context {
runtime.LockOSThread() runtime.LockOSThread()
@ -50,7 +64,7 @@ func Init() *opengl.Context {
panic(err) panic(err)
} }
u := &userInterface{ u := &UserInterface{
window: window, window: window,
} }
ch := make(chan struct{}) ch := make(chan struct{})
@ -69,53 +83,23 @@ func Init() *opengl.Context {
return u.context return u.context
} }
func Start(width, height, scale int, title string) error { func (u *UserInterface) SetScreenSize(width, height int) bool {
return currentUI.start(width, height, scale, title) return u.setScreenSize(width, height, currentUI.scale)
} }
func Terminate() { func (u *UserInterface) SetScreenScale(scale int) bool {
currentUI.terminate() return u.setScreenSize(currentUI.width, currentUI.height, scale)
} }
func DoEvents() error { func (u *UserInterface) ScreenScale() int {
return currentUI.doEvents() return u.scale
} }
func IsClosed() bool { func (u *UserInterface) ActualScreenScale() int {
return currentUI.isClosed() return u.actualScreenScale()
} }
func SwapBuffers() { func (u *UserInterface) Start(width, height, scale int, title string) error {
currentUI.swapBuffers()
}
func SetScreenSize(width, height int) bool {
return currentUI.setScreenSize(width, height, currentUI.scale)
}
func SetScreenScale(scale int) bool {
return currentUI.setScreenSize(currentUI.width, currentUI.height, scale)
}
func ScreenScale() int {
return currentUI.scale
}
func ActualScreenScale() int {
return currentUI.actualScreenScale()
}
type userInterface struct {
window *glfw.Window
width int
height int
scale int
deviceScale float64
framebufferScale int
context *opengl.Context
}
func (u *userInterface) start(width, height, scale int, title string) error {
m := glfw.GetPrimaryMonitor() m := glfw.GetPrimaryMonitor()
v := m.GetVideoMode() v := m.GetVideoMode()
mw, _ := m.GetPhysicalSize() mw, _ := m.GetPhysicalSize()
@ -143,20 +127,20 @@ func (u *userInterface) start(width, height, scale int, title string) error {
return nil return nil
} }
func (u *userInterface) windowScale() int { func (u *UserInterface) windowScale() int {
return u.scale * int(u.deviceScale) return u.scale * int(u.deviceScale)
} }
func (u *userInterface) actualScreenScale() int { func (u *UserInterface) actualScreenScale() int {
return u.windowScale() * u.framebufferScale return u.windowScale() * u.framebufferScale
} }
func (u *userInterface) pollEvents() error { func (u *UserInterface) pollEvents() error {
glfw.PollEvents() glfw.PollEvents()
return currentInput.update(u.window, u.windowScale()) return currentInput.update(u.window, u.windowScale())
} }
func (u *userInterface) doEvents() error { func (u *UserInterface) DoEvents() error {
if err := u.pollEvents(); err != nil { if err := u.pollEvents(); err != nil {
return err return err
} }
@ -166,22 +150,22 @@ func (u *userInterface) doEvents() error {
if err := u.pollEvents(); err != nil { if err := u.pollEvents(); err != nil {
return err return err
} }
if u.isClosed() { if u.IsClosed() {
return nil return nil
} }
} }
return nil return nil
} }
func (u *userInterface) terminate() { func (u *UserInterface) Terminate() {
glfw.Terminate() glfw.Terminate()
} }
func (u *userInterface) isClosed() bool { func (u *UserInterface) IsClosed() bool {
return u.window.ShouldClose() return u.window.ShouldClose()
} }
func (u *userInterface) swapBuffers() { func (u *UserInterface) SwapBuffers() {
// The bound framebuffer must be the default one (0) before swapping buffers. // The bound framebuffer must be the default one (0) before swapping buffers.
u.context.BindZeroFramebuffer() u.context.BindZeroFramebuffer()
// Call glFinish before glfwSwapBuffer to make sure // Call glFinish before glfwSwapBuffer to make sure
@ -192,7 +176,7 @@ func (u *userInterface) swapBuffers() {
}) })
} }
func (u *userInterface) setScreenSize(width, height, scale int) bool { func (u *UserInterface) setScreenSize(width, height, scale int) bool {
if u.width == width && u.height == height && u.scale == scale { if u.width == width && u.height == height && u.scale == scale {
return false return false
} }
@ -214,7 +198,7 @@ func (u *userInterface) setScreenSize(width, height, scale int) bool {
// To make sure the current existing framebuffers are rendered, // To make sure the current existing framebuffers are rendered,
// swap buffers here before SetSize is called. // swap buffers here before SetSize is called.
u.swapBuffers() u.SwapBuffers()
ch := make(chan struct{}) ch := make(chan struct{})
window := u.window window := u.window

View File

@ -29,49 +29,33 @@ func Now() int64 {
return int64(js.Global.Get("performance").Call("now").Float() * float64(time.Millisecond)) return int64(js.Global.Get("performance").Call("now").Float() * float64(time.Millisecond))
} }
func Start(width, height, scale int, title string) error { func (u *UserInterface) SetScreenSize(width, height int) bool {
return currentUI.start(width, height, scale, title)
}
func Terminate() {
currentUI.terminate()
}
func DoEvents() error {
return currentUI.doEvents()
}
func IsClosed() bool {
return currentUI.isClosed()
}
func SwapBuffers() {
currentUI.swapBuffers()
}
func SetScreenSize(width, height int) bool {
scale := canvas.Get("dataset").Get("ebitenScreenScale").Int() scale := canvas.Get("dataset").Get("ebitenScreenScale").Int()
return currentUI.setScreenSize(width, height, scale) return u.setScreenSize(width, height, scale)
} }
func SetScreenScale(scale int) bool { func (u *UserInterface) SetScreenScale(scale int) bool {
width, height := currentUI.size() width, height := currentUI.size()
return currentUI.setScreenSize(width, height, scale) return u.setScreenSize(width, height, scale)
} }
func ScreenScale() int { func (u *UserInterface) ScreenScale() int {
return canvas.Get("dataset").Get("ebitenScreenScale").Int() return canvas.Get("dataset").Get("ebitenScreenScale").Int()
} }
func ActualScreenScale() int { func (u *UserInterface) ActualScreenScale() int {
return canvas.Get("dataset").Get("ebitenActualScreenScale").Int() return canvas.Get("dataset").Get("ebitenActualScreenScale").Int()
} }
var canvas *js.Object var canvas *js.Object
type userInterface struct{} type UserInterface struct{}
var currentUI = &userInterface{} var currentUI = &UserInterface{}
func CurrentUI() *UserInterface {
return currentUI
}
// NOTE: This returns true even when the browser is not active. // NOTE: This returns true even when the browser is not active.
func shown() bool { func shown() bool {
@ -96,20 +80,20 @@ func vsync() {
<-ch <-ch
} }
func (*userInterface) doEvents() error { func (u *UserInterface) DoEvents() error {
currentInput.UpdateGamepads() currentInput.UpdateGamepads()
return nil return nil
} }
func (*userInterface) terminate() { func (u *UserInterface) Terminate() {
// Do nothing. // Do nothing.
} }
func (*userInterface) isClosed() bool { func (u *UserInterface) IsClosed() bool {
return false return false
} }
func (*userInterface) swapBuffers() { func (u *UserInterface) SwapBuffers() {
vsync() vsync()
for !shown() { for !shown() {
vsync() vsync()
@ -243,7 +227,7 @@ func devicePixelRatio() int {
return ratio return ratio
} }
func (u *userInterface) start(width, height, scale int, title string) error { func (u *UserInterface) Start(width, height, scale int, title string) error {
doc := js.Global.Get("document") doc := js.Global.Get("document")
doc.Set("title", title) doc.Set("title", title)
u.setScreenSize(width, height, scale) u.setScreenSize(width, height, scale)
@ -251,7 +235,7 @@ func (u *userInterface) start(width, height, scale int, title string) error {
return nil return nil
} }
func (*userInterface) size() (width, height int) { func (*UserInterface) size() (width, height int) {
a := canvas.Get("dataset").Get("ebitenActualScreenScale").Int() a := canvas.Get("dataset").Get("ebitenActualScreenScale").Int()
if a == 0 { if a == 0 {
// a == 0 only on the initial state. // a == 0 only on the initial state.
@ -262,7 +246,7 @@ func (*userInterface) size() (width, height int) {
return return
} }
func (u *userInterface) setScreenSize(width, height, scale int) bool { func (u *UserInterface) setScreenSize(width, height, scale int) bool {
w, h := u.size() w, h := u.size()
s := canvas.Get("dataset").Get("ebitenScreenScale").Int() s := canvas.Get("dataset").Get("ebitenScreenScale").Int()
if w == width && h == height && s == scale { if w == width && h == height && s == scale {

25
run.go
View File

@ -54,6 +54,7 @@ func IsRunningSlowly() bool {
// The argument (*Image) is the render target that represents the screen. // The argument (*Image) is the render target that represents the screen.
// //
// This function must be called from the main thread. // This function must be called from the main thread.
// Note that ebiten bounds the main goroutine to the main OS thread by runtime.LockOSThread.
// //
// The given function f is guaranteed to be called 60 times a second // The given function f is guaranteed to be called 60 times a second
// even if a rendering frame is skipped. // even if a rendering frame is skipped.
@ -64,13 +65,13 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
runContext.running = false runContext.running = false
}() }()
if err := ui.Start(width, height, scale, title); err != nil { if err := ui.CurrentUI().Start(width, height, scale, title); err != nil {
return err return err
} }
defer ui.Terminate() defer ui.CurrentUI().Terminate()
glContext.Check() glContext.Check()
graphicsContext, err := newGraphicsContext(width, height, ui.ActualScreenScale()) graphicsContext, err := newGraphicsContext(width, height, ui.CurrentUI().ActualScreenScale())
if err != nil { if err != nil {
return err return err
} }
@ -84,16 +85,16 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
if 0 < runContext.newScreenWidth || 0 < runContext.newScreenHeight || 0 < runContext.newScreenScale { if 0 < runContext.newScreenWidth || 0 < runContext.newScreenHeight || 0 < runContext.newScreenScale {
changed := false changed := false
if 0 < runContext.newScreenWidth || 0 < runContext.newScreenHeight { if 0 < runContext.newScreenWidth || 0 < runContext.newScreenHeight {
c := ui.SetScreenSize(runContext.newScreenWidth, runContext.newScreenHeight) c := ui.CurrentUI().SetScreenSize(runContext.newScreenWidth, runContext.newScreenHeight)
changed = changed || c changed = changed || c
} }
if 0 < runContext.newScreenScale { if 0 < runContext.newScreenScale {
c := ui.SetScreenScale(runContext.newScreenScale) c := ui.CurrentUI().SetScreenScale(runContext.newScreenScale)
changed = changed || c changed = changed || c
} }
if changed { if changed {
w, h := runContext.newScreenWidth, runContext.newScreenHeight w, h := runContext.newScreenWidth, runContext.newScreenHeight
if err := graphicsContext.setSize(w, h, ui.ActualScreenScale()); err != nil { if err := graphicsContext.setSize(w, h, ui.CurrentUI().ActualScreenScale()); err != nil {
return err return err
} }
} }
@ -102,10 +103,10 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
runContext.newScreenHeight = 0 runContext.newScreenHeight = 0
runContext.newScreenScale = 0 runContext.newScreenScale = 0
if err := ui.DoEvents(); err != nil { if err := ui.CurrentUI().DoEvents(); err != nil {
return err return err
} }
if ui.IsClosed() { if ui.CurrentUI().IsClosed() {
return nil return nil
} }
now := ui.Now() now := ui.Now()
@ -117,10 +118,10 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
c := float64(now-beforeForUpdate) * FPS / float64(time.Second) c := float64(now-beforeForUpdate) * FPS / float64(time.Second)
runContext.isRunningSlowly = c >= 2.5 runContext.isRunningSlowly = c >= 2.5
for i := 0; i < int(c); i++ { for i := 0; i < int(c); i++ {
if err := ui.DoEvents(); err != nil { if err := ui.CurrentUI().DoEvents(); err != nil {
return err return err
} }
if ui.IsClosed() { if ui.CurrentUI().IsClosed() {
return nil return nil
} }
if err := graphicsContext.update(f); err != nil { if err := graphicsContext.update(f); err != nil {
@ -128,7 +129,7 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
} }
} }
beforeForUpdate += int64(c) * int64(time.Second/FPS) beforeForUpdate += int64(c) * int64(time.Second/FPS)
ui.SwapBuffers() ui.CurrentUI().SwapBuffers()
} }
// Calc the current FPS. // Calc the current FPS.
@ -168,5 +169,5 @@ func SetScreenScale(scale int) {
// ScreenScale returns the current screen scale. // ScreenScale returns the current screen scale.
func ScreenScale() int { func ScreenScale() int {
return ui.ScreenScale() return ui.CurrentUI().ScreenScale()
} }