summaryrefslogtreecommitdiff
path: root/uitask_windows.go
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2014-06-30 20:55:42 -0400
committerPietro Gagliardi <[email protected]>2014-06-30 20:55:42 -0400
commit46ba0049cb80d8b6973c3146b40ceceaead710ed (patch)
tree425bb58415d1d06c15c3b23f592ed686b8c536a2 /uitask_windows.go
parent496df12751b029caa7dbbb9480c1a81f242f1c6d (diff)
Converted the Windows backend to make uitask a function that runs the func() passed into it, rather than a channel that sends the function to another dispatcher. Windows lets us, since SendMessage() will switch threads if called form another thread. This gets rid of one goroutine and makes things cleaner. Mac OS X has the same optimization avaialble (performSelectorOnMainThread:); GTK+... doesn't seem to...
Diffstat (limited to 'uitask_windows.go')
-rw-r--r--uitask_windows.go49
1 files changed, 12 insertions, 37 deletions
diff --git a/uitask_windows.go b/uitask_windows.go
index 1075b5b..772403f 100644
--- a/uitask_windows.go
+++ b/uitask_windows.go
@@ -22,17 +22,15 @@ the only recourse, and the one both Microsoft (http://support.microsoft.com/kb/1
yay.
*/
-var uitask chan interface{}
+var uimsgwin _HWND
-type uimsg struct {
- call *syscall.LazyProc
- p []uintptr
- ret chan uiret
-}
-
-type uiret struct {
- ret uintptr
- err error
+// works from any thread; waits for the function to finish before returning
+func uitask(f func()) {
+ _sendMessage.Call(
+ uintptr(uimsgwin),
+ msgRequested,
+ uintptr(0),
+ uintptr(unsafe.Pointer(&f)))
}
const (
@@ -49,34 +47,20 @@ var (
func ui(main func()) error {
runtime.LockOSThread()
- uitask = make(chan interface{})
err := doWindowsInit()
if err != nil {
return fmt.Errorf("error doing general Windows initialization: %v", err)
}
- hwnd, err := makeMessageHandler()
+ uimsgwin, err = makeMessageHandler()
if err != nil {
return fmt.Errorf("error making invisible window for handling events: %v", err)
}
go func() {
- for m := range uitask {
- r1, _, err := _postMessage.Call(
- uintptr(hwnd),
- msgRequested,
- uintptr(0),
- uintptr(unsafe.Pointer(&m)))
- if r1 == 0 { // failure
- panic("error sending message to message loop to call function: " + err.Error())
- }
- }
- }()
-
- go func() {
main()
r1, _, err := _postMessage.Call(
- uintptr(hwnd),
+ uintptr(uimsgwin),
msgQuit,
uintptr(0),
uintptr(0))
@@ -178,17 +162,8 @@ func makeMessageHandler() (hwnd _HWND, err error) {
func messageHandlerWndProc(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam _LPARAM) _LRESULT {
switch uMsg {
case msgRequested:
- mt := (*interface{})(unsafe.Pointer(lParam))
- switch m := (*mt).(type) {
- case *uimsg:
- r1, _, err := m.call.Call(m.p...)
- m.ret <- uiret{
- ret: r1,
- err: err,
- }
- case func():
- m()
- }
+ f := (*func())(unsafe.Pointer(lParam))
+ (*f)()
return 0
case msgQuit:
// does not return a value according to MSDN