1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
3
4package objc_test
5
6import (
7 "fmt"
8 "testing"
9
10 "github.com/ebitengine/purego"
11 "github.com/ebitengine/purego/objc"
12)
13
14func ExampleAllocateClassPair() {
15 var class = objc.AllocateClassPair(objc.GetClass("NSObject"), "FooObject", 0)
16 class.AddMethod(objc.RegisterName("run"), objc.NewIMP(func(self objc.ID, _cmd objc.SEL) {
17 fmt.Println("Hello World!")
18 }), "v@:")
19 class.Register()
20
21 var fooObject = objc.ID(class).Send(objc.RegisterName("new"))
22 fooObject.Send(objc.RegisterName("run"))
23 // Output: Hello World!
24}
25
26func ExampleClass_AddIvar() {
27 type barObject struct {
28 isa objc.Class
29 bar int
30 }
31 var class = objc.AllocateClassPair(objc.GetClass("NSObject"), "BarObject", 0)
32 class.AddIvar("bar", int(0), "q")
33 class.AddMethod(objc.RegisterName("bar"), objc.NewIMP(func(self *barObject, _cmd objc.SEL) int {
34 return self.bar
35 }), "q@:")
36 class.AddMethod(objc.RegisterName("setBar:"), objc.NewIMP(func(self *barObject, _cmd objc.SEL, bar int) {
37 self.bar = bar
38 }), "v@:q")
39 class.Register()
40
41 var object = objc.ID(class).Send(objc.RegisterName("new"))
42 object.Send(objc.RegisterName("setBar:"), 123)
43 var bar = int(object.Send(objc.RegisterName("bar")))
44 fmt.Println(bar)
45 // Output: 123
46}
47
48func ExampleIMP() {
49 imp := objc.NewIMP(func(self objc.ID, _cmd objc.SEL, a3, a4, a5, a6, a7, a8, a9 int) {
50 fmt.Println("IMP:", self, _cmd, a3, a4, a5, a6, a7, a8, a9)
51 })
52
53 purego.SyscallN(uintptr(imp), 105, 567, 9, 2, 3, ^uintptr(4), 4, 8, 9)
54
55 // Output: IMP: 105 567 9 2 3 -5 4 8 9
56}
57
58func ExampleID_SendSuper() {
59 super := objc.AllocateClassPair(objc.GetClass("NSObject"), "SuperObject", 0)
60 super.AddMethod(objc.RegisterName("doSomething"), objc.NewIMP(func(self objc.ID, _cmd objc.SEL) {
61 fmt.Println("In Super!")
62 }), "v@:")
63 super.Register()
64
65 child := objc.AllocateClassPair(super, "ChildObject", 0)
66 child.AddMethod(objc.RegisterName("doSomething"), objc.NewIMP(func(self objc.ID, _cmd objc.SEL) {
67 fmt.Println("In Child")
68 self.SendSuper(_cmd)
69 }), "v@:")
70 child.Register()
71
72 objc.ID(child).Send(objc.RegisterName("new")).Send(objc.RegisterName("doSomething"))
73
74 // Output: In Child
75 // In Super!
76}
77
78func TestSend(t *testing.T) {
79 // NSNumber comes from Foundation so make sure we have linked to that framework.
80 _, err := purego.Dlopen("Foundation.framework/Foundation", purego.RTLD_GLOBAL)
81 if err != nil {
82 t.Fatal(err)
83 }
84 const double = float64(2.34)
85 // Initialize a NSNumber
86 NSNumber := objc.ID(objc.GetClass("NSNumber")).Send(objc.RegisterName("numberWithDouble:"), double)
87 // Then get that number back using the generic Send function.
88 var number = objc.Send[float64](NSNumber, objc.RegisterName("doubleValue"))
89 if double != number {
90 t.Failed()
91 }
92}