Add LazyCanvas

This commit is contained in:
Hajime Hoshi 2013-12-02 21:45:10 +09:00
parent 5eb08941e0
commit add743572c
4 changed files with 121 additions and 48 deletions

View File

@ -13,7 +13,6 @@ import (
"github.com/hajimehoshi/go-ebiten/ui/cocoa" "github.com/hajimehoshi/go-ebiten/ui/cocoa"
"os" "os"
"runtime" "runtime"
"sync"
"time" "time"
) )
@ -60,25 +59,13 @@ func main() {
var ui ebiten.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{} drawing := make(chan *graphics.LazyCanvas)
go func() { go func() {
inputStateUpdated := ui.ObserveInputStateUpdated()
screenSizeUpdated := ui.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 {
<-tick
func() {
lock.Lock()
defer lock.Unlock()
game.Update()
}()
}
}()
inputStateUpdated := ui.ObserveInputStateUpdated()
screenSizeUpdated := ui.ObserveScreenSizeUpdated()
for {
ui.PollEvents()
events:
for { for {
select { select {
case e, ok := <-inputStateUpdated: case e, ok := <-inputStateUpdated:
@ -101,14 +88,21 @@ func main() {
} }
} }
screenSizeUpdated = ui.ObserveScreenSizeUpdated() screenSizeUpdated = ui.ObserveScreenSizeUpdated()
default: case <-tick:
break events game.Update()
case canvas := <-drawing:
game.Draw(canvas)
drawing <- canvas
} }
} }
}()
for {
ui.PollEvents()
ui.Draw(func(c graphics.Canvas) { ui.Draw(func(c graphics.Canvas) {
lock.Lock() drawing <- graphics.NewLazyCanvas()
defer lock.Unlock() canvas := <-drawing
game.Draw(c) canvas.Flush(c)
}) })
} }
} }

102
graphics/canvas.go Normal file
View File

@ -0,0 +1,102 @@
package graphics
import (
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
)
type Canvas interface {
Clear()
Fill(r, g, b uint8)
DrawTexture(id TextureId,
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color)
DrawRenderTarget(id RenderTargetId,
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color)
DrawTextureParts(id TextureId,
parts []TexturePart,
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color)
DrawRenderTargetParts(id RenderTargetId,
parts []TexturePart,
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color)
ResetOffscreen()
SetOffscreen(id RenderTargetId)
}
type LazyCanvas struct {
funcs []func(Canvas)
}
func NewLazyCanvas() *LazyCanvas {
return &LazyCanvas{
funcs: []func(Canvas){},
}
}
func (c *LazyCanvas) Flush(actual Canvas) {
for _, f := range c.funcs {
f(actual)
}
c.funcs = []func(Canvas){}
}
func (c *LazyCanvas) Clear() {
c.funcs = append(c.funcs, func(actual Canvas) {
actual.Clear()
})
}
func (c *LazyCanvas) Fill(r, g, b uint8) {
c.funcs = append(c.funcs, func(actual Canvas) {
actual.Fill(r, g, b)
})
}
func (c *LazyCanvas) DrawTexture(id TextureId,
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color) {
c.funcs = append(c.funcs, func(actual Canvas) {
actual.DrawTexture(id, geometryMatrix, colorMatrix)
})
}
func (c *LazyCanvas) DrawRenderTarget(id RenderTargetId,
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color) {
c.funcs = append(c.funcs, func(actual Canvas) {
actual.DrawRenderTarget(id, geometryMatrix, colorMatrix)
})
}
func (c *LazyCanvas) DrawTextureParts(id TextureId,
parts []TexturePart,
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color) {
c.funcs = append(c.funcs, func(actual Canvas) {
actual.DrawTextureParts(id, parts, geometryMatrix, colorMatrix)
})
}
func (c *LazyCanvas) DrawRenderTargetParts(id RenderTargetId,
parts []TexturePart,
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color) {
c.funcs = append(c.funcs, func(actual Canvas) {
actual.DrawRenderTargetParts(id, parts, geometryMatrix, colorMatrix)
})
}
func (c *LazyCanvas) ResetOffscreen() {
c.funcs = append(c.funcs, func(actual Canvas) {
actual.ResetOffscreen()
})
}
func (c *LazyCanvas) SetOffscreen(id RenderTargetId) {
c.funcs = append(c.funcs, func(actual Canvas) {
actual.SetOffscreen(id)
})
}

View File

@ -1,7 +1,6 @@
package graphics package graphics
import ( import (
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
"image" "image"
) )
@ -18,28 +17,6 @@ type TexturePart struct {
Source Rect Source Rect
} }
type Canvas interface {
Clear()
Fill(r, g, b uint8)
DrawTexture(id TextureId,
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color)
DrawRenderTarget(id RenderTargetId,
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color)
DrawTextureParts(id TextureId,
parts []TexturePart,
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color)
DrawRenderTargetParts(id RenderTargetId,
parts []TexturePart,
geometryMatrix matrix.Geometry,
colorMatrix matrix.Color)
ResetOffscreen()
SetOffscreen(id RenderTargetId)
}
type TextureFactory interface { type TextureFactory interface {
CreateRenderTarget(width, height int) (RenderTargetId, error) CreateRenderTarget(width, height int) (RenderTargetId, error)
CreateTextureFromImage(img image.Image) (TextureId, error) CreateTextureFromImage(img image.Image) (TextureId, error)

View File

@ -1,12 +1,12 @@
package matrix package matrix
type Affine interface { type affine interface {
Dim() int Dim() int
element(i, j int) float64 element(i, j int) float64
setElement(i, j int, element float64) setElement(i, j int, element float64)
} }
func isIdentity(matrix Affine) bool { func isIdentity(matrix affine) bool {
dim := matrix.Dim() dim := matrix.Dim()
for i := 0; i < dim-1; i++ { for i := 0; i < dim-1; i++ {
for j := 0; j < dim; j++ { for j := 0; j < dim; j++ {
@ -21,7 +21,7 @@ func isIdentity(matrix Affine) bool {
return true return true
} }
func mul(lhs, rhs, result Affine) { func mul(lhs, rhs, result affine) {
dim := lhs.Dim() dim := lhs.Dim()
if dim != rhs.Dim() { if dim != rhs.Dim() {
panic("diffrent-sized matrices can't be multiplied") panic("diffrent-sized matrices can't be multiplied")