summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--darwintest/delegate.go43
-rw-r--r--darwintest/newtypes.go54
-rw-r--r--darwintest/runtimetest.go1
3 files changed, 51 insertions, 47 deletions
diff --git a/darwintest/delegate.go b/darwintest/delegate.go
new file mode 100644
index 0000000..d0cd3e7
--- /dev/null
+++ b/darwintest/delegate.go
@@ -0,0 +1,43 @@
+// 28 february 2014
+package main
+
+import (
+ "fmt"
+)
+
+// #cgo LDFLAGS: -lobjc -framework Foundation -framework AppKit
+// #include "objc_darwin.h"
+// extern void windowShouldClose(id, SEL, id);
+// extern void buttonClicked(id, SEL, id);
+// extern void gotNotification(id, SEL, id);
+import "C"
+
+// TODO move these around later
+var (
+ _stop = sel_getUid("stop:")
+)
+
+//export windowShouldClose
+func windowShouldClose(self C.id, sel C.SEL, sender C.id) {
+ fmt.Println("-[hello windowShouldClose:]")
+ C.objc_msgSend_id(NSApp, _stop, sender)
+}
+
+//export buttonClicked
+func buttonClicked(self C.id, sel C.SEL, sender C.id) {
+ fmt.Println("button clicked; sending notification...")
+ notify("button")
+}
+
+//export gotNotification
+func gotNotification(self C.id, sel C.SEL, object C.id) {
+ fmt.Printf("got notification from %s\n", fromNSString(object))
+}
+
+func mk(name string, selW C.SEL, selB C.SEL, selN C.SEL) C.id {
+ class := newClass(name)
+ addDelegateMethod(class, selW, C.windowShouldClose)
+ addDelegateMethod(class, selB, C.buttonClicked)
+ addDelegateMethod(class, selN, C.gotNotification)
+ return objc_getClass(name)
+}
diff --git a/darwintest/newtypes.go b/darwintest/newtypes.go
index f054a54..97c1d82 100644
--- a/darwintest/newtypes.go
+++ b/darwintest/newtypes.go
@@ -2,19 +2,14 @@
package main
import (
- "fmt"
"unsafe"
)
-// #cgo CFLAGS: -Dqqq
// #cgo LDFLAGS: -lobjc -framework Foundation
// #include <stdlib.h>
// #include "objc_darwin.h"
-// extern void windowShouldClose(id, SEL, id);
-// extern void buttonClicked(id, SEL, id);
-// extern void gotNotification(id, SEL, id);
// /* because cgo doesn't like Nil */
-// extern Class NilClass; /* defined in runtimetest.go due to cgo limitations */
+// Class NilClass = Nil;
import "C"
var (
@@ -29,56 +24,23 @@ func newClass(name string) C.Class {
if c == C.NilClass {
panic("unable to create Objective-C class " + name)
}
+ C.objc_registerClassPair(c)
return c
}
-// TODO move these around later
-var (
- _stop = sel_getUid("stop:")
-)
-
-//export windowShouldClose
-func windowShouldClose(self C.id, sel C.SEL, sender C.id) {
- fmt.Println("-[hello windowShouldClose:]")
- C.objc_msgSend_id(NSApp, _stop, sender)
-}
-
-//export buttonClicked
-func buttonClicked(self C.id, sel C.SEL, sender C.id) {
- fmt.Println("button clicked; sending notification...")
- notify("button")
-}
-
-//export gotNotification
-func gotNotification(self C.id, sel C.SEL, object C.id) {
- fmt.Printf("got notification from %s\n", fromNSString(object))
-}
-
-func addOurMethod(class C.Class, sel C.SEL, imp C.IMP) {
-// ty := []C.char{'v', '@', ':', 0} // according to the example for class_addMethod()
+// according to errors spit out by cgo, C function pointers are unsafe.Pointer
+func addDelegateMethod(class C.Class, sel C.SEL, imp unsafe.Pointer) {
+ // maps to void (*)(id, SEL, id)
ty := []C.char{'v', '@', ':', '@', 0}
// clas methods get stored in the metaclass; the objc_allocateClassPair() docs say this will work
-// metaclass := C.object_getClass(C.id(unsafe.Pointer(class)))
-// ok := C.class_addMethod(metaclass,
+ // metaclass := C.object_getClass(C.id(unsafe.Pointer(class)))
+ // we're adding instance methods, so just class will do
ok := C.class_addMethod(class,
sel,
- imp,
+ C.IMP(imp),
&ty[0])
if ok == C.BOOL(C.NO) {
panic("unable to add ourMethod")
}
}
-
-func mk(name string, selW C.SEL, selB C.SEL, selN C.SEL) C.id {
- class := newClass(name)
- addOurMethod(class, selW,
- // using &C.ourMethod causes faults for some reason
- C.IMP(unsafe.Pointer(C.windowShouldClose)))
- C.objc_registerClassPair(class)
- addOurMethod(class, selB,
- C.IMP(unsafe.Pointer(C.buttonClicked)))
- addOurMethod(class, selN,
- C.IMP(unsafe.Pointer(C.gotNotification)))
- return objc_getClass(name)
-}
diff --git a/darwintest/runtimetest.go b/darwintest/runtimetest.go
index aafc074..6a8149f 100644
--- a/darwintest/runtimetest.go
+++ b/darwintest/runtimetest.go
@@ -9,7 +9,6 @@ import (
// #cgo LDFLAGS: -lobjc -framework Foundation -framework AppKit
// #include <stdlib.h>
// #include "objc_darwin.h"
-// Class NilClass = Nil; /* for newtypes.go; here due to cgo limitations */
import "C"
var (