mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 02:42:02 +01:00
ui: Use gopherwasm
This commit is contained in:
parent
faaf391619
commit
8e9c3bd304
@ -19,7 +19,7 @@ package input
|
|||||||
import (
|
import (
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/gopherjs/gopherjs/js"
|
"github.com/hajimehoshi/gopherwasm/js"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mockRWLock struct{}
|
type mockRWLock struct{}
|
||||||
@ -147,7 +147,7 @@ func (i *Input) UpdateGamepads() {
|
|||||||
for id := 0; id < l; id++ {
|
for id := 0; id < l; id++ {
|
||||||
i.gamepads[id].valid = false
|
i.gamepads[id].valid = false
|
||||||
gamepad := gamepads.Index(id)
|
gamepad := gamepads.Index(id)
|
||||||
if gamepad == js.Undefined || gamepad == nil {
|
if gamepad == js.Undefined || gamepad == js.Null {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
i.gamepads[id].valid = true
|
i.gamepads[id].valid = true
|
||||||
@ -176,7 +176,7 @@ func (i *Input) UpdateGamepads() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnKeyDown(e *js.Object) {
|
func OnKeyDown(e js.Value) {
|
||||||
c := e.Get("code")
|
c := e.Get("code")
|
||||||
if c == js.Undefined {
|
if c == js.Undefined {
|
||||||
code := e.Get("keyCode").Int()
|
code := e.Get("keyCode").Int()
|
||||||
@ -203,15 +203,13 @@ func OnKeyDown(e *js.Object) {
|
|||||||
theInput.keyDown(cs)
|
theInput.keyDown(cs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnKeyPress(e *js.Object) {
|
func OnKeyPress(e js.Value) {
|
||||||
e.Call("preventDefault")
|
|
||||||
if r := rune(e.Get("charCode").Int()); unicode.IsPrint(r) {
|
if r := rune(e.Get("charCode").Int()); unicode.IsPrint(r) {
|
||||||
theInput.runeBuffer = append(theInput.runeBuffer, r)
|
theInput.runeBuffer = append(theInput.runeBuffer, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnKeyUp(e *js.Object) {
|
func OnKeyUp(e js.Value) {
|
||||||
e.Call("preventDefault")
|
|
||||||
if e.Get("code") == js.Undefined {
|
if e.Get("code") == js.Undefined {
|
||||||
// Assume that UA is Edge.
|
// Assume that UA is Edge.
|
||||||
code := e.Get("keyCode").Int()
|
code := e.Get("keyCode").Int()
|
||||||
@ -222,46 +220,40 @@ func OnKeyUp(e *js.Object) {
|
|||||||
theInput.keyUp(code)
|
theInput.keyUp(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnMouseDown(e *js.Object) {
|
func OnMouseDown(e js.Value) {
|
||||||
e.Call("preventDefault")
|
|
||||||
button := e.Get("button").Int()
|
button := e.Get("button").Int()
|
||||||
theInput.mouseDown(button)
|
theInput.mouseDown(button)
|
||||||
setMouseCursorFromEvent(e)
|
setMouseCursorFromEvent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnMouseUp(e *js.Object) {
|
func OnMouseUp(e js.Value) {
|
||||||
e.Call("preventDefault")
|
|
||||||
button := e.Get("button").Int()
|
button := e.Get("button").Int()
|
||||||
theInput.mouseUp(button)
|
theInput.mouseUp(button)
|
||||||
setMouseCursorFromEvent(e)
|
setMouseCursorFromEvent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnMouseMove(e *js.Object) {
|
func OnMouseMove(e js.Value) {
|
||||||
e.Call("preventDefault")
|
|
||||||
setMouseCursorFromEvent(e)
|
setMouseCursorFromEvent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnTouchStart(e *js.Object) {
|
func OnTouchStart(e js.Value) {
|
||||||
e.Call("preventDefault")
|
|
||||||
theInput.updateTouches(e)
|
theInput.updateTouches(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnTouchEnd(e *js.Object) {
|
func OnTouchEnd(e js.Value) {
|
||||||
e.Call("preventDefault")
|
|
||||||
theInput.updateTouches(e)
|
theInput.updateTouches(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnTouchMove(e *js.Object) {
|
func OnTouchMove(e js.Value) {
|
||||||
e.Call("preventDefault")
|
|
||||||
theInput.updateTouches(e)
|
theInput.updateTouches(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setMouseCursorFromEvent(e *js.Object) {
|
func setMouseCursorFromEvent(e js.Value) {
|
||||||
x, y := e.Get("clientX").Int(), e.Get("clientY").Int()
|
x, y := e.Get("clientX").Int(), e.Get("clientY").Int()
|
||||||
theInput.setMouseCursor(x, y)
|
theInput.setMouseCursor(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Input) updateTouches(e *js.Object) {
|
func (i *Input) updateTouches(e js.Value) {
|
||||||
j := e.Get("targetTouches")
|
j := e.Get("targetTouches")
|
||||||
ts := make([]*Touch, j.Get("length").Int())
|
ts := make([]*Touch, j.Get("length").Int())
|
||||||
for i := 0; i < len(ts); i++ {
|
for i := 0; i < len(ts); i++ {
|
||||||
|
@ -18,9 +18,10 @@ package ui
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/gopherjs/gopherjs/js"
|
"github.com/hajimehoshi/gopherwasm/js"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/devicescale"
|
"github.com/hajimehoshi/ebiten/internal/devicescale"
|
||||||
"github.com/hajimehoshi/ebiten/internal/hooks"
|
"github.com/hajimehoshi/ebiten/internal/hooks"
|
||||||
@ -29,7 +30,7 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/internal/web"
|
"github.com/hajimehoshi/ebiten/internal/web"
|
||||||
)
|
)
|
||||||
|
|
||||||
var canvas *js.Object
|
var canvas js.Value
|
||||||
|
|
||||||
type userInterface struct {
|
type userInterface struct {
|
||||||
width int
|
width int
|
||||||
@ -204,69 +205,66 @@ func (u *userInterface) update(g GraphicsContext) error {
|
|||||||
|
|
||||||
func (u *userInterface) loop(g GraphicsContext) error {
|
func (u *userInterface) loop(g GraphicsContext) error {
|
||||||
ch := make(chan error)
|
ch := make(chan error)
|
||||||
var f func()
|
var f func([]js.Value)
|
||||||
f = func() {
|
var cf js.Callback
|
||||||
go func() {
|
f = func([]js.Value) {
|
||||||
if err := u.update(g); err != nil {
|
if err := u.update(g); err != nil {
|
||||||
ch <- err
|
ch <- err
|
||||||
close(ch)
|
close(ch)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
js.Global.Get("window").Call("requestAnimationFrame", f)
|
js.Global.Get("window").Call("requestAnimationFrame", cf)
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
f()
|
cf = js.NewCallback(f)
|
||||||
|
f(nil)
|
||||||
return <-ch
|
return <-ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
if err := initialize(); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func initialize() error {
|
|
||||||
// Do nothing in node.js.
|
// Do nothing in node.js.
|
||||||
if web.IsNodeJS() {
|
if web.IsNodeJS() {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
doc := js.Global.Get("document")
|
doc := js.Global.Get("document")
|
||||||
window := js.Global.Get("window")
|
window := js.Global.Get("window")
|
||||||
if doc.Get("body") == nil {
|
if doc.Get("body") == js.Null {
|
||||||
ch := make(chan struct{})
|
ch := make(chan struct{})
|
||||||
window.Call("addEventListener", "load", func() {
|
window.Call("addEventListener", "load", js.NewCallback(func([]js.Value) {
|
||||||
close(ch)
|
close(ch)
|
||||||
})
|
}))
|
||||||
|
if runtime.GOARCH == "js" {
|
||||||
|
js.Global.Get("console").Call("warn", "'deadlock' error is raised from GopherJS, but this is a known issue: https://github.com/gopherjs/gopherjs/issues/826")
|
||||||
|
}
|
||||||
<-ch
|
<-ch
|
||||||
}
|
}
|
||||||
window.Call("addEventListener", "focus", func() {
|
|
||||||
|
window.Call("addEventListener", "focus", js.NewCallback(func([]js.Value) {
|
||||||
currentUI.windowFocus = true
|
currentUI.windowFocus = true
|
||||||
if currentUI.suspended() {
|
if currentUI.suspended() {
|
||||||
hooks.SuspendAudio()
|
hooks.SuspendAudio()
|
||||||
} else {
|
} else {
|
||||||
hooks.ResumeAudio()
|
hooks.ResumeAudio()
|
||||||
}
|
}
|
||||||
})
|
}))
|
||||||
window.Call("addEventListener", "blur", func() {
|
window.Call("addEventListener", "blur", js.NewCallback(func([]js.Value) {
|
||||||
currentUI.windowFocus = false
|
currentUI.windowFocus = false
|
||||||
if currentUI.suspended() {
|
if currentUI.suspended() {
|
||||||
hooks.SuspendAudio()
|
hooks.SuspendAudio()
|
||||||
} else {
|
} else {
|
||||||
hooks.ResumeAudio()
|
hooks.ResumeAudio()
|
||||||
}
|
}
|
||||||
})
|
}))
|
||||||
doc.Call("addEventListener", "visibilitychange", func() {
|
doc.Call("addEventListener", "visibilitychange", js.NewCallback(func([]js.Value) {
|
||||||
currentUI.pageVisible = !doc.Get("hidden").Bool()
|
currentUI.pageVisible = !doc.Get("hidden").Bool()
|
||||||
if currentUI.suspended() {
|
if currentUI.suspended() {
|
||||||
hooks.SuspendAudio()
|
hooks.SuspendAudio()
|
||||||
} else {
|
} else {
|
||||||
hooks.ResumeAudio()
|
hooks.ResumeAudio()
|
||||||
}
|
}
|
||||||
})
|
}))
|
||||||
window.Call("addEventListener", "resize", func() {
|
window.Call("addEventListener", "resize", js.NewCallback(func([]js.Value) {
|
||||||
currentUI.updateScreenSize()
|
currentUI.updateScreenSize()
|
||||||
})
|
}))
|
||||||
|
|
||||||
// Adjust the initial scale to 1.
|
// Adjust the initial scale to 1.
|
||||||
// https://developer.mozilla.org/en/docs/Mozilla/Mobile/Viewport_meta_tag
|
// https://developer.mozilla.org/en/docs/Mozilla/Mobile/Viewport_meta_tag
|
||||||
@ -293,9 +291,9 @@ func initialize() error {
|
|||||||
bodyStyle.Set("padding", "0")
|
bodyStyle.Set("padding", "0")
|
||||||
// TODO: This is OK as long as the game is in an independent iframe.
|
// TODO: This is OK as long as the game is in an independent iframe.
|
||||||
// What if the canvas is embedded in a HTML directly?
|
// What if the canvas is embedded in a HTML directly?
|
||||||
doc.Get("body").Call("addEventListener", "click", func() {
|
doc.Get("body").Call("addEventListener", "click", js.NewCallback(func([]js.Value) {
|
||||||
canvas.Call("focus")
|
canvas.Call("focus")
|
||||||
})
|
}))
|
||||||
|
|
||||||
canvasStyle := canvas.Get("style")
|
canvasStyle := canvas.Get("style")
|
||||||
canvasStyle.Set("position", "absolute")
|
canvasStyle.Set("position", "absolute")
|
||||||
@ -305,36 +303,35 @@ func initialize() error {
|
|||||||
canvas.Get("style").Set("outline", "none")
|
canvas.Get("style").Set("outline", "none")
|
||||||
|
|
||||||
// Keyboard
|
// Keyboard
|
||||||
canvas.Call("addEventListener", "keydown", input.OnKeyDown)
|
canvas.Call("addEventListener", "keydown", js.NewEventCallback(true, false, false, input.OnKeyDown))
|
||||||
canvas.Call("addEventListener", "keypress", input.OnKeyPress)
|
canvas.Call("addEventListener", "keypress", js.NewEventCallback(true, false, false, input.OnKeyPress))
|
||||||
canvas.Call("addEventListener", "keyup", input.OnKeyUp)
|
canvas.Call("addEventListener", "keyup", js.NewEventCallback(true, false, false, input.OnKeyUp))
|
||||||
|
|
||||||
// Mouse
|
// Mouse
|
||||||
canvas.Call("addEventListener", "mousedown", input.OnMouseDown)
|
canvas.Call("addEventListener", "mousedown", js.NewEventCallback(true, false, false, input.OnMouseDown))
|
||||||
canvas.Call("addEventListener", "mouseup", input.OnMouseUp)
|
canvas.Call("addEventListener", "mouseup", js.NewEventCallback(true, false, false, input.OnMouseUp))
|
||||||
canvas.Call("addEventListener", "mousemove", input.OnMouseMove)
|
canvas.Call("addEventListener", "mousemove", js.NewEventCallback(true, false, false, input.OnMouseMove))
|
||||||
canvas.Call("addEventListener", "contextmenu", func(e *js.Object) {
|
|
||||||
e.Call("preventDefault")
|
|
||||||
})
|
|
||||||
|
|
||||||
// Touch
|
// Touch
|
||||||
canvas.Call("addEventListener", "touchstart", input.OnTouchStart)
|
canvas.Call("addEventListener", "touchstart", js.NewEventCallback(true, false, false, input.OnTouchStart))
|
||||||
canvas.Call("addEventListener", "touchend", input.OnTouchEnd)
|
canvas.Call("addEventListener", "touchend", js.NewEventCallback(true, false, false, input.OnTouchEnd))
|
||||||
canvas.Call("addEventListener", "touchmove", input.OnTouchMove)
|
canvas.Call("addEventListener", "touchmove", js.NewEventCallback(true, false, false, input.OnTouchMove))
|
||||||
|
|
||||||
// Gamepad
|
// Gamepad
|
||||||
window.Call("addEventListener", "gamepadconnected", func(e *js.Object) {
|
window.Call("addEventListener", "gamepadconnected", js.NewCallback(func(e []js.Value) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
})
|
}))
|
||||||
|
|
||||||
canvas.Call("addEventListener", "webglcontextlost", func(e *js.Object) {
|
canvas.Call("addEventListener", "contextmenu", js.NewEventCallback(true, false, false, func(js.Value) {
|
||||||
e.Call("preventDefault")
|
|
||||||
})
|
|
||||||
canvas.Call("addEventListener", "webglcontextrestored", func(e *js.Object) {
|
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
})
|
}))
|
||||||
|
|
||||||
return nil
|
canvas.Call("addEventListener", "webglcontextlost", js.NewEventCallback(true, false, false, func(js.Value) {
|
||||||
|
// Do nothing.
|
||||||
|
}))
|
||||||
|
canvas.Call("addEventListener", "webglcontextrestored", js.NewCallback(func(e []js.Value) {
|
||||||
|
// Do nothing.
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunMainThreadLoop(ch <-chan error) error {
|
func RunMainThreadLoop(ch <-chan error) error {
|
||||||
|
Loading…
Reference in New Issue
Block a user