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 void windowShouldClose(id, SEL, id);
|
||||||
// extern id objc_msgSend_id(id, SEL, id);
|
// extern id objc_msgSend_id(id, SEL, id);
|
||||||
// extern void buttonClicked(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 Class NilClass; /* in runtimetest.go because of cgo limitations */
|
||||||
|
// extern id Nilid;
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
var NSObject = C.object_getClass(objc_getClass("NSObject"))
|
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
|
//export buttonClicked
|
||||||
func buttonClicked(self C.id, sel C.SEL, sender C.id) {
|
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) {
|
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)
|
class := newClass(name)
|
||||||
addOurMethod(class, selW,
|
addOurMethod(class, selW,
|
||||||
// using &C.ourMethod causes faults for some reason
|
// 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)
|
C.objc_registerClassPair(class)
|
||||||
addOurMethod(class, selB,
|
addOurMethod(class, selB,
|
||||||
C.IMP(unsafe.Pointer(C.buttonClicked)))
|
C.IMP(unsafe.Pointer(C.buttonClicked)))
|
||||||
|
addOurMethod(class, selN,
|
||||||
|
C.IMP(unsafe.Pointer(C.gotNotification)))
|
||||||
return objc_getClass(name)
|
return objc_getClass(name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// #cgo LDFLAGS: -lobjc -framework Foundation -framework AppKit
|
// #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_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_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_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 */
|
// Class NilClass = Nil; /* for newtypes.go */
|
||||||
|
// id Nilid = nil;
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
func objc_getClass(class string) C.id {
|
func objc_getClass(class string) C.id {
|
||||||
|
@ -42,6 +47,10 @@ func sel_getUid(sel string) C.SEL {
|
||||||
}
|
}
|
||||||
|
|
||||||
var NSApp C.id
|
var NSApp C.id
|
||||||
|
var defNC C.id
|
||||||
|
var delegate C.id
|
||||||
|
var note C.id
|
||||||
|
var notekey C.id
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// need an NSApplication first - see https://github.com/TooTallNate/NodObjC/issues/21
|
// need an NSApplication first - see https://github.com/TooTallNate/NodObjC/issues/21
|
||||||
|
@ -49,9 +58,31 @@ func init() {
|
||||||
sharedApplication := sel_getUid("sharedApplication")
|
sharedApplication := sel_getUid("sharedApplication")
|
||||||
NSApp = C.objc_msgSend_noargs(NSApplication, sharedApplication)
|
NSApp = C.objc_msgSend_noargs(NSApplication, sharedApplication)
|
||||||
|
|
||||||
|
defNC = C.objc_msgSend_noargs(
|
||||||
|
objc_getClass("NSNotificationCenter"),
|
||||||
|
sel_getUid("defaultCenter"))
|
||||||
|
|
||||||
selW := sel_getUid("windowShouldClose:")
|
selW := sel_getUid("windowShouldClose:")
|
||||||
selB := sel_getUid("buttonClicked:")
|
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 (
|
const (
|
||||||
|
@ -75,6 +106,27 @@ const (
|
||||||
|
|
||||||
var alloc = sel_getUid("alloc")
|
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() {
|
func main() {
|
||||||
NSWindow := objc_getClass("NSWindow")
|
NSWindow := objc_getClass("NSWindow")
|
||||||
NSWindowinit :=
|
NSWindowinit :=
|
||||||
|
@ -92,9 +144,6 @@ func main() {
|
||||||
window := C.objc_msgSend_noargs(NSWindow, alloc)
|
window := C.objc_msgSend_noargs(NSWindow, alloc)
|
||||||
window = C.objc_msgSend_NSRect_uint_uint_bool(window, NSWindowinit, rect, style, backing, deferx)
|
window = C.objc_msgSend_NSRect_uint_uint_bool(window, NSWindowinit, rect, style, backing, deferx)
|
||||||
C.objc_msgSend_id(window, makeKeyAndOrderFront, window)
|
C.objc_msgSend_id(window, makeKeyAndOrderFront, window)
|
||||||
delegate := C.objc_msgSend_noargs(
|
|
||||||
objc_getClass("hello"),
|
|
||||||
alloc)
|
|
||||||
C.objc_msgSend_id(window, setDelegate,
|
C.objc_msgSend_id(window, setDelegate,
|
||||||
delegate)
|
delegate)
|
||||||
windowView := C.objc_msgSend_noargs(window,
|
windowView := C.objc_msgSend_noargs(window,
|
||||||
|
@ -121,6 +170,14 @@ func main() {
|
||||||
sel_getUid("addSubview:"),
|
sel_getUid("addSubview:"),
|
||||||
button)
|
button)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
<-time.After(5 * time.Second)
|
||||||
|
fmt.Println("five seconds passed; sending notification...")
|
||||||
|
notify("timer")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
C.objc_msgSend_noargs(NSApp,
|
C.objc_msgSend_noargs(NSApp,
|
||||||
sel_getUid("run"))
|
sel_getUid("run"))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue