summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2014-07-01 17:11:08 -0400
committerPietro Gagliardi <[email protected]>2014-07-01 17:11:08 -0400
commit37051f5c15ba64f22de431c41cb88947af361b32 (patch)
tree45f05f54e53a776cc68c5546bfa5b14d24dc97e3
parent2a7152339fd5cd7306bdc420ffea7b3af4f6845e (diff)
Migrated the Mac OS X backend to the new uitask system.
-rw-r--r--delegateuitask_darwin.m17
-rw-r--r--objc_darwin.h3
-rw-r--r--uitask_darwin.go36
3 files changed, 40 insertions, 16 deletions
diff --git a/delegateuitask_darwin.m b/delegateuitask_darwin.m
index e30ebc2..4d38e3a 100644
--- a/delegateuitask_darwin.m
+++ b/delegateuitask_darwin.m
@@ -56,11 +56,15 @@ extern NSRect dummyRect;
@implementation appDelegate
-- (void)uitask:(NSValue *)fp
+// these are the uitask actions
+
+- (void)createWindow:(NSValue *)fp
{
- appDelegate_uitask([fp pointerValue]);
+ uitask_createWindow([fp pointerValue]);
}
+// these are the other delegate functions
+
- (BOOL)windowShouldClose:(id)win
{
return appDelegate_windowShouldClose(win);
@@ -111,6 +115,9 @@ id windowGetContentView(id window)
return [((NSWindow *) window) contentView];
}
+// these are for douitask() but are here because @selector() is not a constant expression
+SEL createWindow;
+
BOOL initCocoa(id appDelegate)
{
// on 10.6 the -[NSApplication setDelegate:] method complains if we don't have one
@@ -124,11 +131,13 @@ BOOL initCocoa(id appDelegate)
return NO;
[NSApp activateIgnoringOtherApps:YES]; // TODO actually do C.NO here? Russ Cox does YES in his devdraw; the docs say the Finder does NO
[NSApp setDelegate:appDelegate];
+ // uitask selectors
+ createWindow = @selector(createWindow:);
[pool release];
return YES;
}
-void douitask(id appDelegate, void *p)
+void douitask(id appDelegate, SEL sel, void *p)
{
NSAutoreleasePool *pool;
NSValue *fp;
@@ -136,7 +145,7 @@ void douitask(id appDelegate, void *p)
// we need to make an NSAutoreleasePool, otherwise we get leak warnings on stderr
pool = [NSAutoreleasePool new];
fp = [NSValue valueWithPointer:p];
- [appDelegate performSelectorOnMainThread:@selector(uitask:)
+ [appDelegate performSelectorOnMainThread:sel
withObject:fp
waitUntilDone:YES]; // wait so we can properly drain the autorelease pool; on other platforms we wind up waiting anyway (since the main thread can only handle one thing at a time) so
[pool release];
diff --git a/objc_darwin.h b/objc_darwin.h
index 8174ec1..aa2f59f 100644
--- a/objc_darwin.h
+++ b/objc_darwin.h
@@ -63,7 +63,8 @@ extern uintptr_t keyCode(id);
extern id makeAppDelegate(void);
extern id windowGetContentView(id);
extern BOOL initCocoa(id);
-extern void douitask(id, void *);
+extern SEL createWindow;
+extern void douitask(id, SEL, void *);
extern void breakMainLoop(void);
extern void cocoaMainLoop(void);
diff --git a/uitask_darwin.go b/uitask_darwin.go
index 317cb12..7eecd4f 100644
--- a/uitask_darwin.go
+++ b/uitask_darwin.go
@@ -13,7 +13,28 @@ import (
// #include "objc_darwin.h"
import "C"
-var uitask chan func()
+// the performSelectorOnMainThread: in our uitask functions is told to wait until the action is done before it returns
+// so we're fine keeping this on the Go side since the GC won't collect it from under us
+type uitaskParams struct {
+ window *Window // createWindow
+ control Control // createWindow
+ show bool // createWindow
+}
+
+//export uitask_createWindow
+func uitask_createWindow(data unsafe.Pointer) {
+ uc := (*uitaskParams)(data)
+ uc.window.create(uc.control, uc.show)
+}
+
+func (_uitask) createWindow(w *Window, c Control, s bool) {
+ uc := &uitaskParams{
+ window: w,
+ control: c,
+ show: s,
+ }
+ C.douitask(appDelegate, C.createWindow, unsafe.Pointer(uc))
+}
func uiinit() error {
err := initCocoa()
@@ -21,22 +42,15 @@ func uiinit() error {
return err
}
- // do this at the end in case something goes wrong
- uitask = make(chan func())
return nil
}
func ui() {
// Cocoa must run on the first thread created by the program, so we run our dispatcher on another thread instead
go func() {
- for {
- select {
- case f := <-uitask:
- C.douitask(appDelegate, unsafe.Pointer(&f))
- case <-Stop:
- C.breakMainLoop()
- }
- }
+ <-Stop
+ // TODO is this function thread-safe?
+ C.breakMainLoop()
}()
C.cocoaMainLoop()