Added a notification system, hopefully allowing us to merge AppKit requests onto a single thread. In practice, this generates autorelease pool leak messages; it appears notifications are not for this...
This commit is contained in:
parent
3b9e26ab38
commit
6982912a58
|
@ -15,8 +15,12 @@ import (
|
|||
// extern void windowShouldClose(id, SEL, id);
|
||||
// extern id objc_msgSend_id(id, SEL, id);
|
||||
// extern void buttonClicked(id, SEL, id);
|
||||
// /* cgo doesn't like Nil */
|
||||
// extern void gotNotification(id, SEL, id);
|
||||
// extern id objc_msgSend_id_id_id(id, SEL, id, id, id);
|
||||
// /* cgo doesn't like nil or Nil */
|
||||
// extern id objc_msgSend_noargs(id, SEL);
|
||||
// extern Class NilClass; /* in runtimetest.go because of cgo limitations */
|
||||
// extern id Nilid;
|
||||
import "C"
|
||||
|
||||
var NSObject = C.object_getClass(objc_getClass("NSObject"))
|
||||
|
@ -42,7 +46,22 @@ func windowShouldClose(self C.id, sel C.SEL, sender C.id) {
|
|||
|
||||
//export buttonClicked
|
||||
func buttonClicked(self C.id, sel C.SEL, sender C.id) {
|
||||
fmt.Println("button clicked")
|
||||
fmt.Println("button clicked; sending notification...")
|
||||
notify("button")
|
||||
}
|
||||
|
||||
//export gotNotification
|
||||
func gotNotification(self C.id, sel C.SEL, note C.id) {
|
||||
data := C.objc_msgSend_noargs(note,
|
||||
sel_getUid("userInfo"))
|
||||
val := C.objc_msgSend_id(data,
|
||||
sel_getUid("objectForKey:"),
|
||||
notekey)
|
||||
source := (*C.char)(unsafe.Pointer(
|
||||
C.objc_msgSend_noargs(val,
|
||||
sel_getUid("UTF8String"))))
|
||||
fmt.Println("got notification from %s",
|
||||
C.GoString(source))
|
||||
}
|
||||
|
||||
func addOurMethod(class C.Class, sel C.SEL, imp C.IMP) {
|
||||
|
@ -61,7 +80,7 @@ func addOurMethod(class C.Class, sel C.SEL, imp C.IMP) {
|
|||
}
|
||||
}
|
||||
|
||||
func mk(name string, selW C.SEL, selB C.SEL) C.id {
|
||||
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
|
||||
|
@ -69,5 +88,7 @@ func mk(name string, selW C.SEL, selB C.SEL) C.id {
|
|||
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)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
"time"
|
||||
)
|
||||
|
||||
// #cgo LDFLAGS: -lobjc -framework Foundation -framework AppKit
|
||||
|
@ -24,7 +25,11 @@ import (
|
|||
// id objc_msgSend_NSRect(id obj, SEL sel, CGRect a) { return objc_msgSend(obj, sel, a); }
|
||||
// id objc_msgSend_sel(id obj, SEL sel, SEL a) { return objc_msgSend(obj, sel, a); }
|
||||
// id objc_msgSend_uint(id obj, SEL sel, NSUInteger a) { return objc_msgSend(obj, sel, a); }
|
||||
// id objc_msgSend_id_sel_id_id(id obj, SEL sel, id a, SEL b, id c, id d) { return objc_msgSend(obj, sel, a, b, c, d); }
|
||||
// id objc_msgSend_id_id_id(id obj, SEL sel, id a, id b, id c) { return objc_msgSend(obj, sel, a, b, c); }
|
||||
// id objc_msgSend_id_id(id obj, SEL sel, id a, id b) { return objc_msgSend(obj, sel, a, b); }
|
||||
// Class NilClass = Nil; /* for newtypes.go */
|
||||
// id Nilid = nil;
|
||||
import "C"
|
||||
|
||||
func objc_getClass(class string) C.id {
|
||||
|
@ -42,6 +47,10 @@ func sel_getUid(sel string) C.SEL {
|
|||
}
|
||||
|
||||
var NSApp C.id
|
||||
var defNC C.id
|
||||
var delegate C.id
|
||||
var note C.id
|
||||
var notekey C.id
|
||||
|
||||
func init() {
|
||||
// need an NSApplication first - see https://github.com/TooTallNate/NodObjC/issues/21
|
||||
|
@ -49,9 +58,31 @@ func init() {
|
|||
sharedApplication := sel_getUid("sharedApplication")
|
||||
NSApp = C.objc_msgSend_noargs(NSApplication, sharedApplication)
|
||||
|
||||
defNC = C.objc_msgSend_noargs(
|
||||
objc_getClass("NSNotificationCenter"),
|
||||
sel_getUid("defaultCenter"))
|
||||
|
||||
selW := sel_getUid("windowShouldClose:")
|
||||
selB := sel_getUid("buttonClicked:")
|
||||
mk("hello", selW, selB)
|
||||
selN := sel_getUid("gotNotification:")
|
||||
mk("hello", selW, selB, selN)
|
||||
delegate = C.objc_msgSend_noargs(
|
||||
objc_getClass("hello"),
|
||||
alloc)
|
||||
|
||||
noteStr := []C.char{'g', 'o', 'n', 'o', 't', 'e', 0}
|
||||
note = C.objc_msgSend_strarg(
|
||||
objc_getClass("NSString"),
|
||||
sel_getUid("stringWithUTF8String:"),
|
||||
¬eStr[0])
|
||||
notekey = note
|
||||
C.objc_msgSend_id_sel_id_id(
|
||||
defNC,
|
||||
sel_getUid("addObserver:selector:name:object:"),
|
||||
delegate,
|
||||
selN,
|
||||
note,
|
||||
C.Nilid)
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -75,6 +106,27 @@ const (
|
|||
|
||||
var alloc = sel_getUid("alloc")
|
||||
|
||||
func notify(source string) {
|
||||
csource := C.CString(source)
|
||||
defer C.free(unsafe.Pointer(csource))
|
||||
|
||||
src := C.objc_msgSend_strarg(
|
||||
objc_getClass("NSString"),
|
||||
sel_getUid("stringWithUTF8String:"),
|
||||
csource)
|
||||
dict := C.objc_msgSend_id_id(
|
||||
objc_getClass("NSDictionary"),
|
||||
sel_getUid("dictionaryWithObject:forKey:"),
|
||||
src,
|
||||
notekey)
|
||||
C.objc_msgSend_id_id_id(
|
||||
defNC,
|
||||
sel_getUid("postNotificationName:object:userInfo:"),
|
||||
note,
|
||||
C.Nilid,
|
||||
dict)
|
||||
}
|
||||
|
||||
func main() {
|
||||
NSWindow := objc_getClass("NSWindow")
|
||||
NSWindowinit :=
|
||||
|
@ -92,9 +144,6 @@ func main() {
|
|||
window := C.objc_msgSend_noargs(NSWindow, alloc)
|
||||
window = C.objc_msgSend_NSRect_uint_uint_bool(window, NSWindowinit, rect, style, backing, deferx)
|
||||
C.objc_msgSend_id(window, makeKeyAndOrderFront, window)
|
||||
delegate := C.objc_msgSend_noargs(
|
||||
objc_getClass("hello"),
|
||||
alloc)
|
||||
C.objc_msgSend_id(window, setDelegate,
|
||||
delegate)
|
||||
windowView := C.objc_msgSend_noargs(window,
|
||||
|
@ -121,6 +170,14 @@ func main() {
|
|||
sel_getUid("addSubview:"),
|
||||
button)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
<-time.After(5 * time.Second)
|
||||
fmt.Println("five seconds passed; sending notification...")
|
||||
notify("timer")
|
||||
}
|
||||
}()
|
||||
|
||||
C.objc_msgSend_noargs(NSApp,
|
||||
sel_getUid("run"))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue