From 303c66d2b9bcd11d8eceb14207481cae916be845 Mon Sep 17 00:00:00 2001
From: faiface <faiface@ksp.sk>
Date: Sun, 18 Dec 2016 20:16:27 +0100
Subject: [PATCH] remove destructors, instead SetFinalizer

---
 graphics.go        | 24 +-----------------------
 picture.go         | 11 +----------
 pixelgl/shader.go  |  6 ++++--
 pixelgl/texture.go |  6 ++++--
 pixelgl/vertex.go  |  7 +++++--
 window.go          | 10 +++++++---
 6 files changed, 22 insertions(+), 42 deletions(-)

diff --git a/graphics.go b/graphics.go
index db5074b..d6948be 100644
--- a/graphics.go
+++ b/graphics.go
@@ -24,19 +24,6 @@ type Drawer interface {
 	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,
 // 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.
 func (s *Shape) SetPicture(picture Picture) {
 	s.picture = picture
@@ -183,7 +165,7 @@ type MultiShape struct {
 	*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.
 func NewMultiShape(parent pixelgl.Doer, shapes ...*Shape) *MultiShape {
@@ -259,10 +241,6 @@ func NewMultiShape(parent pixelgl.Doer, shapes ...*Shape) *MultiShape {
 		offset += shape.VertexArray().VertexNum()
 	}
 
-	for _, shape := range shapes {
-		shape.Delete()
-	}
-
 	return &MultiShape{NewShape(parent, picture, color.White, Position(0), va)}
 }
 
diff --git a/picture.go b/picture.go
index 8915eaa..fd5287b 100644
--- a/picture.go
+++ b/picture.go
@@ -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 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 {
 	texture *pixelgl.Texture
 	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.
 func (p Picture) IsNil() bool {
 	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
-// 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
 // the upper-right quadrant of the original picture.
diff --git a/pixelgl/shader.go b/pixelgl/shader.go
index 666eed6..da68dbc 100644
--- a/pixelgl/shader.go
+++ b/pixelgl/shader.go
@@ -2,6 +2,7 @@ package pixelgl
 
 import (
 	"fmt"
+	"runtime"
 
 	"github.com/go-gl/gl/v3.3-core/gl"
 	"github.com/go-gl/mathgl/mgl32"
@@ -113,11 +114,12 @@ func NewShader(parent Doer, vertexFmt, uniformFmt AttrFormat, vertexShader, frag
 		return nil, err
 	}
 
+	runtime.SetFinalizer(shader, (*Shader).delete)
+
 	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) {
 		DoNoBlock(func() {
 			gl.DeleteProgram(s.program.obj)
diff --git a/pixelgl/texture.go b/pixelgl/texture.go
index f443081..843ed82 100644
--- a/pixelgl/texture.go
+++ b/pixelgl/texture.go
@@ -1,6 +1,7 @@
 package pixelgl
 
 import "github.com/go-gl/gl/v3.3-core/gl"
+import "runtime"
 
 // Texture is an OpenGL texture.
 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
 }
 
-// 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) {
 		DoNoBlock(func() {
 			gl.DeleteTextures(1, &t.tex.obj)
diff --git a/pixelgl/vertex.go b/pixelgl/vertex.go
index e8c9ca2..f9c67ff 100644
--- a/pixelgl/vertex.go
+++ b/pixelgl/vertex.go
@@ -3,6 +3,8 @@ package pixelgl
 import (
 	"unsafe"
 
+	"runtime"
+
 	"github.com/go-gl/gl/v3.3-core/gl"
 	"github.com/go-gl/mathgl/mgl32"
 	"github.com/pkg/errors"
@@ -107,11 +109,12 @@ func NewVertexArray(parent Doer, format AttrFormat, vertexNum int, indices []int
 
 	va.SetIndices(indices)
 
+	runtime.SetFinalizer(va, (*VertexArray).delete)
+
 	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) {
 		DoNoBlock(func() {
 			gl.DeleteVertexArrays(1, &va.vao.obj)
diff --git a/window.go b/window.go
index 7867ea3..90b90f7 100644
--- a/window.go
+++ b/window.go
@@ -4,6 +4,8 @@ import (
 	"image/color"
 	"sync"
 
+	"runtime"
+
 	"github.com/faiface/pixel/pixelgl"
 	"github.com/go-gl/gl/v3.3-core/gl"
 	"github.com/go-gl/glfw/v3.2/glfw"
@@ -121,15 +123,17 @@ func NewWindow(config WindowConfig) (*Window, error) {
 		w.defaultShader.SetUniformAttr(transformMat3, mgl32.Ident3())
 	})
 	if err != nil {
-		w.Delete()
+		w.Destroy()
 		return nil, errors.Wrap(err, "creating window failed")
 	}
 
+	runtime.SetFinalizer(w, (*Window).Destroy)
+
 	return w, nil
 }
 
-// Delete destroys a window. The window can't be used any further.
-func (w *Window) Delete() {
+// Destroy destroys a window. The window can't be used any further.
+func (w *Window) Destroy() {
 	pixelgl.Do(func() {
 		w.window.Destroy()
 	})
-- 
GitLab