diff --git a/objc/objc_runtime_darwin.go b/objc/objc_runtime_darwin.go index 73e1e881..a35fe5b3 100644 --- a/objc/objc_runtime_darwin.go +++ b/objc/objc_runtime_darwin.go @@ -554,7 +554,7 @@ type IMP uintptr func NewIMP(fn interface{}) IMP { ty := reflect.TypeOf(fn) if ty.Kind() != reflect.Func { - panic("objc: not a function") + panic(fmt.Sprintf("objc: not a function")) } // IMP is stricter than a normal callback // id (*IMP)(id, SEL, ...) diff --git a/objc/objc_runtime_darwin_test.go b/objc/objc_runtime_darwin_test.go index 08e51198..9aa35d2d 100644 --- a/objc/objc_runtime_darwin_test.go +++ b/objc/objc_runtime_darwin_test.go @@ -12,6 +12,30 @@ import ( "github.com/ebitengine/purego/objc" ) +func ExampleRegisterClass_helloworld() { + class, err := objc.RegisterClass( + "FooObject", + objc.GetClass("NSObject"), + nil, + nil, + []objc.MethodDef{ + { + Cmd: objc.RegisterName("run"), + Fn: func(self objc.ID, _cmd objc.SEL) { + fmt.Println("Hello World!") + }, + }, + }, + ) + if err != nil { + panic(err) + } + + object := objc.ID(class).Send(objc.RegisterName("new")) + object.Send(objc.RegisterName("run")) + // Output: Hello World! +} + func ExampleRegisterClass() { var ( sel_new = objc.RegisterName("new") @@ -66,10 +90,52 @@ func ExampleIMP() { }) purego.SyscallN(uintptr(imp), 105, 567, 9, 2, 3, ^uintptr(4), 4, 8, 9) - // Output: IMP: 105 567 9 2 3 -5 4 8 9 } +func ExampleID_SendSuper() { + super, err := objc.RegisterClass( + "SuperObject", + objc.GetClass("NSObject"), + nil, + nil, + []objc.MethodDef{ + { + Cmd: objc.RegisterName("doSomething"), + Fn: func(self objc.ID, _cmd objc.SEL) { + fmt.Println("In Super!") + }, + }, + }, + ) + if err != nil { + panic(err) + } + + child, err := objc.RegisterClass( + "ChildObject", + super, + nil, + nil, + []objc.MethodDef{ + { + Cmd: objc.RegisterName("doSomething"), + Fn: func(self objc.ID, _cmd objc.SEL) { + fmt.Println("In Child") + self.SendSuper(_cmd) + }, + }, + }, + ) + if err != nil { + panic(err) + } + + objc.ID(child).Send(objc.RegisterName("new")).Send(objc.RegisterName("doSomething")) + // Output: In Child + // In Super! +} + func TestSend(t *testing.T) { // NSNumber comes from Foundation so make sure we have linked to that framework. _, err := purego.Dlopen("/System/Library/Frameworks/Foundation.framework/Foundation", purego.RTLD_GLOBAL) @@ -97,8 +163,48 @@ func ExampleSend() { subString := objc.ID(class_NSString).Send(sel_stringWithUTF8String, "lo, Wor\x00") r := objc.Send[NSRange](fullString, objc.RegisterName("rangeOfString:"), subString) - fmt.Println(r) - // Output: {3 7} } + +func ExampleSendSuper() { + super, err := objc.RegisterClass( + "SuperObject2", + objc.GetClass("NSObject"), + nil, + nil, + []objc.MethodDef{ + { + Cmd: objc.RegisterName("doSomething"), + Fn: func(self objc.ID, _cmd objc.SEL) int { + return 16 + }, + }, + }, + ) + if err != nil { + panic(err) + } + + child, err := objc.RegisterClass( + "ChildObject2", + super, + nil, + nil, + []objc.MethodDef{ + { + Cmd: objc.RegisterName("doSomething"), + Fn: func(self objc.ID, _cmd objc.SEL) int { + return 24 + }, + }, + }, + ) + if err != nil { + panic(err) + } + + res := objc.SendSuper[int](objc.ID(child).Send(objc.RegisterName("new")), objc.RegisterName("doSomething")) + fmt.Println(res) + // Output: 16 +}