uidriver/js: Avoid calling String when possible to reduce overhead

Updates #1437
This commit is contained in:
Hajime Hoshi 2020-12-16 12:41:49 +09:00
parent e856b236f3
commit 442be20f4d
2 changed files with 32 additions and 11 deletions

View File

@ -20,6 +20,20 @@ import (
"unicode" "unicode"
"github.com/hajimehoshi/ebiten/v2/internal/driver" "github.com/hajimehoshi/ebiten/v2/internal/driver"
"github.com/hajimehoshi/ebiten/v2/internal/jsutil"
)
var (
stringKeydown = js.ValueOf("keydown")
stringKeypress = js.ValueOf("keypress")
stringKeyup = js.ValueOf("keyup")
stringMousedown = js.ValueOf("mousedown")
stringMouseup = js.ValueOf("mouseup")
stringMousemove = js.ValueOf("mousemove")
stringWheel = js.ValueOf("wheel")
stringTouchstart = js.ValueOf("touchstart")
stringTouchend = js.ValueOf("touchend")
stringTouchmove = js.ValueOf("touchmove")
) )
type pos struct { type pos struct {
@ -286,8 +300,10 @@ func (i *Input) UpdateGamepads() {
} }
func (i *Input) Update(e js.Value) { func (i *Input) Update(e js.Value) {
switch e.Get("type").String() { // Avoid using js.Value.String() as String creates a Uint8Array via a TextEncoder and causes a heavy
case "keydown": // overhead (#1437).
switch t := e.Get("type"); {
case jsutil.Equal(t, stringKeydown):
c := e.Get("code") c := e.Get("code")
if c.Type() != js.TypeString { if c.Type() != js.TypeString {
code := e.Get("keyCode").Int() code := e.Get("keyCode").Int()
@ -312,11 +328,11 @@ func (i *Input) Update(e js.Value) {
e.Call("preventDefault") e.Call("preventDefault")
} }
i.keyDown(cs) i.keyDown(cs)
case "keypress": case jsutil.Equal(t, stringKeypress):
if r := rune(e.Get("charCode").Int()); unicode.IsPrint(r) { if r := rune(e.Get("charCode").Int()); unicode.IsPrint(r) {
i.runeBuffer = append(i.runeBuffer, r) i.runeBuffer = append(i.runeBuffer, r)
} }
case "keyup": case jsutil.Equal(t, stringKeyup):
if e.Get("code").Type() != js.TypeString { if e.Get("code").Type() != js.TypeString {
// Assume that UA is Edge. // Assume that UA is Edge.
code := e.Get("keyCode").Int() code := e.Get("keyCode").Int()
@ -325,21 +341,21 @@ func (i *Input) Update(e js.Value) {
} }
code := e.Get("code").String() code := e.Get("code").String()
i.keyUp(code) i.keyUp(code)
case "mousedown": case jsutil.Equal(t, stringMousedown):
button := e.Get("button").Int() button := e.Get("button").Int()
i.mouseDown(button) i.mouseDown(button)
i.setMouseCursorFromEvent(e) i.setMouseCursorFromEvent(e)
case "mouseup": case jsutil.Equal(t, stringMouseup):
button := e.Get("button").Int() button := e.Get("button").Int()
i.mouseUp(button) i.mouseUp(button)
i.setMouseCursorFromEvent(e) i.setMouseCursorFromEvent(e)
case "mousemove": case jsutil.Equal(t, stringMousemove):
i.setMouseCursorFromEvent(e) i.setMouseCursorFromEvent(e)
case "wheel": case jsutil.Equal(t, stringWheel):
// TODO: What if e.deltaMode is not DOM_DELTA_PIXEL? // TODO: What if e.deltaMode is not DOM_DELTA_PIXEL?
i.wheelX = -e.Get("deltaX").Float() i.wheelX = -e.Get("deltaX").Float()
i.wheelY = -e.Get("deltaY").Float() i.wheelY = -e.Get("deltaY").Float()
case "touchstart", "touchend", "touchmove": case jsutil.Equal(t, stringTouchstart) || jsutil.Equal(t, stringTouchend) || jsutil.Equal(t, stringTouchmove):
i.updateTouches(e) i.updateTouches(e)
} }
} }

View File

@ -26,6 +26,11 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/restorable" "github.com/hajimehoshi/ebiten/v2/internal/restorable"
) )
var (
stringNone = js.ValueOf("none")
stringTransparent = js.ValueOf("transparent")
)
type UserInterface struct { type UserInterface struct {
runnableOnUnfocused bool runnableOnUnfocused bool
vsync bool vsync bool
@ -98,7 +103,7 @@ func (u *UserInterface) IsVsyncEnabled() bool {
} }
func (u *UserInterface) CursorMode() driver.CursorMode { func (u *UserInterface) CursorMode() driver.CursorMode {
if canvas.Get("style").Get("cursor").String() != "none" { if jsutil.Equal(canvas.Get("style").Get("cursor"), stringNone) {
return driver.CursorModeVisible return driver.CursorModeVisible
} }
return driver.CursorModeHidden return driver.CursorModeHidden
@ -469,7 +474,7 @@ func (u *UserInterface) SetScreenTransparent(transparent bool) {
func (u *UserInterface) IsScreenTransparent() bool { func (u *UserInterface) IsScreenTransparent() bool {
bodyStyle := document.Get("body").Get("style") bodyStyle := document.Get("body").Get("style")
return bodyStyle.Get("backgroundColor").String() == "transparent" return jsutil.Equal(bodyStyle.Get("backgroundColor"), stringTransparent)
} }
func (u *UserInterface) ResetForFrame() { func (u *UserInterface) ResetForFrame() {