Remove InputState

This commit is contained in:
Hajime Hoshi 2013-11-30 03:21:10 +09:00
parent 7c91b03678
commit 2a8af24518
5 changed files with 114 additions and 37 deletions

View File

@ -4,19 +4,33 @@ import (
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
) )
type Game interface { // TODO: Remove this
InitTextures(tf graphics.TextureFactory)
Update(context GameContext)
Draw(canvas graphics.Canvas)
}
type GameContext interface { type GameContext interface {
ScreenWidth() int ScreenWidth() int
ScreenHeight() int ScreenHeight() int
InputState() InputState
} }
type InputState struct { type ScreenSizeUpdatedEvent struct {
Width int
Height int
}
type InputStateUpdatedEvent struct {
X int X int
Y int Y int
} }
type UIEvents interface {
ScreenSizeUpdated() <-chan ScreenSizeUpdatedEvent
}
type UI interface {
PollEvents()
InitTextures(func(graphics.TextureFactory))
Draw(func(graphics.Canvas))
InputStateUpdated() <-chan InputStateUpdatedEvent
// TODO: Remove this
Update(func(GameContext))
}

View File

@ -11,11 +11,21 @@ import (
type Input struct { type Input struct {
textTextureId graphics.TextureId textTextureId graphics.TextureId
inputState ebiten.InputState inputStateCh chan ebiten.InputStateUpdatedEvent
x int
y int
} }
func New() *Input { func New() *Input {
return &Input{} return &Input{
inputStateCh: make(chan ebiten.InputStateUpdatedEvent, 1),
x: -1,
y: -1,
}
}
func (game *Input) InputStateUpdated() chan<- ebiten.InputStateUpdatedEvent {
return game.inputStateCh
} }
func (game *Input) InitTextures(tf graphics.TextureFactory) { func (game *Input) InitTextures(tf graphics.TextureFactory) {
@ -35,14 +45,22 @@ func (game *Input) InitTextures(tf graphics.TextureFactory) {
} }
func (game *Input) Update(context ebiten.GameContext) { func (game *Input) Update(context ebiten.GameContext) {
game.inputState = context.InputState() events:
for {
select {
case e := <-game.inputStateCh:
game.x, game.y = e.X, e.Y
default:
break events
}
}
} }
func (game *Input) Draw(g graphics.Canvas) { func (game *Input) Draw(g graphics.Canvas) {
g.Fill(128, 128, 255) g.Fill(128, 128, 255)
str := fmt.Sprintf(`Input State: str := fmt.Sprintf(`Input State:
X: %d X: %d
Y: %d`, game.inputState.X, game.inputState.Y) Y: %d`, game.x, game.y)
game.drawText(g, str, 5, 5) game.drawText(g, str, 5, 5)
} }

View File

@ -17,6 +17,12 @@ import (
"time" "time"
) )
type Game interface {
InitTextures(tf graphics.TextureFactory)
Update(context ebiten.GameContext)
Draw(canvas graphics.Canvas)
}
func main() { func main() {
runtime.GOMAXPROCS(runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU())
@ -25,7 +31,7 @@ func main() {
gameName = os.Args[1] gameName = os.Args[1]
} }
var game ebiten.Game var game Game
switch gameName { switch gameName {
case "blank": case "blank":
game = blank.New() game = blank.New()
@ -50,7 +56,8 @@ func main() {
const screenScale = 2 const screenScale = 2
const fps = 60 const fps = 60
const title = "Ebiten Demo" const title = "Ebiten Demo"
ui := cocoa.New(screenWidth, screenHeight, screenScale, title)
var ui ebiten.UI = cocoa.New(screenWidth, screenHeight, screenScale, title)
ui.InitTextures(game.InitTextures) ui.InitTextures(game.InitTextures)
lock := sync.Mutex{} lock := sync.Mutex{}
@ -66,8 +73,24 @@ func main() {
}) })
} }
}() }()
inputStateUpdated := ui.InputStateUpdated()
for { for {
ui.PollEvents() ui.PollEvents()
events:
for {
select {
case e := <-inputStateUpdated:
type InputStateUpdatedHandler interface {
InputStateUpdated() chan<- ebiten.InputStateUpdatedEvent
}
if game2, ok := game.(InputStateUpdatedHandler); ok {
game2.InputStateUpdated() <- e
}
default:
break events
}
}
ui.Draw(func(c graphics.Canvas) { ui.Draw(func(c graphics.Canvas) {
lock.Lock() lock.Lock()
defer lock.Unlock() defer lock.Unlock()

View File

@ -20,7 +20,6 @@ import (
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/opengl" "github.com/hajimehoshi/go-ebiten/graphics/opengl"
"runtime" "runtime"
"sync"
"unsafe" "unsafe"
) )
@ -31,7 +30,6 @@ func init() {
type GameContext struct { type GameContext struct {
screenWidth int screenWidth int
screenHeight int screenHeight int
inputState ebiten.InputState
} }
func (context *GameContext) ScreenWidth() int { func (context *GameContext) ScreenWidth() int {
@ -42,18 +40,15 @@ func (context *GameContext) ScreenHeight() int {
return context.screenHeight return context.screenHeight
} }
func (context *GameContext) InputState() ebiten.InputState {
return context.inputState
}
type UI struct { type UI struct {
screenWidth int screenWidth int
screenHeight int screenHeight int
screenScale int screenScale int
graphicsDevice *opengl.Device graphicsDevice *opengl.Device
gameContext *GameContext gameContext *GameContext
gameContextLock sync.Mutex
window unsafe.Pointer window unsafe.Pointer
inputStateUpdatedChs chan chan ebiten.InputStateUpdatedEvent
inputStateUpdatedNotified chan ebiten.InputStateUpdatedEvent
} }
var currentUI *UI var currentUI *UI
@ -69,9 +64,9 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
gameContext: &GameContext{ gameContext: &GameContext{
screenWidth: screenWidth, screenWidth: screenWidth,
screenHeight: screenHeight, screenHeight: screenHeight,
inputState: ebiten.InputState{-1, -1},
}, },
gameContextLock: sync.Mutex{}, inputStateUpdatedChs: make(chan chan ebiten.InputStateUpdatedEvent),
inputStateUpdatedNotified: make(chan ebiten.InputStateUpdatedEvent),
} }
cTitle := C.CString(title) cTitle := C.CString(title)
@ -91,9 +86,26 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
cTitle, cTitle,
context) context)
currentUI = ui currentUI = ui
go ui.chLoop()
return ui return ui
} }
func (ui *UI) chLoop() {
inputStateUpdated := []chan ebiten.InputStateUpdatedEvent{}
for {
select {
case ch := <-ui.inputStateUpdatedChs:
inputStateUpdated = append(inputStateUpdated, ch)
case e := <-ui.inputStateUpdatedNotified:
for _, ch := range inputStateUpdated {
ch <- e
}
}
}
}
func (ui *UI) PollEvents() { func (ui *UI) PollEvents() {
C.PollEvents() C.PollEvents()
} }
@ -105,8 +117,6 @@ func (ui *UI) InitTextures(f func(graphics.TextureFactory)) {
} }
func (ui *UI) Update(f func(ebiten.GameContext)) { func (ui *UI) Update(f func(ebiten.GameContext)) {
ui.gameContextLock.Lock()
defer ui.gameContextLock.Unlock()
f(ui.gameContext) f(ui.gameContext)
} }
@ -116,15 +126,27 @@ func (ui *UI) Draw(f func(graphics.Canvas)) {
C.EndDrawing(ui.window) C.EndDrawing(ui.window)
} }
func (ui *UI) InputStateUpdated() <-chan ebiten.InputStateUpdatedEvent {
ch := make(chan ebiten.InputStateUpdatedEvent)
go func() {
ui.inputStateUpdatedChs <- ch
}()
return ch
}
func (ui *UI) notifyInputStateUpdated(e ebiten.InputStateUpdatedEvent) {
go func() {
ui.inputStateUpdatedNotified <- e
}()
}
//export ebiten_InputUpdated //export ebiten_InputUpdated
func ebiten_InputUpdated(inputType C.InputType, cx, cy C.int) { func ebiten_InputUpdated(inputType C.InputType, cx, cy C.int) {
ui := currentUI ui := currentUI
ui.gameContextLock.Lock()
defer ui.gameContextLock.Unlock()
if inputType == C.InputTypeMouseUp { if inputType == C.InputTypeMouseUp {
ui.gameContext.inputState = ebiten.InputState{-1, -1} e := ebiten.InputStateUpdatedEvent{-1, -1}
ui.notifyInputStateUpdated(e)
return return
} }
@ -141,5 +163,6 @@ func ebiten_InputUpdated(inputType C.InputType, cx, cy C.int) {
} else if ui.screenHeight <= y { } else if ui.screenHeight <= y {
y = ui.screenHeight - 1 y = ui.screenHeight - 1
} }
ui.gameContext.inputState = ebiten.InputState{x, y} e := ebiten.InputStateUpdatedEvent{x, y}
ui.notifyInputStateUpdated(e)
} }

View File

@ -1 +0,0 @@
package ui