Remove TODOs; Hide some structs

This commit is contained in:
Hajime Hoshi 2014-12-08 00:07:36 +09:00
parent 4c79f1bccd
commit ca99e94b5c
8 changed files with 99 additions and 87 deletions

View File

@ -67,6 +67,19 @@ func (f *Field) AbsorbPiece(piece *Piece, x, y int, angle Angle) {
f.Flush() f.Flush()
} }
func (f *Field) setBlock(x, y int, blockType BlockType) {
f.blocks[x][y] = blockType
}
func (f *Field) Flush() {
flushedLineNum := 0
for j := fieldBlockNumY - 1; 0 <= j; j-- {
if f.flushLine(j + flushedLineNum) {
flushedLineNum++
}
}
}
func (f *Field) flushLine(j int) bool { func (f *Field) flushLine(j int) bool {
for i := 0; i < fieldBlockNumX; i++ { for i := 0; i < fieldBlockNumX; i++ {
if f.blocks[i][j] == BlockTypeNone { if f.blocks[i][j] == BlockTypeNone {
@ -84,15 +97,6 @@ func (f *Field) flushLine(j int) bool {
return true return true
} }
func (f *Field) Flush() {
flushedLineNum := 0
for j := fieldBlockNumY - 1; 0 <= j; j-- {
if f.flushLine(j + flushedLineNum) {
flushedLineNum++
}
}
}
func (f *Field) Draw(context graphics.Context, textures *Textures, geo matrix.Geometry) { func (f *Field) Draw(context graphics.Context, textures *Textures, geo matrix.Geometry) {
blocks := make([][]BlockType, len(f.blocks)) blocks := make([][]BlockType, len(f.blocks))
for i, blockCol := range f.blocks { for i, blockCol := range f.blocks {

View File

@ -198,8 +198,7 @@ func (p *Piece) AbsorbInto(field *Field, x, y int, angle Angle) {
for i := 0; i < size; i++ { for i := 0; i < size; i++ {
for j := 0; j < size; j++ { for j := 0; j < size; j++ {
if p.isBlocked(i, j, angle) { if p.isBlocked(i, j, angle) {
// TODO: Is it OK to access field.block directly? field.setBlock(x+i, y+j, p.blockType)
field.blocks[x+i][y+j] = p.blockType
} }
} }
} }

View File

@ -26,37 +26,36 @@ func TestGeometryConcat(t *testing.T) {
{0, 1, 1}, {0, 1, 1},
} }
// TODO: 'matrix1x2' may not be a good name. matrix3 := matrix1
matrix1x2 := matrix1 matrix3.Concat(matrix2)
matrix1x2.Concat(matrix2)
expected := [][]float64{ expected := [][]float64{
{2, 0, 1}, {2, 0, 1},
{0, 2, 1}, {0, 2, 1},
} }
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ { for j := 0; j < 3; j++ {
got := matrix1x2.Elements[i][j] got := matrix3.Elements[i][j]
want := expected[i][j] want := expected[i][j]
if want != got { if want != got {
t.Errorf("matrix1x2.Element(%d, %d) = %f,"+ t.Errorf("matrix3.Element(%d, %d) = %f,"+
" want %f", " want %f",
i, j, got, want) i, j, got, want)
} }
} }
} }
matrix2x1 := matrix2 matrix4 := matrix2
matrix2x1.Concat(matrix1) matrix4.Concat(matrix1)
expected = [][]float64{ expected = [][]float64{
{2, 0, 2}, {2, 0, 2},
{0, 2, 2}, {0, 2, 2},
} }
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ { for j := 0; j < 3; j++ {
got := matrix2x1.Elements[i][j] got := matrix4.Elements[i][j]
want := expected[i][j] want := expected[i][j]
if want != got { if want != got {
t.Errorf("matrix2x1.Element(%d, %d) = %f, want %f", t.Errorf("matrix4.Element(%d, %d) = %f, want %f",
i, j, got, want) i, j, got, want)
} }
} }

View File

@ -8,13 +8,23 @@ import (
"sync" "sync"
) )
func flush() { type ContextUpdater struct {
gl.Flush() context *context
}
func NewContextUpdater(screenWidth, screenHeight, screenScale int) *ContextUpdater {
return &ContextUpdater{
context: newContext(screenWidth, screenHeight, screenScale),
}
}
func (u *ContextUpdater) Update(drawer ui.Drawer) error {
return u.context.update(drawer)
} }
var onceInit sync.Once var onceInit sync.Once
type Context struct { type context struct {
screenId graphics.RenderTargetID screenId graphics.RenderTargetID
defaultId graphics.RenderTargetID defaultId graphics.RenderTargetID
currentId graphics.RenderTargetID currentId graphics.RenderTargetID
@ -23,44 +33,68 @@ type Context struct {
screenScale int screenScale int
} }
func NewContext(screenWidth, screenHeight, screenScale int) *Context { func newContext(screenWidth, screenHeight, screenScale int) *context {
onceInit.Do(func() { onceInit.Do(func() {
gl.Init() gl.Init()
gl.Enable(gl.TEXTURE_2D) gl.Enable(gl.TEXTURE_2D)
gl.Enable(gl.BLEND) gl.Enable(gl.BLEND)
}) })
context := &Context{ c := &context{
screenWidth: screenWidth, screenWidth: screenWidth,
screenHeight: screenHeight, screenHeight: screenHeight,
screenScale: screenScale, screenScale: screenScale,
} }
defaultRenderTarget := &RenderTarget{ // The defualt framebuffer should be 0.
defaultRenderTarget := &renderTarget{
width: screenWidth * screenScale, width: screenWidth * screenScale,
height: screenHeight * screenScale, height: screenHeight * screenScale,
flipY: true, flipY: true,
} }
context.defaultId = idsInstance.addRenderTarget(defaultRenderTarget) c.defaultId = idsInstance.addRenderTarget(defaultRenderTarget)
var err error var err error
context.screenId, err = idsInstance.createRenderTarget(screenWidth, screenHeight, graphics.FilterNearest) c.screenId, err = idsInstance.createRenderTarget(screenWidth, screenHeight, graphics.FilterNearest)
if err != nil { if err != nil {
panic("opengl.NewContext: initializing the offscreen failed: " + err.Error()) panic("opengl.NewContext: initializing the offscreen failed: " + err.Error())
} }
context.ResetOffscreen() c.ResetOffscreen()
context.Clear() c.Clear()
return context return c
} }
func (c *Context) Dispose() { func (c *context) dispose() {
// TODO: remove the default framebuffer? // NOTE: Now this method is not used anywhere.
idsInstance.deleteRenderTarget(c.screenId) idsInstance.deleteRenderTarget(c.screenId)
} }
// TODO: This interface is confusing: Can we change this? func (c *context) Clear() {
func (c *Context) Update(drawer ui.Drawer) error { c.Fill(0, 0, 0)
}
func (c *context) Fill(r, g, b uint8) {
idsInstance.fillRenderTarget(c.currentId, r, g, b)
}
func (c *context) Texture(id graphics.TextureID) graphics.Drawer {
return &textureWithContext{id, c}
}
func (c *context) RenderTarget(id graphics.RenderTargetID) graphics.Drawer {
return &textureWithContext{idsInstance.toTexture(id), c}
}
func (c *context) ResetOffscreen() {
c.currentId = c.screenId
}
func (c *context) SetOffscreen(renderTargetId graphics.RenderTargetID) {
c.currentId = renderTargetId
}
func (c *context) update(drawer ui.Drawer) error {
c.ResetOffscreen() c.ResetOffscreen()
c.Clear() c.Clear()
@ -76,37 +110,13 @@ func (c *Context) Update(drawer ui.Drawer) error {
geo.Scale(scale, scale) geo.Scale(scale, scale)
graphics.DrawWhole(c.RenderTarget(c.screenId), c.screenWidth, c.screenHeight, geo, matrix.ColorI()) graphics.DrawWhole(c.RenderTarget(c.screenId), c.screenWidth, c.screenHeight, geo, matrix.ColorI())
flush() gl.Flush()
return nil return nil
} }
func (c *Context) Clear() {
c.Fill(0, 0, 0)
}
func (c *Context) Fill(r, g, b uint8) {
idsInstance.fillRenderTarget(c.currentId, r, g, b)
}
func (c *Context) Texture(id graphics.TextureID) graphics.Drawer {
return &textureWithContext{id, c}
}
func (c *Context) RenderTarget(id graphics.RenderTargetID) graphics.Drawer {
return &textureWithContext{idsInstance.toTexture(id), c}
}
func (c *Context) ResetOffscreen() {
c.currentId = c.screenId
}
func (c *Context) SetOffscreen(renderTargetId graphics.RenderTargetID) {
c.currentId = renderTargetId
}
type textureWithContext struct { type textureWithContext struct {
id graphics.TextureID id graphics.TextureID
context *Context context *context
} }
func (t *textureWithContext) Draw(parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) { func (t *textureWithContext) Draw(parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) {

View File

@ -11,8 +11,8 @@ import (
) )
type ids struct { type ids struct {
textures map[graphics.TextureID]*Texture textures map[graphics.TextureID]*texture
renderTargets map[graphics.RenderTargetID]*RenderTarget renderTargets map[graphics.RenderTargetID]*renderTarget
renderTargetToTexture map[graphics.RenderTargetID]graphics.TextureID renderTargetToTexture map[graphics.RenderTargetID]graphics.TextureID
lastId int lastId int
currentRenderTargetId graphics.RenderTargetID currentRenderTargetId graphics.RenderTargetID
@ -20,8 +20,8 @@ type ids struct {
} }
var idsInstance = &ids{ var idsInstance = &ids{
textures: map[graphics.TextureID]*Texture{}, textures: map[graphics.TextureID]*texture{},
renderTargets: map[graphics.RenderTargetID]*RenderTarget{}, renderTargets: map[graphics.RenderTargetID]*renderTarget{},
renderTargetToTexture: map[graphics.RenderTargetID]graphics.TextureID{}, renderTargetToTexture: map[graphics.RenderTargetID]graphics.TextureID{},
currentRenderTargetId: -1, currentRenderTargetId: -1,
} }
@ -34,13 +34,13 @@ func NewTextureID(img image.Image, filter graphics.Filter) (graphics.TextureID,
return idsInstance.createTexture(img, filter) return idsInstance.createTexture(img, filter)
} }
func (i *ids) textureAt(id graphics.TextureID) *Texture { func (i *ids) textureAt(id graphics.TextureID) *texture {
i.RLock() i.RLock()
defer i.RUnlock() defer i.RUnlock()
return i.textures[id] return i.textures[id]
} }
func (i *ids) renderTargetAt(id graphics.RenderTargetID) *RenderTarget { func (i *ids) renderTargetAt(id graphics.RenderTargetID) *renderTarget {
i.RLock() i.RLock()
defer i.RUnlock() defer i.RUnlock()
return i.renderTargets[id] return i.renderTargets[id]
@ -74,7 +74,7 @@ func (i *ids) createRenderTarget(width, height int, filter graphics.Filter) (gra
framebuffer := createFramebuffer(gl.Texture(texture.native)) framebuffer := createFramebuffer(gl.Texture(texture.native))
// The current binded framebuffer can be changed. // The current binded framebuffer can be changed.
i.currentRenderTargetId = -1 i.currentRenderTargetId = -1
renderTarget := &RenderTarget{ r := &renderTarget{
framebuffer: framebuffer, framebuffer: framebuffer,
width: texture.width, width: texture.width,
height: texture.height, height: texture.height,
@ -88,14 +88,14 @@ func (i *ids) createRenderTarget(width, height int, filter graphics.Filter) (gra
renderTargetId := graphics.RenderTargetID(i.lastId) renderTargetId := graphics.RenderTargetID(i.lastId)
i.textures[textureId] = texture i.textures[textureId] = texture
i.renderTargets[renderTargetId] = renderTarget i.renderTargets[renderTargetId] = r
i.renderTargetToTexture[renderTargetId] = textureId i.renderTargetToTexture[renderTargetId] = textureId
return renderTargetId, nil return renderTargetId, nil
} }
// NOTE: renderTarget can't be used as a texture. // NOTE: renderTarget can't be used as a texture.
func (i *ids) addRenderTarget(renderTarget *RenderTarget) graphics.RenderTargetID { func (i *ids) addRenderTarget(renderTarget *renderTarget) graphics.RenderTargetID {
i.Lock() i.Lock()
defer i.Unlock() defer i.Unlock()
i.lastId++ i.lastId++

View File

@ -20,7 +20,7 @@ func orthoProjectionMatrix(left, right, bottom, top int) [4][4]float64 {
} }
} }
type RenderTarget struct { type renderTarget struct {
framebuffer gl.Framebuffer framebuffer gl.Framebuffer
width int width int
height int height int
@ -45,7 +45,7 @@ func createFramebuffer(nativeTexture gl.Texture) gl.Framebuffer {
return framebuffer return framebuffer
} }
func (r *RenderTarget) setAsViewport() { func (r *renderTarget) setAsViewport() {
gl.Flush() gl.Flush()
r.framebuffer.Bind() r.framebuffer.Bind()
err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER) err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
@ -60,7 +60,7 @@ func (r *RenderTarget) setAsViewport() {
gl.Viewport(0, 0, width, height) gl.Viewport(0, 0, width, height)
} }
func (r *RenderTarget) projectionMatrix() [4][4]float64 { func (r *renderTarget) projectionMatrix() [4][4]float64 {
width := shader.AdjustSizeForTexture(r.width) width := shader.AdjustSizeForTexture(r.width)
height := shader.AdjustSizeForTexture(r.height) height := shader.AdjustSizeForTexture(r.height)
matrix := orthoProjectionMatrix(0, width, 0, height) matrix := orthoProjectionMatrix(0, width, 0, height)
@ -71,6 +71,6 @@ func (r *RenderTarget) projectionMatrix() [4][4]float64 {
return matrix return matrix
} }
func (r *RenderTarget) dispose() { func (r *renderTarget) dispose() {
r.framebuffer.Delete() r.framebuffer.Delete()
} }

View File

@ -31,7 +31,7 @@ func adjustImageForTexture(img image.Image) *image.NRGBA {
return adjustedImage return adjustedImage
} }
type Texture struct { type texture struct {
native gl.Texture native gl.Texture
width int width int
height int height int
@ -67,20 +67,20 @@ func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, filter
return nativeTexture return nativeTexture
} }
func createTexture(width, height int, filter graphics.Filter) (*Texture, error) { func createTexture(width, height int, filter graphics.Filter) (*texture, error) {
w := shader.AdjustSizeForTexture(width) w := shader.AdjustSizeForTexture(width)
h := shader.AdjustSizeForTexture(height) h := shader.AdjustSizeForTexture(height)
native := createNativeTexture(w, h, nil, filter) native := createNativeTexture(w, h, nil, filter)
return &Texture{native, width, height}, nil return &texture{native, width, height}, nil
} }
func createTextureFromImage(img image.Image, filter graphics.Filter) (*Texture, error) { func createTextureFromImage(img image.Image, filter graphics.Filter) (*texture, error) {
adjustedImage := adjustImageForTexture(img) adjustedImage := adjustImageForTexture(img)
size := adjustedImage.Bounds().Size() size := adjustedImage.Bounds().Size()
native := createNativeTexture(size.X, size.Y, adjustedImage.Pix, filter) native := createNativeTexture(size.X, size.Y, adjustedImage.Pix, filter)
return &Texture{native, size.X, size.Y}, nil return &texture{native, size.X, size.Y}, nil
} }
func (t *Texture) dispose() { func (t *texture) dispose() {
t.native.Delete() t.native.Delete()
} }

View File

@ -12,7 +12,7 @@ import (
type canvas struct { type canvas struct {
window *glfw.Window window *glfw.Window
context *opengl.Context contextUpdater *opengl.ContextUpdater
keyboard *keyboard keyboard *keyboard
funcs chan func() funcs chan func()
funcsDone chan struct{} funcsDone chan struct{}
@ -39,14 +39,14 @@ func newCanvas(width, height, scale int, title string) *canvas {
canvas.run() canvas.run()
canvas.use(func() { canvas.use(func() {
canvas.context = opengl.NewContext(width, height, realScale) canvas.contextUpdater = opengl.NewContextUpdater(width, height, realScale)
}) })
return canvas return canvas
} }
func (c *canvas) Draw(d ui.Drawer) (err error) { func (c *canvas) Draw(d ui.Drawer) (err error) {
c.use(func() { c.use(func() {
err = c.context.Update(d) err = c.contextUpdater.Update(d)
c.window.SwapBuffers() c.window.SwapBuffers()
}) })
return return