Refactor dispatching

This commit is contained in:
Lea Anthony 2022-12-14 07:52:10 +11:00
commit bb36ce61bc
No known key found for this signature in database
GPG key ID: 33DAF7BB90A58405
4 changed files with 35 additions and 36 deletions

View file

@ -1,22 +1,16 @@
//go:build darwin
package application
/*
extern void dispatch(unsigned int id);
*/
import "C"
import (
"sync"
)
var mainThreadFuntionStore = make(map[uint]func())
var mainThreadFuntionStoreLock sync.RWMutex
var mainThreadFunctionStore = make(map[uint]func())
var mainThreadFunctionStoreLock sync.RWMutex
func generateFunctionStoreID() uint {
startID := 0
for {
if _, ok := mainThreadFuntionStore[uint(startID)]; !ok {
if _, ok := mainThreadFunctionStore[uint(startID)]; !ok {
return uint(startID)
}
startID++
@ -26,23 +20,11 @@ func generateFunctionStoreID() uint {
}
}
func Dispatch(fn func()) {
mainThreadFuntionStoreLock.Lock()
func DispatchOnMainThread(fn func()) {
mainThreadFunctionStoreLock.Lock()
id := generateFunctionStoreID()
mainThreadFuntionStore[id] = fn
mainThreadFuntionStoreLock.Unlock()
C.dispatch(C.uint(id))
}
//export dispatchCallback
func dispatchCallback(callbackID C.uint) {
mainThreadFuntionStoreLock.RLock()
id := uint(callbackID)
fn := mainThreadFuntionStore[id]
if fn == nil {
Fatal("dispatchCallback called with invalid id: ", id)
}
delete(mainThreadFuntionStore, id)
mainThreadFuntionStoreLock.RUnlock()
fn()
mainThreadFunctionStore[id] = fn
mainThreadFunctionStoreLock.Unlock()
// Call platform specific dispatch function
platformDispatch(id)
}

View file

@ -10,7 +10,7 @@ package application
extern void dispatchCallback(unsigned int);
void dispatch(unsigned int id) {
static void dispatch(unsigned int id) {
dispatch_async(dispatch_get_main_queue(), ^{
dispatchCallback(id);
});
@ -18,3 +18,20 @@ void dispatch(unsigned int id) {
*/
import "C"
func platformDispatch(id uint) {
C.dispatch(C.uint(id))
}
//export dispatchCallback
func dispatchCallback(callbackID C.uint) {
mainThreadFunctionStoreLock.RLock()
id := uint(callbackID)
fn := mainThreadFunctionStore[id]
if fn == nil {
Fatal("dispatchCallback called with invalid id: ", id)
}
delete(mainThreadFunctionStore, id)
mainThreadFunctionStoreLock.RUnlock()
fn()
}

View file

@ -86,7 +86,7 @@ func (s *macosSystemTray) setMenu(menu *Menu) {
}
func (s *macosSystemTray) run() {
Dispatch(func() {
DispatchOnMainThread(func() {
if s.nsStatusItem != nil {
Fatal("System tray '%d' already running", s.id)
}
@ -110,7 +110,7 @@ func (s *macosSystemTray) run() {
func (s *macosSystemTray) setIcon(icon []byte) {
s.icon = icon
Dispatch(func() {
DispatchOnMainThread(func() {
s.nsImage = unsafe.Pointer(C.imageFromBytes((*C.uchar)(&icon[0]), C.int(len(icon))))
C.systemTraySetIcon(s.nsStatusItem, s.nsImage, C.int(s.iconPosition))
})

View file

@ -493,7 +493,7 @@ func (w *macosWindow) syncMainThreadReturningBool(fn func() bool) bool {
var wg sync.WaitGroup
wg.Add(1)
var result bool
Dispatch(func() {
DispatchOnMainThread(func() {
result = fn()
wg.Done()
})
@ -569,7 +569,7 @@ func (w *macosWindow) size() (int, int) {
var width, height C.int
var wg sync.WaitGroup
wg.Add(1)
Dispatch(func() {
DispatchOnMainThread(func() {
C.windowGetSize(w.nsWindow, &width, &height)
wg.Done()
})
@ -581,7 +581,7 @@ func (w *macosWindow) width() int {
var width C.int
var wg sync.WaitGroup
wg.Add(1)
Dispatch(func() {
DispatchOnMainThread(func() {
width = C.windowGetWidth(w.nsWindow)
wg.Done()
})
@ -592,7 +592,7 @@ func (w *macosWindow) height() int {
var height C.int
var wg sync.WaitGroup
wg.Add(1)
Dispatch(func() {
DispatchOnMainThread(func() {
height = C.windowGetHeight(w.nsWindow)
wg.Done()
})
@ -601,7 +601,7 @@ func (w *macosWindow) height() int {
}
func (w *macosWindow) run() {
Dispatch(func() {
DispatchOnMainThread(func() {
w.nsWindow = C.windowNew(C.uint(w.id), C.int(w.options.Width), C.int(w.options.Height))
w.setTitle(w.options.Title)
w.setAlwaysOnTop(w.options.AlwaysOnTop)
@ -668,7 +668,7 @@ func (w *macosWindow) position() (int, int) {
var x, y C.int
var wg sync.WaitGroup
wg.Add(1)
go Dispatch(func() {
go DispatchOnMainThread(func() {
C.windowGetPosition(w.nsWindow, &x, &y)
wg.Done()
})