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"
)
type Game interface {
InitTextures(tf graphics.TextureFactory)
Update(context GameContext)
Draw(canvas graphics.Canvas)
}
// TODO: Remove this
type GameContext interface {
ScreenWidth() int
ScreenHeight() int
InputState() InputState
}
type InputState struct {
type ScreenSizeUpdatedEvent struct {
Width int
Height int
}
type InputStateUpdatedEvent struct {
X 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 {
textTextureId graphics.TextureId
inputState ebiten.InputState
inputStateCh chan ebiten.InputStateUpdatedEvent
x int
y int
}
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) {
@ -35,14 +45,22 @@ func (game *Input) InitTextures(tf graphics.TextureFactory) {
}
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) {
g.Fill(128, 128, 255)
str := fmt.Sprintf(`Input State:
X: %d
Y: %d`, game.inputState.X, game.inputState.Y)
Y: %d`, game.x, game.y)
game.drawText(g, str, 5, 5)
}

View File

@ -17,6 +17,12 @@ import (
"time"
)
type Game interface {
InitTextures(tf graphics.TextureFactory)
Update(context ebiten.GameContext)
Draw(canvas graphics.Canvas)
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
@ -25,7 +31,7 @@ func main() {
gameName = os.Args[1]
}
var game ebiten.Game
var game Game
switch gameName {
case "blank":
game = blank.New()
@ -50,7 +56,8 @@ func main() {
const screenScale = 2
const fps = 60
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)
lock := sync.Mutex{}
@ -66,8 +73,24 @@ func main() {
})
}
}()
inputStateUpdated := ui.InputStateUpdated()
for {
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) {
lock.Lock()
defer lock.Unlock()

View File

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