Move some definitions to the ui package

This commit is contained in:
Hajime Hoshi 2013-12-03 00:15:01 +09:00
parent add743572c
commit f9e5e754b2
11 changed files with 111 additions and 109 deletions

View File

@ -2,29 +2,29 @@ package input
import ( import (
"fmt" "fmt"
"github.com/hajimehoshi/go-ebiten"
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix" "github.com/hajimehoshi/go-ebiten/graphics/matrix"
"github.com/hajimehoshi/go-ebiten/ui"
"image" "image"
"os" "os"
) )
type Input struct { type Input struct {
textTextureId graphics.TextureId textTextureId graphics.TextureId
inputStateUpdatedCh chan ebiten.InputStateUpdatedEvent inputStateUpdatedCh chan ui.InputStateUpdatedEvent
x int x int
y int y int
} }
func New() *Input { func New() *Input {
return &Input{ return &Input{
inputStateUpdatedCh: make(chan ebiten.InputStateUpdatedEvent), inputStateUpdatedCh: make(chan ui.InputStateUpdatedEvent),
x: -1, x: -1,
y: -1, y: -1,
} }
} }
func (game *Input) OnInputStateUpdated(e ebiten.InputStateUpdatedEvent) { func (game *Input) OnInputStateUpdated(e ui.InputStateUpdatedEvent) {
go func() { go func() {
e := e e := e
game.inputStateUpdatedCh <- e game.inputStateUpdatedCh <- e

View File

@ -1,9 +1,9 @@
package monochrome package monochrome
import ( import (
"github.com/hajimehoshi/go-ebiten"
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix" "github.com/hajimehoshi/go-ebiten/graphics/matrix"
"github.com/hajimehoshi/go-ebiten/ui"
"image" "image"
_ "image/png" _ "image/png"
"os" "os"
@ -19,7 +19,7 @@ type Monochrome struct {
ch chan bool ch chan bool
colorMatrix matrix.Color colorMatrix matrix.Color
geometryMatrix matrix.Geometry geometryMatrix matrix.Geometry
screenSizeUpdatedCh chan ebiten.ScreenSizeUpdatedEvent screenSizeUpdatedCh chan ui.ScreenSizeUpdatedEvent
screenWidth int screenWidth int
screenHeight int screenHeight int
} }
@ -29,11 +29,11 @@ func New() *Monochrome {
ch: make(chan bool), ch: make(chan bool),
colorMatrix: matrix.IdentityColor(), colorMatrix: matrix.IdentityColor(),
geometryMatrix: matrix.IdentityGeometry(), geometryMatrix: matrix.IdentityGeometry(),
screenSizeUpdatedCh: make(chan ebiten.ScreenSizeUpdatedEvent), screenSizeUpdatedCh: make(chan ui.ScreenSizeUpdatedEvent),
} }
} }
func (game *Monochrome) OnScreenSizeUpdated(e ebiten.ScreenSizeUpdatedEvent) { func (game *Monochrome) OnScreenSizeUpdated(e ui.ScreenSizeUpdatedEvent) {
go func() { go func() {
e := e e := e
game.screenSizeUpdatedCh <- e game.screenSizeUpdatedCh <- e

View File

@ -1,9 +1,9 @@
package rects package rects
import ( import (
"github.com/hajimehoshi/go-ebiten"
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix" "github.com/hajimehoshi/go-ebiten/graphics/matrix"
"github.com/hajimehoshi/go-ebiten/ui"
"image/color" "image/color"
"math" "math"
"math/rand" "math/rand"
@ -17,7 +17,7 @@ type Rects struct {
offscreenInited bool offscreenInited bool
rectBounds *graphics.Rect rectBounds *graphics.Rect
rectColor *color.RGBA rectColor *color.RGBA
screenSizeUpdatedCh chan ebiten.ScreenSizeUpdatedEvent screenSizeUpdatedCh chan ui.ScreenSizeUpdatedEvent
screenWidth int screenWidth int
screenHeight int screenHeight int
} }
@ -35,11 +35,11 @@ func New() *Rects {
offscreenInited: false, offscreenInited: false,
rectBounds: &graphics.Rect{}, rectBounds: &graphics.Rect{},
rectColor: &color.RGBA{}, rectColor: &color.RGBA{},
screenSizeUpdatedCh: make(chan ebiten.ScreenSizeUpdatedEvent), screenSizeUpdatedCh: make(chan ui.ScreenSizeUpdatedEvent),
} }
} }
func (game *Rects) OnScreenSizeUpdated(e ebiten.ScreenSizeUpdatedEvent) { func (game *Rects) OnScreenSizeUpdated(e ui.ScreenSizeUpdatedEvent) {
go func() { go func() {
e := e e := e
game.screenSizeUpdatedCh <- e game.screenSizeUpdatedCh <- e

View File

@ -1,9 +1,9 @@
package rotating package rotating
import ( import (
"github.com/hajimehoshi/go-ebiten"
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix" "github.com/hajimehoshi/go-ebiten/graphics/matrix"
"github.com/hajimehoshi/go-ebiten/ui"
"image" "image"
_ "image/png" _ "image/png"
"math" "math"
@ -19,18 +19,18 @@ type Rotating struct {
ebitenTextureId graphics.TextureId ebitenTextureId graphics.TextureId
x int x int
geometryMatrix matrix.Geometry geometryMatrix matrix.Geometry
screenSizeUpdatedCh chan ebiten.ScreenSizeUpdatedEvent screenSizeUpdatedCh chan ui.ScreenSizeUpdatedEvent
screenWidth int screenWidth int
screenHeight int screenHeight int
} }
func New() *Rotating { func New() *Rotating {
return &Rotating{ return &Rotating{
screenSizeUpdatedCh: make(chan ebiten.ScreenSizeUpdatedEvent), screenSizeUpdatedCh: make(chan ui.ScreenSizeUpdatedEvent),
} }
} }
func (game *Rotating) OnScreenSizeUpdated(e ebiten.ScreenSizeUpdatedEvent) { func (game *Rotating) OnScreenSizeUpdated(e ui.ScreenSizeUpdatedEvent) {
go func() { go func() {
e := e e := e
game.screenSizeUpdatedCh <- e game.screenSizeUpdatedCh <- e

View File

@ -1,9 +1,9 @@
package sprites package sprites
import ( import (
"github.com/hajimehoshi/go-ebiten"
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/matrix" "github.com/hajimehoshi/go-ebiten/graphics/matrix"
"github.com/hajimehoshi/go-ebiten/ui"
"image" "image"
"math/rand" "math/rand"
"os" "os"
@ -66,18 +66,18 @@ func (sprite *Sprite) Update() {
type Sprites struct { type Sprites struct {
ebitenTextureId graphics.TextureId ebitenTextureId graphics.TextureId
sprites []*Sprite sprites []*Sprite
screenSizeUpdatedCh chan ebiten.ScreenSizeUpdatedEvent screenSizeUpdatedCh chan ui.ScreenSizeUpdatedEvent
screenWidth int screenWidth int
screenHeight int screenHeight int
} }
func New() *Sprites { func New() *Sprites {
return &Sprites{ return &Sprites{
screenSizeUpdatedCh: make(chan ebiten.ScreenSizeUpdatedEvent), screenSizeUpdatedCh: make(chan ui.ScreenSizeUpdatedEvent),
} }
} }
func (game *Sprites) OnScreenSizeUpdated(e ebiten.ScreenSizeUpdatedEvent) { func (game *Sprites) OnScreenSizeUpdated(e ui.ScreenSizeUpdatedEvent) {
go func() { go func() {
e := e e := e
game.screenSizeUpdatedCh <- e game.screenSizeUpdatedCh <- e

View File

@ -1,7 +1,6 @@
package main package main
import ( import (
"github.com/hajimehoshi/go-ebiten"
"github.com/hajimehoshi/go-ebiten/example/game/blank" "github.com/hajimehoshi/go-ebiten/example/game/blank"
"github.com/hajimehoshi/go-ebiten/example/game/input" "github.com/hajimehoshi/go-ebiten/example/game/input"
"github.com/hajimehoshi/go-ebiten/example/game/monochrome" "github.com/hajimehoshi/go-ebiten/example/game/monochrome"
@ -10,6 +9,7 @@ import (
"github.com/hajimehoshi/go-ebiten/example/game/sprites" "github.com/hajimehoshi/go-ebiten/example/game/sprites"
"github.com/hajimehoshi/go-ebiten/example/game/testpattern" "github.com/hajimehoshi/go-ebiten/example/game/testpattern"
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/ui"
"github.com/hajimehoshi/go-ebiten/ui/cocoa" "github.com/hajimehoshi/go-ebiten/ui/cocoa"
"os" "os"
"runtime" "runtime"
@ -56,38 +56,40 @@ func main() {
const fps = 60 const fps = 60
const title = "Ebiten Demo" const title = "Ebiten Demo"
var ui ebiten.UI = cocoa.New(screenWidth, screenHeight, screenScale, title) var u ui.UI = cocoa.New(screenWidth, screenHeight, screenScale, title)
ui.InitTextures(game.InitTextures) // TODO: Get a map or something
u.LoadResources(game.InitTextures)
drawing := make(chan *graphics.LazyCanvas) drawing := make(chan *graphics.LazyCanvas)
go func() { go func() {
inputStateUpdated := ui.ObserveInputStateUpdated() inputStateUpdated := u.ObserveInputStateUpdated()
screenSizeUpdated := ui.ObserveScreenSizeUpdated() screenSizeUpdated := u.ObserveScreenSizeUpdated()
frameTime := time.Duration(int64(time.Second) / int64(fps)) frameTime := time.Duration(int64(time.Second) / int64(fps))
tick := time.Tick(frameTime) tick := time.Tick(frameTime)
for { for {
select { select {
case e, ok := <-inputStateUpdated: case e, ok := <-inputStateUpdated:
// TODO: Use Adaptor?
if ok { if ok {
type Handler interface { type Handler interface {
OnInputStateUpdated(ebiten.InputStateUpdatedEvent) OnInputStateUpdated(ui.InputStateUpdatedEvent)
} }
if game2, ok := game.(Handler); ok { if game2, ok := game.(Handler); ok {
game2.OnInputStateUpdated(e) game2.OnInputStateUpdated(e)
} }
} }
inputStateUpdated = ui.ObserveInputStateUpdated() inputStateUpdated = u.ObserveInputStateUpdated()
case e, ok := <-screenSizeUpdated: case e, ok := <-screenSizeUpdated:
if ok { if ok {
type Handler interface { type Handler interface {
OnScreenSizeUpdated(e ebiten.ScreenSizeUpdatedEvent) OnScreenSizeUpdated(ui.ScreenSizeUpdatedEvent)
} }
if game2, ok := game.(Handler); ok { if game2, ok := game.(Handler); ok {
game2.OnScreenSizeUpdated(e) game2.OnScreenSizeUpdated(e)
} }
} }
screenSizeUpdated = ui.ObserveScreenSizeUpdated() screenSizeUpdated = u.ObserveScreenSizeUpdated()
case <-tick: case <-tick:
game.Update() game.Update()
case canvas := <-drawing: case canvas := <-drawing:
@ -98,11 +100,11 @@ func main() {
}() }()
for { for {
ui.PollEvents() u.PollEvents()
ui.Draw(func(c graphics.Canvas) { u.Draw(func(actualCanvas graphics.Canvas) {
drawing <- graphics.NewLazyCanvas() drawing <- graphics.NewLazyCanvas()
canvas := <-drawing canvas := <-drawing
canvas.Flush(c) canvas.Flush(actualCanvas)
}) })
} }
} }

View File

@ -7,6 +7,7 @@ import (
type Canvas interface { type Canvas interface {
Clear() Clear()
Fill(r, g, b uint8) Fill(r, g, b uint8)
// TODO: Refacotring
DrawTexture(id TextureId, DrawTexture(id TextureId,
geometryMatrix matrix.Geometry, geometryMatrix matrix.Geometry,
colorMatrix matrix.Color) colorMatrix matrix.Color)

View File

@ -1,9 +1,5 @@
package graphics package graphics
import (
"image"
)
type Rect struct { type Rect struct {
X int X int
Y int Y int
@ -17,11 +13,6 @@ type TexturePart struct {
Source Rect Source Rect
} }
type TextureFactory interface {
CreateRenderTarget(width, height int) (RenderTargetId, error)
CreateTextureFromImage(img image.Image) (TextureId, error)
}
type TextureId int type TextureId int
// A render target is essentially same as a texture, but it is assumed that the // A render target is essentially same as a texture, but it is assumed that the

View File

@ -0,0 +1,10 @@
package graphics
import (
"image"
)
type TextureFactory interface {
CreateRenderTarget(width, height int) (RenderTargetId, error)
CreateTextureFromImage(img image.Image) (TextureId, error)
}

View File

@ -16,9 +16,9 @@ package cocoa
// //
import "C" import "C"
import ( import (
"github.com/hajimehoshi/go-ebiten"
"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"
"github.com/hajimehoshi/go-ebiten/ui"
"runtime" "runtime"
"unsafe" "unsafe"
) )
@ -34,10 +34,10 @@ type UI struct {
graphicsDevice *opengl.Device graphicsDevice *opengl.Device
window unsafe.Pointer window unsafe.Pointer
initialEventSent bool initialEventSent bool
inputStateUpdatedChs chan chan ebiten.InputStateUpdatedEvent inputStateUpdatedChs chan chan ui.InputStateUpdatedEvent
inputStateUpdatedNotified chan ebiten.InputStateUpdatedEvent inputStateUpdatedNotified chan ui.InputStateUpdatedEvent
screenSizeUpdatedChs chan chan ebiten.ScreenSizeUpdatedEvent screenSizeUpdatedChs chan chan ui.ScreenSizeUpdatedEvent
screenSizeUpdatedNotified chan ebiten.ScreenSizeUpdatedEvent screenSizeUpdatedNotified chan ui.ScreenSizeUpdatedEvent
} }
var currentUI *UI var currentUI *UI
@ -46,15 +46,15 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
if currentUI != nil { if currentUI != nil {
panic("UI can't be duplicated.") panic("UI can't be duplicated.")
} }
ui := &UI{ u := &UI{
screenWidth: screenWidth, screenWidth: screenWidth,
screenHeight: screenHeight, screenHeight: screenHeight,
screenScale: screenScale, screenScale: screenScale,
initialEventSent: false, initialEventSent: false,
inputStateUpdatedChs: make(chan chan ebiten.InputStateUpdatedEvent), inputStateUpdatedChs: make(chan chan ui.InputStateUpdatedEvent),
inputStateUpdatedNotified: make(chan ebiten.InputStateUpdatedEvent), inputStateUpdatedNotified: make(chan ui.InputStateUpdatedEvent),
screenSizeUpdatedChs: make(chan chan ebiten.ScreenSizeUpdatedEvent), screenSizeUpdatedChs: make(chan chan ui.ScreenSizeUpdatedEvent),
screenSizeUpdatedNotified: make(chan ebiten.ScreenSizeUpdatedEvent), screenSizeUpdatedNotified: make(chan ui.ScreenSizeUpdatedEvent),
} }
cTitle := C.CString(title) cTitle := C.CString(title)
@ -64,30 +64,30 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
context := C.CreateGLContext(unsafe.Pointer(nil)) context := C.CreateGLContext(unsafe.Pointer(nil))
C.SetCurrentGLContext(context) C.SetCurrentGLContext(context)
ui.graphicsDevice = opengl.NewDevice( u.graphicsDevice = opengl.NewDevice(
ui.screenWidth, u.screenWidth,
ui.screenHeight, u.screenHeight,
ui.screenScale) u.screenScale)
ui.window = C.CreateWindow(C.size_t(ui.screenWidth*ui.screenScale), u.window = C.CreateWindow(C.size_t(u.screenWidth*u.screenScale),
C.size_t(ui.screenHeight*ui.screenScale), C.size_t(u.screenHeight*u.screenScale),
cTitle, cTitle,
context) context)
currentUI = ui currentUI = u
ui.eventLoop() u.eventLoop()
return ui return u
} }
func (ui *UI) eventLoop() { func (u *UI) eventLoop() {
go func() { go func() {
inputStateUpdated := []chan ebiten.InputStateUpdatedEvent{} inputStateUpdated := []chan ui.InputStateUpdatedEvent{}
for { for {
select { select {
case ch := <-ui.inputStateUpdatedChs: case ch := <-u.inputStateUpdatedChs:
inputStateUpdated = append(inputStateUpdated, ch) inputStateUpdated = append(inputStateUpdated, ch)
case e := <-ui.inputStateUpdatedNotified: case e := <-u.inputStateUpdatedNotified:
for _, ch := range inputStateUpdated { for _, ch := range inputStateUpdated {
ch <- e ch <- e
close(ch) close(ch)
@ -98,103 +98,101 @@ func (ui *UI) eventLoop() {
}() }()
go func() { go func() {
screenSizeUpdated := []chan ebiten.ScreenSizeUpdatedEvent{} screenSizeUpdated := []chan ui.ScreenSizeUpdatedEvent{}
for { for {
select { select {
case ch := <-ui.screenSizeUpdatedChs: case ch := <-u.screenSizeUpdatedChs:
screenSizeUpdated = append(screenSizeUpdated, ch) screenSizeUpdated = append(screenSizeUpdated, ch)
case e := <-ui.screenSizeUpdatedNotified: case e := <-u.screenSizeUpdatedNotified:
for _, ch := range screenSizeUpdated { for _, ch := range screenSizeUpdated {
ch <- e ch <- e
close(ch) close(ch)
} }
screenSizeUpdated = []chan ebiten.ScreenSizeUpdatedEvent{} screenSizeUpdated = []chan ui.ScreenSizeUpdatedEvent{}
} }
} }
}() }()
} }
func (ui *UI) PollEvents() { func (u *UI) PollEvents() {
C.PollEvents() C.PollEvents()
if !ui.initialEventSent { if !u.initialEventSent {
e := ebiten.ScreenSizeUpdatedEvent{ui.screenWidth, ui.screenHeight} e := ui.ScreenSizeUpdatedEvent{u.screenWidth, u.screenHeight}
ui.notifyScreenSizeUpdated(e) u.notifyScreenSizeUpdated(e)
ui.initialEventSent = true u.initialEventSent = true
} }
} }
func (ui *UI) InitTextures(f func(graphics.TextureFactory)) { func (u *UI) LoadResources(f func(graphics.TextureFactory)) {
C.BeginDrawing(ui.window) C.BeginDrawing(u.window)
f(ui.graphicsDevice.TextureFactory()) f(u.graphicsDevice.TextureFactory())
C.EndDrawing(ui.window) C.EndDrawing(u.window)
} }
func (ui *UI) Draw(f func(graphics.Canvas)) { func (u *UI) Draw(f func(graphics.Canvas)) {
C.BeginDrawing(ui.window) C.BeginDrawing(u.window)
ui.graphicsDevice.Update(f) u.graphicsDevice.Update(f)
C.EndDrawing(ui.window) C.EndDrawing(u.window)
} }
func (ui *UI) ObserveInputStateUpdated() <-chan ebiten.InputStateUpdatedEvent { func (u *UI) ObserveInputStateUpdated() <-chan ui.InputStateUpdatedEvent {
ch := make(chan ebiten.InputStateUpdatedEvent) ch := make(chan ui.InputStateUpdatedEvent)
go func() { go func() {
ui.inputStateUpdatedChs <- ch u.inputStateUpdatedChs <- ch
}() }()
return ch return ch
} }
func (ui *UI) notifyInputStateUpdated(e ebiten.InputStateUpdatedEvent) { func (u *UI) notifyInputStateUpdated(e ui.InputStateUpdatedEvent) {
go func() { go func() {
e := e u.inputStateUpdatedNotified <- e
ui.inputStateUpdatedNotified <- e
}() }()
} }
func (ui *UI) ObserveScreenSizeUpdated() <-chan ebiten.ScreenSizeUpdatedEvent { func (u *UI) ObserveScreenSizeUpdated() <-chan ui.ScreenSizeUpdatedEvent {
ch := make(chan ebiten.ScreenSizeUpdatedEvent) ch := make(chan ui.ScreenSizeUpdatedEvent)
go func() { go func() {
ui.screenSizeUpdatedChs <- ch u.screenSizeUpdatedChs <- ch
}() }()
return ch return ch
} }
func (ui *UI) notifyScreenSizeUpdated(e ebiten.ScreenSizeUpdatedEvent) { func (u *UI) notifyScreenSizeUpdated(e ui.ScreenSizeUpdatedEvent) {
go func() { go func() {
e := e u.screenSizeUpdatedNotified <- e
ui.screenSizeUpdatedNotified <- e
}() }()
} }
//export ebiten_ScreenSizeUpdated //export ebiten_ScreenSizeUpdated
func ebiten_ScreenSizeUpdated(width, height int) { func ebiten_ScreenSizeUpdated(width, height int) {
ui := currentUI u := currentUI
e := ebiten.ScreenSizeUpdatedEvent{width, height} e := ui.ScreenSizeUpdatedEvent{width, height}
ui.notifyScreenSizeUpdated(e) u.notifyScreenSizeUpdated(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 u := currentUI
if inputType == C.InputTypeMouseUp { if inputType == C.InputTypeMouseUp {
e := ebiten.InputStateUpdatedEvent{-1, -1} e := ui.InputStateUpdatedEvent{-1, -1}
ui.notifyInputStateUpdated(e) u.notifyInputStateUpdated(e)
return return
} }
x, y := int(cx), int(cy) x, y := int(cx), int(cy)
x /= ui.screenScale x /= u.screenScale
y /= ui.screenScale y /= u.screenScale
if x < 0 { if x < 0 {
x = 0 x = 0
} else if ui.screenWidth <= x { } else if u.screenWidth <= x {
x = ui.screenWidth - 1 x = u.screenWidth - 1
} }
if y < 0 { if y < 0 {
y = 0 y = 0
} else if ui.screenHeight <= y { } else if u.screenHeight <= y {
y = ui.screenHeight - 1 y = u.screenHeight - 1
} }
e := ebiten.InputStateUpdatedEvent{x, y} e := ui.InputStateUpdatedEvent{x, y}
ui.notifyInputStateUpdated(e) u.notifyInputStateUpdated(e)
} }

View File

@ -1,4 +1,4 @@
package ebiten package ui
import ( import (
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
@ -21,7 +21,7 @@ type UIEvents interface {
type UI interface { type UI interface {
PollEvents() PollEvents()
InitTextures(func(graphics.TextureFactory)) LoadResources(func(graphics.TextureFactory))
Draw(func(graphics.Canvas)) Draw(func(graphics.Canvas))
UIEvents UIEvents
} }