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 // #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 // #include "objc_darwin.h" -// Class NilClass = Nil; /* for newtypes.go; here due to cgo limitations */ import "C" var (