From add743572ce1c20214d16408487800061c78f29a Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Mon, 2 Dec 2013 21:45:10 +0900 Subject: [PATCH] Add LazyCanvas --- example/main.go | 38 ++++++-------- graphics/canvas.go | 102 ++++++++++++++++++++++++++++++++++++++ graphics/graphics.go | 23 --------- graphics/matrix/affine.go | 6 +-- 4 files changed, 121 insertions(+), 48 deletions(-) create mode 100644 graphics/canvas.go diff --git a/example/main.go b/example/main.go index 4c66b561d..59f12a1ee 100644 --- a/example/main.go +++ b/example/main.go @@ -13,7 +13,6 @@ import ( "github.com/hajimehoshi/go-ebiten/ui/cocoa" "os" "runtime" - "sync" "time" ) @@ -60,25 +59,13 @@ func main() { var ui ebiten.UI = cocoa.New(screenWidth, screenHeight, screenScale, title) ui.InitTextures(game.InitTextures) - lock := sync.Mutex{} + drawing := make(chan *graphics.LazyCanvas) go func() { + inputStateUpdated := ui.ObserveInputStateUpdated() + screenSizeUpdated := ui.ObserveScreenSizeUpdated() + frameTime := time.Duration(int64(time.Second) / int64(fps)) 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 { select { case e, ok := <-inputStateUpdated: @@ -101,14 +88,21 @@ func main() { } } screenSizeUpdated = ui.ObserveScreenSizeUpdated() - default: - break events + case <-tick: + game.Update() + case canvas := <-drawing: + game.Draw(canvas) + drawing <- canvas } } + }() + + for { + ui.PollEvents() ui.Draw(func(c graphics.Canvas) { - lock.Lock() - defer lock.Unlock() - game.Draw(c) + drawing <- graphics.NewLazyCanvas() + canvas := <-drawing + canvas.Flush(c) }) } } diff --git a/graphics/canvas.go b/graphics/canvas.go new file mode 100644 index 000000000..9869157b5 --- /dev/null +++ b/graphics/canvas.go @@ -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) + }) +} diff --git a/graphics/graphics.go b/graphics/graphics.go index ba9d587bd..49625a797 100644 --- a/graphics/graphics.go +++ b/graphics/graphics.go @@ -1,7 +1,6 @@ package graphics import ( - "github.com/hajimehoshi/go-ebiten/graphics/matrix" "image" ) @@ -18,28 +17,6 @@ type TexturePart struct { 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 { CreateRenderTarget(width, height int) (RenderTargetId, error) CreateTextureFromImage(img image.Image) (TextureId, error) diff --git a/graphics/matrix/affine.go b/graphics/matrix/affine.go index b83541c2d..12f24bf21 100644 --- a/graphics/matrix/affine.go +++ b/graphics/matrix/affine.go @@ -1,12 +1,12 @@ package matrix -type Affine interface { +type affine interface { Dim() int element(i, j int) float64 setElement(i, j int, element float64) } -func isIdentity(matrix Affine) bool { +func isIdentity(matrix affine) bool { dim := matrix.Dim() for i := 0; i < dim-1; i++ { for j := 0; j < dim; j++ { @@ -21,7 +21,7 @@ func isIdentity(matrix Affine) bool { return true } -func mul(lhs, rhs, result Affine) { +func mul(lhs, rhs, result affine) { dim := lhs.Dim() if dim != rhs.Dim() { panic("diffrent-sized matrices can't be multiplied")