/* * The distinction here involves messaging to superclasses, with message receipt to the subclass. This * requires initing a structure that refers to both the receiver and its superclass. */ func (obj Object) CallSuper(method string, args ...Passable) Object { if obj == 0 { panic("can't call super with nil object pointer") } if obj.Class().Super() == 0 { panic("can't call super with nil superclass pointer") } var super superStruct super.receiver = obj super.class = obj.Class().Super() var result C.id sel := C.sel_registerName(C.CString(method)) if len(args) > 0 { items, types := constructArgs(args...) C.gocoa_ISuper((*C.struct_objc_super)(unsafe.Pointer(&super)), sel, &result, &items[0], (**C.char)(&types[0]), (C.int)(len(items))) } else { result = C.objc_msgSendSuper((*C.struct_objc_super)(unsafe.Pointer(&super)), sel) } // XXX output conversion needed return (Object)(unsafe.Pointer(result)) }
func (cls Class) AddMethod(methodName string, implementor interface{}) bool { v := reflect.ValueOf(implementor) if (v.Kind() == reflect.Func) && (v.Type().NumIn() > 1) { types := "v" impName := trimPackage(runtime.FuncForPC(v.Pointer()).Name()) numArgs := v.Type().NumIn() if v.Type().NumOut() == 1 { types = objcArgTypeString(trimPackage(v.Type().Out(0).String())) } for i := 0; i < numArgs; i++ { argType := trimPackage(v.Type().In(i).String()) types = types + objcArgTypeString(argType) } sel := C.sel_registerName(C.CString(methodName)) imp := loadThySelf(impName) result := C.class_addMethod(cls.cclass(), sel, imp, C.CString(types)) return (result == 1) } return false }
// one possibility is that this always returns an object, always converting structs to // pointers on output, assuming that the runtime can generally use them on input func (obj Object) Call(selector string, args ...Passable) Object { // if obj == 0 { // panic("can't call with nil class pointer") // } var result C.id sel := C.sel_registerName(C.CString(selector)) if len(args) > 0 { items, types := constructArgs(args...) C.gocoa_I(obj.cid(), sel, &result, &items[0], (**C.char)(&types[0]), (C.int)(len(items))) } else { result = C.objc_msgSend(obj.cid(), sel) } // XXX output conversion needed return (Object)(unsafe.Pointer(result)) }
func SelectorForName(name string) Selector { return (Selector)(unsafe.Pointer(C.sel_registerName(C.CString(name)))) }
func (obj Object) Method(name string) Method { sel := C.sel_registerName(C.CString(name)) return (Method)(unsafe.Pointer(C.class_getInstanceMethod(obj.Class().cclass(), sel))) }
func (cls Class) Method(name string) Method { sel := C.sel_registerName(C.CString(name)) return (Method)(unsafe.Pointer(C.class_getClassMethod(cls.cclass(), sel))) }
func (cls Class) RespondsTo(selector string) bool { sel := C.sel_registerName(C.CString(selector)) return (C.class_respondsToSelector(cls.cclass(), sel) == 1) }
func Runtime_sel_registerName(name string) unsafe.Pointer { var n *C.char = C.CString(name) defer C.free(unsafe.Pointer(n)) return unsafe.Pointer(C.sel_registerName(n)) }