Refactoring

This commit is contained in:
Hajime Hoshi 2013-06-27 01:46:13 +09:00
parent 9dd6fff9ab
commit ef6d643438
4 changed files with 63 additions and 56 deletions

View File

@ -2,8 +2,6 @@ package ebiten
import (
"github.com/hajimehoshi/go.ebiten/graphics"
"runtime"
"time"
)
type TapInfo struct {
@ -21,7 +19,7 @@ type Game interface {
}
type UI interface {
Run(device graphics.Device)
Run()
}
type InputState struct {
@ -29,35 +27,3 @@ type InputState struct {
X int
Y int
}
func mainLoop(game Game, input <-chan InputState, draw <-chan chan graphics.Drawable) {
frameTime := time.Duration(int64(time.Second) / int64(game.Fps()))
update := time.Tick(frameTime)
for {
select {
case <-update:
inputState := <-input
game.Update(inputState)
case gameDraw := <-draw:
gameDraw <- game
// TODO: wait!
}
}
}
func Run(game Game, ui UI,
screenScale int,
graphicsDevice graphics.Device,
input <-chan InputState) {
draw := graphicsDevice.Drawing()
go mainLoop(game, input, draw)
// UI should be executed on the main thread.
ui.Run(graphicsDevice)
}
func init() {
runtime.LockOSThread()
}

View File

@ -27,6 +27,7 @@ import (
"github.com/hajimehoshi/go.ebiten/graphics/opengl"
"os"
"runtime"
"time"
"unsafe"
)
@ -45,16 +46,18 @@ type GlutInputEvent struct {
type GlutUI struct {
screenScale int
device graphics.Device
glutInputEventCh chan GlutInputEvent
updating chan chan func()
}
var currentUI *GlutUI
//export display
func display() {
// TODO: Use channels?
currentUI.device.Update()
ch := make(chan func())
currentUI.updating <- ch
f := <-ch
f()
C.glutSwapBuffers()
}
@ -81,10 +84,11 @@ func idle() {
C.glutPostRedisplay()
}
func NewGlutUI(screenWidth, screenHeight, screenScale int) *GlutUI{
func NewGlutUI(screenWidth, screenHeight, screenScale int) *GlutUI {
ui := &GlutUI{
screenScale: screenScale,
screenScale: screenScale,
glutInputEventCh: make(chan GlutInputEvent, 10),
updating: make(chan chan func()),
}
cargs := []*C.char{}
@ -113,8 +117,7 @@ func NewGlutUI(screenWidth, screenHeight, screenScale int) *GlutUI{
return ui
}
func (ui *GlutUI) Run(device graphics.Device) {
ui.device = device
func (ui *GlutUI) Run() {
C.glutMainLoop()
}
@ -126,24 +129,24 @@ func main() {
gameName = os.Args[1]
}
var gm ebiten.Game
var game ebiten.Game
switch gameName {
case "blank":
gm = blank.New()
game = blank.New()
case "monochrome":
gm = monochrome.New()
game = monochrome.New()
case "rects":
gm = rects.New()
game = rects.New()
case "rotating":
gm = rotating.New()
game = rotating.New()
case "sprites":
gm = sprites.New()
game = sprites.New()
default:
gm = rotating.New()
game = rotating.New()
}
screenScale := 2
currentUI = NewGlutUI(gm.ScreenWidth(), gm.ScreenHeight(), screenScale)
currentUI = NewGlutUI(game.ScreenWidth(), game.ScreenHeight(), screenScale)
input := make(chan ebiten.InputState)
go func() {
@ -170,8 +173,38 @@ func main() {
}()
graphicsDevice := opengl.NewDevice(
gm.ScreenWidth(), gm.ScreenHeight(), screenScale)
game.ScreenWidth(), game.ScreenHeight(), screenScale,
currentUI.updating)
gm.Init(graphicsDevice.TextureFactory())
ebiten.Run(gm, currentUI, screenScale, graphicsDevice, input)
game.Init(graphicsDevice.TextureFactory())
draw := graphicsDevice.Drawing()
go func() {
frameTime := time.Duration(int64(time.Second) / int64(game.Fps()))
update := time.Tick(frameTime)
for {
select {
case <-update:
inputState := <-input
game.Update(inputState)
case gameDraw := <-draw:
ch := make(chan interface{})
s := &SyncDrawable{game, ch}
gameDraw <- s
<-ch
}
}
}()
currentUI.Run()
}
type SyncDrawable struct {
drawable graphics.Drawable
ch chan interface{}
}
func (s *SyncDrawable) Draw(g graphics.GraphicsContext, offscreen graphics.Texture) {
s.drawable.Draw(g, offscreen)
close(s.ch)
}

View File

@ -11,7 +11,6 @@ type Drawable interface {
}
type Device interface {
Update()
TextureFactory() TextureFactory
Drawing() <-chan chan Drawable
}

View File

@ -17,10 +17,10 @@ type Device struct {
graphicsContext *GraphicsContext
offscreenTexture graphics.Texture
deviceUpdate chan chan graphics.Drawable
updating chan chan func()
}
func NewDevice(screenWidth, screenHeight, screenScale int) *Device {
func NewDevice(screenWidth, screenHeight, screenScale int, updating chan chan func()) *Device {
graphicsContext := newGraphicsContext(screenWidth, screenHeight, screenScale)
device := &Device{
@ -29,9 +29,18 @@ func NewDevice(screenWidth, screenHeight, screenScale int) *Device {
screenScale: screenScale,
deviceUpdate: make(chan chan graphics.Drawable),
graphicsContext: graphicsContext,
updating: updating,
}
device.offscreenTexture =
device.graphicsContext.NewTexture(screenWidth, screenHeight)
go func() {
for {
ch := <-device.updating
ch <- device.Update
}
}()
return device
}