mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
ui: Introduce ScreenSizeEvent to simplify the run loop
This commit is contained in:
parent
faff188574
commit
335781759c
@ -15,7 +15,6 @@
|
||||
package loop
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -24,10 +23,6 @@ import (
|
||||
|
||||
const FPS = 60
|
||||
|
||||
func Main() {
|
||||
ui.Main()
|
||||
}
|
||||
|
||||
func CurrentFPS() float64 {
|
||||
return currentRunContext.currentFPS()
|
||||
}
|
||||
@ -40,26 +35,11 @@ func IsRunningSlowly() bool {
|
||||
return currentRunContext.isRunningSlowly()
|
||||
}
|
||||
|
||||
func SetScreenSize(width, height int) error {
|
||||
return currentRunContext.setScreenSize(width, height)
|
||||
}
|
||||
|
||||
func SetScreenScale(scale int) error {
|
||||
return currentRunContext.setScreenScale(scale)
|
||||
}
|
||||
|
||||
func ScreenScale() int {
|
||||
return ui.CurrentUI().ScreenScale()
|
||||
}
|
||||
|
||||
type runContext struct {
|
||||
running bool
|
||||
fps float64
|
||||
newScreenWidth int
|
||||
newScreenHeight int
|
||||
newScreenScale int
|
||||
runningSlowly bool
|
||||
m sync.RWMutex
|
||||
running bool
|
||||
fps float64
|
||||
runningSlowly bool
|
||||
m sync.RWMutex
|
||||
}
|
||||
|
||||
var currentRunContext runContext
|
||||
@ -114,60 +94,6 @@ func (c *runContext) setRunningSlowly(isRunningSlowly bool) {
|
||||
c.runningSlowly = isRunningSlowly
|
||||
}
|
||||
|
||||
func (c *runContext) updateScreenSize(g GraphicsContext) error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
if c.newScreenWidth == 0 && c.newScreenHeight == 0 && c.newScreenScale == 0 {
|
||||
return nil
|
||||
}
|
||||
changed := false
|
||||
if 0 < c.newScreenWidth || 0 < c.newScreenHeight {
|
||||
c := ui.CurrentUI().SetScreenSize(c.newScreenWidth, c.newScreenHeight)
|
||||
changed = changed || c
|
||||
}
|
||||
if 0 < c.newScreenScale {
|
||||
c := ui.CurrentUI().SetScreenScale(c.newScreenScale)
|
||||
changed = changed || c
|
||||
}
|
||||
if changed {
|
||||
w, h := c.newScreenWidth, c.newScreenHeight
|
||||
if err := g.SetSize(w, h, ui.CurrentUI().ActualScreenScale()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
c.newScreenWidth = 0
|
||||
c.newScreenHeight = 0
|
||||
c.newScreenScale = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *runContext) setScreenSize(width, height int) error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
if !c.running {
|
||||
return errors.New("ebiten: SetScreenSize must be called during Run")
|
||||
}
|
||||
if width <= 0 || height <= 0 {
|
||||
return errors.New("ebiten: width and height must be positive")
|
||||
}
|
||||
c.newScreenWidth = width
|
||||
c.newScreenHeight = height
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *runContext) setScreenScale(scale int) error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
if !c.running {
|
||||
return errors.New("ebiten: SetScreenScale must be called during Run")
|
||||
}
|
||||
if scale <= 0 {
|
||||
return errors.New("ebiten: scale must be positive")
|
||||
}
|
||||
c.newScreenScale = scale
|
||||
return nil
|
||||
}
|
||||
|
||||
type GraphicsContext interface {
|
||||
SetSize(width, height, scale int) error
|
||||
Update() error
|
||||
@ -182,23 +108,20 @@ func Run(g GraphicsContext, width, height, scale int, title string) error {
|
||||
}
|
||||
defer ui.CurrentUI().Terminate()
|
||||
|
||||
if err := g.SetSize(width, height, ui.CurrentUI().ActualScreenScale()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
frames := 0
|
||||
n := now()
|
||||
beforeForUpdate := n
|
||||
beforeForFPS := n
|
||||
for {
|
||||
if err := currentRunContext.updateScreenSize(g); err != nil {
|
||||
return err
|
||||
}
|
||||
e, err := ui.CurrentUI().Update()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch e.(type) {
|
||||
switch e := e.(type) {
|
||||
case ui.ScreenSizeEvent:
|
||||
if err := g.SetSize(e.Width, e.Height, e.ActualScale); err != nil {
|
||||
return err
|
||||
}
|
||||
case ui.CloseEvent:
|
||||
return nil
|
||||
case ui.RenderEvent:
|
||||
|
@ -19,3 +19,10 @@ type CloseEvent struct {
|
||||
|
||||
type RenderEvent struct {
|
||||
}
|
||||
|
||||
type ScreenSizeEvent struct {
|
||||
Width int
|
||||
Height int
|
||||
Scale int
|
||||
ActualScale int
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ type UserInterface struct {
|
||||
framebufferScale int
|
||||
context *opengl.Context
|
||||
funcs chan func()
|
||||
sizeChanged bool
|
||||
}
|
||||
|
||||
var currentUI *UserInterface
|
||||
@ -61,8 +62,9 @@ func initialize() (*opengl.Context, error) {
|
||||
}
|
||||
|
||||
u := &UserInterface{
|
||||
window: window,
|
||||
funcs: make(chan func()),
|
||||
window: window,
|
||||
funcs: make(chan func()),
|
||||
sizeChanged: true,
|
||||
}
|
||||
ch := make(chan error)
|
||||
go func() {
|
||||
@ -140,14 +142,6 @@ func (u *UserInterface) ScreenScale() int {
|
||||
return s
|
||||
}
|
||||
|
||||
func (u *UserInterface) ActualScreenScale() int {
|
||||
s := 0
|
||||
u.runOnMainThread(func() {
|
||||
s = u.actualScreenScale()
|
||||
})
|
||||
return s
|
||||
}
|
||||
|
||||
func (u *UserInterface) Start(width, height, scale int, title string) error {
|
||||
var err error
|
||||
u.runOnMainThread(func() {
|
||||
@ -200,6 +194,24 @@ func (u *UserInterface) Update() (interface{}, error) {
|
||||
if shouldClose {
|
||||
return CloseEvent{}, nil
|
||||
}
|
||||
|
||||
var screenSizeEvent *ScreenSizeEvent
|
||||
u.runOnMainThread(func() {
|
||||
if !u.sizeChanged {
|
||||
return
|
||||
}
|
||||
u.sizeChanged = false
|
||||
screenSizeEvent = &ScreenSizeEvent{
|
||||
Width: u.width,
|
||||
Height: u.height,
|
||||
Scale: u.scale,
|
||||
ActualScale: u.actualScreenScale(),
|
||||
}
|
||||
})
|
||||
if screenSizeEvent != nil {
|
||||
return *screenSizeEvent, nil
|
||||
}
|
||||
|
||||
var ferr error
|
||||
u.runOnMainThread(func() {
|
||||
if err := u.pollEvents(); err != nil {
|
||||
@ -291,5 +303,6 @@ event:
|
||||
// This is usually 1, but sometimes more than 1 (e.g. Retina Mac)
|
||||
fw, _ := window.GetFramebufferSize()
|
||||
u.framebufferScale = fw / width / u.windowScale()
|
||||
u.sizeChanged = true
|
||||
return true
|
||||
}
|
||||
|
@ -46,9 +46,12 @@ var canvas *js.Object
|
||||
type UserInterface struct {
|
||||
scale int
|
||||
deviceScale float64
|
||||
sizeChanged bool
|
||||
}
|
||||
|
||||
var currentUI = &UserInterface{}
|
||||
var currentUI = &UserInterface{
|
||||
sizeChanged: true,
|
||||
}
|
||||
|
||||
func CurrentUI() *UserInterface {
|
||||
return currentUI
|
||||
@ -79,6 +82,17 @@ func vsync() {
|
||||
|
||||
func (u *UserInterface) Update() (interface{}, error) {
|
||||
currentInput.UpdateGamepads()
|
||||
if u.sizeChanged {
|
||||
u.sizeChanged = false
|
||||
w, h := u.size()
|
||||
e := ScreenSizeEvent{
|
||||
Width: w,
|
||||
Height: h,
|
||||
Scale: u.ScreenScale(),
|
||||
ActualScale: u.ActualScreenScale(),
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
return RenderEvent{}, nil
|
||||
}
|
||||
|
||||
@ -276,5 +290,6 @@ func (u *UserInterface) setScreenSize(width, height, scale int) bool {
|
||||
// CSS calc requires space chars.
|
||||
canvasStyle.Set("left", "calc((100% - "+strconv.Itoa(cssWidth)+"px) / 2)")
|
||||
canvasStyle.Set("top", "calc((100% - "+strconv.Itoa(cssHeight)+"px) / 2)")
|
||||
u.sizeChanged = true
|
||||
return true
|
||||
}
|
||||
|
15
run.go
15
run.go
@ -16,6 +16,7 @@ package ebiten
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/ebiten/internal/loop"
|
||||
"github.com/hajimehoshi/ebiten/internal/ui"
|
||||
)
|
||||
|
||||
// FPS represents how many times game updating happens in a second.
|
||||
@ -58,7 +59,7 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
|
||||
g := newGraphicsContext(f)
|
||||
ch <- loop.Run(g, width, height, scale, title)
|
||||
}()
|
||||
loop.Main()
|
||||
ui.Main()
|
||||
return <-ch
|
||||
}
|
||||
|
||||
@ -67,23 +68,25 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
|
||||
//
|
||||
// This function is concurrent-safe.
|
||||
func SetScreenSize(width, height int) {
|
||||
if err := loop.SetScreenSize(width, height); err != nil {
|
||||
panic(err)
|
||||
if width <= 0 || height <= 0 {
|
||||
panic("ebiten: width and height must be positive")
|
||||
}
|
||||
ui.CurrentUI().SetScreenSize(width, height)
|
||||
}
|
||||
|
||||
// SetScreenScale changes the scale of the screen.
|
||||
//
|
||||
// This function is concurrent-safe.
|
||||
func SetScreenScale(scale int) {
|
||||
if err := loop.SetScreenScale(scale); err != nil {
|
||||
panic(err)
|
||||
if scale <= 0 {
|
||||
panic("ebiten: scale must be positive")
|
||||
}
|
||||
ui.CurrentUI().SetScreenScale(scale)
|
||||
}
|
||||
|
||||
// ScreenScale returns the current screen scale.
|
||||
//
|
||||
// This function is concurrent-safe.
|
||||
func ScreenScale() int {
|
||||
return loop.ScreenScale()
|
||||
return ui.CurrentUI().ScreenScale()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user