Add ui.InputState

This commit is contained in:
Hajime Hoshi 2014-05-12 10:04:28 +09:00
parent 0b9f27287b
commit a4e74eb4be
4 changed files with 90 additions and 57 deletions

View File

@ -66,11 +66,11 @@ func (game *Game) isInitialized() bool {
return true return true
} }
func (game *Game) Update(state ui.CanvasState) { func (game *Game) Update(state ui.InputState) {
if !game.isInitialized() { if !game.isInitialized() {
return return
} }
game.input.Update(state.PressedKeys) game.input.Update(state.PressedKeys())
game.sceneManager.Update(&GameState{ game.sceneManager.Update(&GameState{
SceneManager: game.sceneManager, SceneManager: game.sceneManager,
Input: game.input, Input: game.input,

View File

@ -13,7 +13,7 @@ import (
) )
type Game interface { type Game interface {
Update(state ui.CanvasState) Update(state ui.InputState)
Draw(c graphics.Context) Draw(c graphics.Context)
} }
@ -47,16 +47,10 @@ func main() {
default: default:
canvas.Draw(game.Draw) canvas.Draw(game.Draw)
case <-tick: case <-tick:
state := canvas.State() game.Update(canvas.InputState())
game.Update(state) if canvas.IsClosed() {
if state.IsClosed {
return return
} }
/*case e := <-windowEvents:
game.HandleEvent(e)
if _, ok := e.(ui.WindowClosedEvent); ok {
return
}*/
case <-sigterm: case <-sigterm:
return return
} }

View File

@ -32,6 +32,14 @@ func newKeys() Keys {
return Keys(map[ui.Key]struct{}{}) return Keys(map[ui.Key]struct{}{})
} }
func (k Keys) clone() Keys {
n := newKeys()
for key, value := range k {
n[key] = value
}
return n
}
func (k Keys) add(key ui.Key) { func (k Keys) add(key ui.Key) {
k[key] = struct{}{} k[key] = struct{}{}
} }
@ -45,37 +53,69 @@ func (k Keys) Includes(key ui.Key) bool {
return ok return ok
} }
type InputState struct {
pressedKeys Keys
mouseX int
mouseY int
}
func (i *InputState) PressedKeys() ui.Keys {
return i.pressedKeys
}
func (i *InputState) MouseX() int {
return i.mouseX
}
func (i *InputState) MouseY() int {
return i.mouseY
}
func (i *InputState) setMouseXY(x, y int) {
i.mouseX = x
i.mouseY = y
}
type GameWindow struct { type GameWindow struct {
state ui.CanvasState width int
title string height int
native *C.EbitenGameWindow scale int
funcs chan func(*opengl.Context) isClosed bool
funcsDone chan struct{} inputState *InputState
closed chan struct{} title string
native *C.EbitenGameWindow
funcs chan func(*opengl.Context)
funcsDone chan struct{}
closed chan struct{}
sync.RWMutex sync.RWMutex
} }
var windows = map[*C.EbitenGameWindow]*GameWindow{} var windows = map[*C.EbitenGameWindow]*GameWindow{}
func newGameWindow(width, height, scale int, title string) *GameWindow { func newGameWindow(width, height, scale int, title string) *GameWindow {
state := ui.CanvasState{ inputState := &InputState{
Width: width, pressedKeys: newKeys(),
Height: height, mouseX: -1,
Scale: scale, mouseY: -1,
PressedKeys: newKeys(),
MouseX: -1,
MouseY: -1,
IsClosed: false,
} }
return &GameWindow{ return &GameWindow{
state: state, width: width,
title: title, height: height,
funcs: make(chan func(*opengl.Context)), scale: scale,
funcsDone: make(chan struct{}), inputState: inputState,
closed: make(chan struct{}), title: title,
funcs: make(chan func(*opengl.Context)),
funcsDone: make(chan struct{}),
closed: make(chan struct{}),
} }
} }
func (w *GameWindow) IsClosed() bool {
w.RLock()
defer w.RUnlock()
return w.isClosed
}
func (w *GameWindow) run(sharedGLContext *C.NSOpenGLContext) { func (w *GameWindow) run(sharedGLContext *C.NSOpenGLContext) {
cTitle := C.CString(w.title) cTitle := C.CString(w.title)
defer C.free(unsafe.Pointer(cTitle)) defer C.free(unsafe.Pointer(cTitle))
@ -85,8 +125,8 @@ func (w *GameWindow) run(sharedGLContext *C.NSOpenGLContext) {
runtime.LockOSThread() runtime.LockOSThread()
glContext := C.CreateGLContext(sharedGLContext) glContext := C.CreateGLContext(sharedGLContext)
w.native = C.CreateGameWindow( w.native = C.CreateGameWindow(
C.size_t(w.state.Width*w.state.Scale), C.size_t(w.width*w.scale),
C.size_t(w.state.Height*w.state.Scale), C.size_t(w.height*w.scale),
cTitle, cTitle,
glContext) glContext)
windows[w.native] = w windows[w.native] = w
@ -94,7 +134,7 @@ func (w *GameWindow) run(sharedGLContext *C.NSOpenGLContext) {
C.UseGLContext(glContext) C.UseGLContext(glContext)
context := opengl.NewContext( context := opengl.NewContext(
w.state.Width, w.state.Height, w.state.Scale) w.width, w.height, w.scale)
C.UnuseGLContext() C.UnuseGLContext()
defer func() { defer func() {
@ -141,10 +181,14 @@ func (w *GameWindow) useGLContext(f func(*opengl.Context)) {
<-w.funcsDone <-w.funcsDone
} }
func (w *GameWindow) State() ui.CanvasState { func (w *GameWindow) InputState() ui.InputState {
w.RLock() w.RLock()
defer w.RUnlock() defer w.RUnlock()
return w.state return &InputState{
pressedKeys: w.inputState.pressedKeys.clone(),
mouseX: w.inputState.mouseX,
mouseY: w.inputState.mouseY,
}
} }
var cocoaKeyCodeToKey = map[int]ui.Key{ var cocoaKeyCodeToKey = map[int]ui.Key{
@ -165,7 +209,7 @@ func ebiten_KeyDown(nativeWindow C.EbitenGameWindowPtr, keyCode int) {
w.Lock() w.Lock()
defer w.Unlock() defer w.Unlock()
w.state.PressedKeys.(Keys).add(key) w.inputState.pressedKeys.add(key)
} }
//export ebiten_KeyUp //export ebiten_KeyUp
@ -178,7 +222,7 @@ func ebiten_KeyUp(nativeWindow C.EbitenGameWindowPtr, keyCode int) {
w.Lock() w.Lock()
defer w.Unlock() defer w.Unlock()
w.state.PressedKeys.(Keys).remove(key) w.inputState.pressedKeys.remove(key)
} }
//export ebiten_MouseStateUpdated //export ebiten_MouseStateUpdated
@ -188,29 +232,27 @@ func ebiten_MouseStateUpdated(nativeWindow C.EbitenGameWindowPtr, inputType C.In
if inputType == C.InputTypeMouseUp { if inputType == C.InputTypeMouseUp {
w.Lock() w.Lock()
defer w.Unlock() defer w.Unlock()
w.state.MouseX = -1 w.inputState.setMouseXY(-1, -1)
w.state.MouseY = -1
return return
} }
x, y := int(cx), int(cy) x, y := int(cx), int(cy)
x /= w.state.Scale x /= w.scale
y /= w.state.Scale y /= w.scale
if x < 0 { if x < 0 {
x = 0 x = 0
} else if w.state.Width <= x { } else if w.width <= x {
x = w.state.Width - 1 x = w.width - 1
} }
if y < 0 { if y < 0 {
y = 0 y = 0
} else if w.state.Height <= y { } else if w.height <= y {
y = w.state.Height - 1 y = w.height - 1
} }
w.Lock() w.Lock()
defer w.Unlock() defer w.Unlock()
w.state.MouseX = x w.inputState.setMouseXY(x, y)
w.state.MouseY = y
} }
//export ebiten_WindowClosed //export ebiten_WindowClosed
@ -220,7 +262,7 @@ func ebiten_WindowClosed(nativeWindow C.EbitenGameWindowPtr) {
w.Lock() w.Lock()
defer w.Unlock() defer w.Unlock()
w.state.IsClosed = true w.isClosed = true
delete(windows, nativeWindow) delete(windows, nativeWindow)
} }

View File

@ -26,17 +26,14 @@ type Keys interface {
Includes(key Key) bool Includes(key Key) bool
} }
type CanvasState struct { type InputState interface {
Width int PressedKeys() Keys
Height int MouseX() int
Scale int MouseY() int
PressedKeys Keys
MouseX int
MouseY int
IsClosed bool
} }
type Canvas interface { type Canvas interface {
Draw(func(graphics.Context)) Draw(func(graphics.Context))
State() CanvasState IsClosed() bool
InputState() InputState
} }