summaryrefslogtreecommitdiff
path: root/main.go
blob: 154192d7b2982279073b67c3c23f96dcdc8eacb4 (plain)
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
// 11 december 2015

package ui

import (
	"errors"
)

// #include "interop.h"
import "C"

// Main initializes package ui, runs f to set up the program,
// and executes the GUI main loop. f should set up the program's
// initial state: open the main window, create controls, and set up
// events. It should then return, at which point Main will
// process events until Quit is called, at which point Main will return
// nil. If package ui fails to initialize, Main returns an appropriate
// error.
func Main(f func()) error {
	errchan := make(chan error)
	go start(errchan, f)
	return <-errchan
}

func start(errchan chan error, f func()) {
	estr := C.interopInit()
	if estr != "" {
		errchan <- errors.New(C.GoString(estr))
		C.interopFreeStr(estr)
		return
	}
	QueueMain(f)
	C.interopRun()
	errchan <- nil
}

// Quit queues an exit from the GUI thread. It does not exit the
// program. Quit must be called from the GUI thread.
func Quit() {
	C.interopQuit()
}

// QueueMain queues f to be executed on the GUI thread when
// next possible. It returns immediately; that is, it does not wait
// for the function to actually be executed. QueueMain is the only
// function that can be called from other goroutines, and its
// primary purpose is to allow communication between other
// goroutines and the GUI thread. Calling QueueMain after Quit
// has been called results in undefined behavior.
func QueueMain(f func()) {
	n := interoperAdd(f)
	C.interopQueueMain(n)
}

//export interopDoQueued
func interopDoQueued(n C.uintptr_t) {
	ff := interoperTake(n)
	f := ff.(func())
	f()
}