remove destructors, instead SetFinalizer

This commit is contained in:
faiface 2016-12-18 20:16:27 +01:00
parent 5f657bafef
commit 303c66d2b9
6 changed files with 22 additions and 42 deletions

View File

@ -24,19 +24,6 @@ type Drawer interface {
Draw(t ...Transform) Draw(t ...Transform)
} }
// Deleter is anything that can be deleted. All graphics objects that have some associated video memory
// are deleters. It is necessary to call Delete when you're done with an object, otherwise you're going
// to have video memory leaks.
type Deleter interface {
Delete()
}
// DrawDeleter combines Drawer and Deleter interfaces.
type DrawDeleter interface {
Drawer
Deleter
}
// Group is used to effeciently handle a collection of objects with a common parent. Usually many objects share a parent, // Group is used to effeciently handle a collection of objects with a common parent. Usually many objects share a parent,
// using a group can significantly increase performance in these cases. // using a group can significantly increase performance in these cases.
// //
@ -110,11 +97,6 @@ func NewShape(parent pixelgl.Doer, picture Picture, c color.Color, transform Tra
} }
} }
// Delete deletes the underlying
func (s *Shape) Delete() {
s.va.Delete()
}
// SetPicture changes the picture of a shape. // SetPicture changes the picture of a shape.
func (s *Shape) SetPicture(picture Picture) { func (s *Shape) SetPicture(picture Picture) {
s.picture = picture s.picture = picture
@ -183,7 +165,7 @@ type MultiShape struct {
*Shape *Shape
} }
// NewMultiShape creates a new multishape from several other shapes. These shapes are automatically deleted after creating a multishape. // NewMultiShape creates a new multishape from several other shapes.
// //
// If two of the supplied shapes have different pictures, this function panics. // If two of the supplied shapes have different pictures, this function panics.
func NewMultiShape(parent pixelgl.Doer, shapes ...*Shape) *MultiShape { func NewMultiShape(parent pixelgl.Doer, shapes ...*Shape) *MultiShape {
@ -259,10 +241,6 @@ func NewMultiShape(parent pixelgl.Doer, shapes ...*Shape) *MultiShape {
offset += shape.VertexArray().VertexNum() offset += shape.VertexArray().VertexNum()
} }
for _, shape := range shapes {
shape.Delete()
}
return &MultiShape{NewShape(parent, picture, color.White, Position(0), va)} return &MultiShape{NewShape(parent, picture, color.White, Position(0), va)}
} }

View File

@ -12,9 +12,6 @@ import (
// //
// A picture is created from an image.Image, that can be either loaded from a file, or generated. After the creation // A picture is created from an image.Image, that can be either loaded from a file, or generated. After the creation
// a picture can be sliced (slicing creates a "sub-picture" from a picture) into smaller pictures. // a picture can be sliced (slicing creates a "sub-picture" from a picture) into smaller pictures.
//
// However note, that all of the sliced pictures share the same underlying texture. Deleting one picture also deletes
// all pictures that share the same underlying texture.
type Picture struct { type Picture struct {
texture *pixelgl.Texture texture *pixelgl.Texture
bounds Rect bounds Rect
@ -42,12 +39,6 @@ func NewPicture(img image.Image) Picture {
} }
} }
// Delete deletes this picture and all pictures that share the same underlying texuture (all that have been
// created from the same parent using slicing).
func (p Picture) Delete() {
p.texture.Delete()
}
// IsNil returns true if a picture is no picture. // IsNil returns true if a picture is no picture.
func (p Picture) IsNil() bool { func (p Picture) IsNil() bool {
return p.texture == nil return p.texture == nil
@ -61,7 +52,7 @@ func (p Picture) Texture() *pixelgl.Texture {
} }
// Slice returns a picture within the supplied rectangle of the original picture. The original and the sliced picture // Slice returns a picture within the supplied rectangle of the original picture. The original and the sliced picture
// share the same texture. Thus deleting one also deletes the other one. // share the same texture.
// //
// For example, suppose we have a 100x200 pixels picture. If we slice it with rectangle (50, 100, 50, 100), we get // For example, suppose we have a 100x200 pixels picture. If we slice it with rectangle (50, 100, 50, 100), we get
// the upper-right quadrant of the original picture. // the upper-right quadrant of the original picture.

View File

@ -2,6 +2,7 @@ package pixelgl
import ( import (
"fmt" "fmt"
"runtime"
"github.com/go-gl/gl/v3.3-core/gl" "github.com/go-gl/gl/v3.3-core/gl"
"github.com/go-gl/mathgl/mgl32" "github.com/go-gl/mathgl/mgl32"
@ -113,11 +114,12 @@ func NewShader(parent Doer, vertexFmt, uniformFmt AttrFormat, vertexShader, frag
return nil, err return nil, err
} }
runtime.SetFinalizer(shader, (*Shader).delete)
return shader, nil return shader, nil
} }
// Delete deletes a shader program. Don't use a shader after deletion. func (s *Shader) delete() {
func (s *Shader) Delete() {
s.parent.Do(func(ctx Context) { s.parent.Do(func(ctx Context) {
DoNoBlock(func() { DoNoBlock(func() {
gl.DeleteProgram(s.program.obj) gl.DeleteProgram(s.program.obj)

View File

@ -1,6 +1,7 @@
package pixelgl package pixelgl
import "github.com/go-gl/gl/v3.3-core/gl" import "github.com/go-gl/gl/v3.3-core/gl"
import "runtime"
// Texture is an OpenGL texture. // Texture is an OpenGL texture.
type Texture struct { type Texture struct {
@ -45,11 +46,12 @@ func NewTexture(parent Doer, width, height int, pixels []uint8) (*Texture, error
}) })
}) })
runtime.SetFinalizer(texture, (*Texture).delete)
return texture, nil return texture, nil
} }
// Delete deletes a texture. Don't use a texture after deletion. func (t *Texture) delete() {
func (t *Texture) Delete() {
t.parent.Do(func(ctx Context) { t.parent.Do(func(ctx Context) {
DoNoBlock(func() { DoNoBlock(func() {
gl.DeleteTextures(1, &t.tex.obj) gl.DeleteTextures(1, &t.tex.obj)

View File

@ -3,6 +3,8 @@ package pixelgl
import ( import (
"unsafe" "unsafe"
"runtime"
"github.com/go-gl/gl/v3.3-core/gl" "github.com/go-gl/gl/v3.3-core/gl"
"github.com/go-gl/mathgl/mgl32" "github.com/go-gl/mathgl/mgl32"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -107,11 +109,12 @@ func NewVertexArray(parent Doer, format AttrFormat, vertexNum int, indices []int
va.SetIndices(indices) va.SetIndices(indices)
runtime.SetFinalizer(va, (*VertexArray).delete)
return va, nil return va, nil
} }
// Delete deletes a vertex array and it's associated vertex buffer. Don't use a vertex array after deletion. func (va *VertexArray) delete() {
func (va *VertexArray) Delete() {
va.parent.Do(func(ctx Context) { va.parent.Do(func(ctx Context) {
DoNoBlock(func() { DoNoBlock(func() {
gl.DeleteVertexArrays(1, &va.vao.obj) gl.DeleteVertexArrays(1, &va.vao.obj)

View File

@ -4,6 +4,8 @@ import (
"image/color" "image/color"
"sync" "sync"
"runtime"
"github.com/faiface/pixel/pixelgl" "github.com/faiface/pixel/pixelgl"
"github.com/go-gl/gl/v3.3-core/gl" "github.com/go-gl/gl/v3.3-core/gl"
"github.com/go-gl/glfw/v3.2/glfw" "github.com/go-gl/glfw/v3.2/glfw"
@ -121,15 +123,17 @@ func NewWindow(config WindowConfig) (*Window, error) {
w.defaultShader.SetUniformAttr(transformMat3, mgl32.Ident3()) w.defaultShader.SetUniformAttr(transformMat3, mgl32.Ident3())
}) })
if err != nil { if err != nil {
w.Delete() w.Destroy()
return nil, errors.Wrap(err, "creating window failed") return nil, errors.Wrap(err, "creating window failed")
} }
runtime.SetFinalizer(w, (*Window).Destroy)
return w, nil return w, nil
} }
// Delete destroys a window. The window can't be used any further. // Destroy destroys a window. The window can't be used any further.
func (w *Window) Delete() { func (w *Window) Destroy() {
pixelgl.Do(func() { pixelgl.Do(func() {
w.window.Destroy() w.window.Destroy()
}) })