-
Notifications
You must be signed in to change notification settings - Fork 0
/
dull.go
104 lines (88 loc) · 2.43 KB
/
dull.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package dull
//go:generate go-bindata -pkg internal -o internal/asset.go internal/font/data/...
import (
"github.com/faiface/mainthread"
"github.com/go-gl/glfw/v3.2/glfw"
"github.com/pkg/errors"
"sync"
)
var glfwTerminated = false
var glfwTerminatedLock sync.Mutex
// InitialisedFn is a function that will be called
// once library initialisation is complete.
//
// A window (or windows) will normally be created within
// this function.
//
// If something went wrong during initialisation, perhaps openGL
// could not be initialised, then err will be an error.
//
// See also the Run function.
type InitialisedFn func(app *Application, err error)
// Run must be the first dull function called.
//
// The initialisedFn function will be called once the library
// has been initialised, and functions other than Run may be called.
// The function will typically create and show a window
// (or multiple windows).
//
// The initialisedFn function will run on the main thread.
//
// Run blocks, and will not return until dull has terminated.
// This will typically be when all windows have closed.
func Run(initialisedFn InitialisedFn) {
mainthread.Run(func() {
run(initialisedFn)
})
}
// DoWait will run a function on the main thread.
// It blocks, and does not return until the function fn finishes.
//
// Some API functions need to run on the main thread.
// See the package documentation for more details.
func DoWait(fn func()) {
glfwTerminatedLock.Lock()
defer glfwTerminatedLock.Unlock()
if glfwTerminated {
return
}
go glfw.PostEmptyEvent()
mainthread.Call(fn)
}
// DoNoWait will run a function on the main thread.
// It returns immediately, and does not wait for the function fn to finish.
//
// Some API functions need to run on the main thread.
// See the package documentation for more details.
func DoNoWait(fn func()) {
glfwTerminatedLock.Lock()
defer glfwTerminatedLock.Unlock()
if glfwTerminated {
return
}
go glfw.PostEmptyEvent()
mainthread.CallNonBlock(fn)
}
func run(initialised InitialisedFn) {
app := &Application{
fontRenderer: FontRendererFreetype,
}
mainthread.Call(func() {
err := glfw.Init()
if err != nil {
initialised(nil, errors.Wrap(err, "Failed to initialise GLFW"))
return
}
initialised(app, nil)
})
defer func() {
app.terminate()
mainthread.Call(func() {
glfw.Terminate()
glfwTerminatedLock.Lock()
defer glfwTerminatedLock.Unlock()
glfwTerminated = true
})
}()
app.run()
}