git.fiddlerwoaroof.com
Browse code

Cleanup reader macros / objc-bridge

Ed L authored on 08/01/2018 22:00:42
Showing 4 changed files
... ...
@@ -19,3 +19,7 @@ GTAGS
19 19
 nsrect-expose.c
20 20
 test.c
21 21
 .[#]*
22
+demo-app
23
+demo.app
24
+*.framework
25
+.DS_Store
... ...
@@ -33,7 +33,7 @@
33 33
 
34 34
 (defun value-for-key (thing key)
35 35
   (with-selectors ((vfk "valueForKey:"))
36
-    (let ((key (make-nsstring key)))
36
+    (let ((key (objc-runtime::make-nsstring key)))
37 37
       [thing vfk :string key])))
38 38
 
39 39
 (defun call-with-rect (x y w h cb)
... ...
@@ -89,22 +89,13 @@
89 89
                               ,(coerce h 'double-float)))
90 90
                            '(:struct objc-runtime:ns-rect)))
91 91
 
92
-(defun make-nsstring (str)
93
-  (with-selectors (alloc (init-with-encoding "initWithCString:length:"))
94
-    [[#@NSString alloc] init-with-encoding :string str :uint (length str)]))
95
-
96 92
 (defun show-alert (message)
97
-  (with-selectors ((set-message-text "setMessageText:")
98
-                   (set-informative-text "setInformativeText:")
99
-                   (add-button-with-title "addButtonWithTitle:")
100
-                   (run-modal "runModal")
101
-                   alloc init)
102
-    (let ((alert [[#@NSAlert alloc] init]))
103
-      [alert set-message-text :pointer (make-nsstring message)]
104
-      [alert set-informative-text :pointer (make-nsstring "Informative text.")]
105
-      [alert add-button-with-title :pointer (make-nsstring "Cancel")]
106
-      [alert add-button-with-title :pointer (make-nsstring "OK")]
107
-      [alert run-modal])))
93
+  (let ((alert [[#@NSAlert @(alloc)] @(init)]))
94
+    [alert @(setMessageText:) :pointer @"message"]
95
+    [alert @(setInformativeText:) :pointer @"Informative text."]
96
+    [alert @(addButtonWithTitle:) :pointer @"OK"]
97
+    [alert @(addButtonWithTitle:) :pointer @"Cancel"]
98
+    [alert @(runModal)]))
108 99
 
109 100
 (cffi:defcallback button-action :void ((a :pointer) (b :pointer) (sender :pointer))
110 101
   (declare (ignore a b sender))
... ...
@@ -120,69 +111,70 @@
120 111
         [button set-target :pointer result]
121 112
         [button set-action :pointer do-magic]))))
122 113
 
114
+(defparameter *main-task* nil)
123 115
 (defun main ()
124 116
   ;; (break)
125
-  (trivial-main-thread:with-body-in-main-thread (:blocking t)
126
-    (with-selectors ((shared-application "sharedApplication")
127
-                     (process-info "processInfo")
128
-                     (process-name "processName")
129
-                     (set-activation-policy "setActivationPolicy:")
130
-                     ;; (init-with-content-rect "initWithContentRect:styleMask:backing:defer:")
131
-                     (set-title "setTitle:")
132
-                     (run "run")
133
-                     (activate-ignoring-other-apps "activateIgnoringOtherApps:")
134
-                     (make-key-and-order-front "makeKeyAndOrderFront:")
135
-                     (cascade-top-left-from-point "cascadeTopLeftFromPoint:")
136
-                     (add-item "addItem:")
137
-                     (set-main-menu "setMainMenu:")
138
-                     (init-with-title "initWithTitle:action:keyEquivalent:")
139
-                     (set-submenu "setSubmenu:")
140
-                     (init-with-encoding "initWithCString:length:")
141
-                     (content-view "contentView")
142
-                     (add-subview "addSubview:")
143
-                     (set-target "setTarget:")
144
-                     (set-action "setAction:")
145
-                     (set-title "setTitle:")
146
-                     terminate?
147
-                     ;; (application-should-terminate "applicationShouldTerminate:")
148
-                     ;; (set-delegate "setDelegate:")
149
-                     ;; (finish-launching "finishLaunching")
150
-                     alloc new autorelease
151
-                     )
152
-      [#@NSAutoReleasePool new]
153
-      [#@NSApplication shared-application]
154
-      [objc-runtime::ns-app set-activation-policy :int 0]
155
-
156
-      ;; (break)
157
-      (let* ((application-name [[#@NSProcessInfo process-info] process-name]))
158
-        (let* ((menubar [[#@NSMenu new] autorelease])
159
-               (app-menu-item [[#@NSMenuItem new] autorelease])
160
-               (app-menu [[#@NSMenu new] autorelease])
161
-               (quit-name [[#@NSString alloc] init-with-encoding :string "Quit" :uint 4])
162
-               (key [[#@NSString alloc] init-with-encoding :string "q" :uint 1])
163
-               (quit-menu-item
164
-                [[[#@NSMenuItem alloc] init-with-title :pointer quit-name :pointer terminate? :string key] autorelease]))
165
-          [menubar add-item :pointer app-menu-item]
166
-          [app-menu add-item :pointer quit-menu-item]
167
-          [app-menu-item set-submenu :pointer app-menu]
168
-          [objc-runtime::ns-app set-main-menu :pointer menubar] )
169
-
170
-        (with-point (p (20 20))
171
-          (let* ((foreign-rect (make-rect 10 10 120 120))
172
-                 (the-window (init-window [#@NSWindow alloc] foreign-rect 1 2 nil))
173
-                 (the-button (init-with-frame [#@NSButton alloc] (make-rect 10 10 100 100))))
174
-            (format t "~{~&~a~%~}"
175
-                    (sort (objc-runtime::get-method-names (objc-runtime::object-get-class [the-window content-view]))
176
-                          #'string-lessp))
177
-            (format t "~&My rect: ~s~%"
178
-                    (cffi:convert-from-foreign foreign-rect
179
-                                               '(:struct objc-runtime::ns-rect)))
180
-            
181
-            [the-button set-title :pointer (make-nsstring "Click me!")]
182
-            (make-button-delegate the-button)
183
-            [(value-for-key the-window "contentView") add-subview :pointer the-button]
184
-            [the-window cascade-top-left-from-point :pointer p]
185
-            [the-window set-title :pointer application-name]
186
-            [the-window make-key-and-order-front :pointer (cffi:null-pointer)]
187
-            [ objc-runtime::ns-app activate-ignoring-other-apps :boolean t]
188
-            [ objc-runtime::ns-app run]))))))
117
+  (setf *main-task*
118
+        (trivial-main-thread:with-body-in-main-thread (:blocking t)
119
+          (with-selectors ((shared-application "sharedApplication")
120
+                           (process-info "processInfo")
121
+                           (process-name "processName")
122
+                           (set-activation-policy "setActivationPolicy:")
123
+                           ;; (init-with-content-rect "initWithContentRect:styleMask:backing:defer:")
124
+                           (set-title "setTitle:")
125
+                           (run "run")
126
+                           (activate-ignoring-other-apps "activateIgnoringOtherApps:")
127
+                           (make-key-and-order-front "makeKeyAndOrderFront:")
128
+                           (cascade-top-left-from-point "cascadeTopLeftFromPoint:")
129
+                           (add-item "addItem:")
130
+                           (set-main-menu "setMainMenu:")
131
+                           (init-with-title "initWithTitle:action:keyEquivalent:")
132
+                           (set-submenu "setSubmenu:")
133
+                           (init-with-encoding "initWithCString:length:")
134
+                           (content-view "contentView")
135
+                           (add-subview "addSubview:")
136
+                           (set-target "setTarget:")
137
+                           (set-action "setAction:")
138
+                           terminate?
139
+                           ;; (application-should-terminate "applicationShouldTerminate:")
140
+                           ;; (set-delegate "setDelegate:")
141
+                           ;; (finish-launching "finishLaunching")
142
+                           alloc new autorelease
143
+                           )
144
+            [#@NSAutoReleasePool new]
145
+            [#@NSApplication shared-application]
146
+            [objc-runtime::ns-app set-activation-policy :int 0]
147
+
148
+            ;; (break)
149
+            (let* ((application-name [[#@NSProcessInfo process-info] process-name]))
150
+              (let* ((menubar [[#@NSMenu new] autorelease])
151
+                     (app-menu-item [[#@NSMenuItem new] autorelease])
152
+                     (app-menu [[#@NSMenu new] autorelease])
153
+                     (quit-name [[#@NSString alloc] init-with-encoding :string "Quit" :uint 4])
154
+                     (key [[#@NSString alloc] init-with-encoding :string "q" :uint 1])
155
+                     (quit-menu-item
156
+                      [[[#@NSMenuItem alloc] init-with-title :pointer quit-name :pointer terminate? :string key] autorelease]))
157
+                [menubar add-item :pointer app-menu-item]
158
+                [app-menu add-item :pointer quit-menu-item]
159
+                [app-menu-item set-submenu :pointer app-menu]
160
+                [objc-runtime::ns-app set-main-menu :pointer menubar] )
161
+
162
+              (with-point (p (20 20))
163
+                (let* ((foreign-rect (make-rect 10 10 120 120))
164
+                       (the-window (init-window [#@NSWindow alloc] foreign-rect 1 2 nil))
165
+                       (the-button
166
+                        (init-with-frame [#@NSButton alloc] (make-rect 10 10 100 35)))
167
+                       (the-button1
168
+                        (init-with-frame [#@NSButton alloc] (make-rect 10 55 100 35)))
169
+                       )
170
+                  
171
+                  [the-button set-title :pointer @"Click me!"]
172
+                  (make-button-delegate the-button)
173
+                  (make-button-delegate the-button1)
174
+                  [(value-for-key the-window "contentView") add-subview :pointer the-button]
175
+                  [(value-for-key the-window "contentView") add-subview :pointer the-button1]
176
+                  [the-window cascade-top-left-from-point :pointer p]
177
+                  [the-window set-title :pointer application-name]
178
+                  [the-window make-key-and-order-front :pointer (cffi:null-pointer)]
179
+                  [ objc-runtime::ns-app activate-ignoring-other-apps :boolean t]
180
+                  [ objc-runtime::ns-app run])))))))
... ...
@@ -40,13 +40,6 @@
40 40
   (class :pointer)
41 41
   (protocol :pointer))
42 42
 
43
-(defcfun (class-add-method "class_addMethod" :library foundation)
44
-    :boolean
45
-  (class :pointer)
46
-  (selector :pointer)
47
-  (cb :pointer)
48
-  (type :string))
49
-
50 43
 (defcfun (objc-class-get-name "class_getName" :library foundation)
51 44
     :string
52 45
   (cls o-class))
... ...
@@ -88,13 +81,14 @@
88 81
   (cls o-class)
89 82
   (name :string))
90 83
 
91
-(defcfun (class-get-instance-variable "class_addMethod" :library foundation)
92
-    :pointer
93
-  (cls o-class)
94
-  (sel :pointer)
95
-  (imp :pointer)
84
+(defcfun (class-add-method "class_addMethod" :library foundation)
85
+    :boolean
86
+  (class :pointer)
87
+  (selector :pointer)
88
+  (cb :pointer)
96 89
   (type :string))
97 90
 
91
+
98 92
 (defcfun (object-get-class "object_getClass" :library foundation)
99 93
     :pointer
100 94
   (object :pointer))
... ...
@@ -141,6 +135,10 @@
141 135
             (push (mem-aref methods :pointer n)
142 136
                   result)))))))
143 137
 
138
+(defun make-nsstring (str)
139
+  [[#@NSString @(alloc)] @(initWithCString:encoding:) :string str :uint 1])
140
+
141
+
144 142
 (defun get-method-names (thing)
145 143
   (mapcar (alexandria:compose #'sel-get-name
146 144
                               #'method-get-name)
... ...
@@ -148,6 +146,7 @@
148 146
 
149 147
 (defgeneric graph->dot (graph stream)
150 148
   (:method :around (graph stream)
149
+     (declare (ignore graph))
151 150
 	   (format stream "~&digraph {~%~4trankdir=LR;~%")
152 151
 	   (call-next-method)
153 152
 	   (format stream "~&}"))
... ...
@@ -1,5 +1,21 @@
1 1
 (in-package :objc-runtime)
2 2
 
3
+(defun read-until (test symbol-prefix &optional stop-before-chars)
4
+  "Read from a string until"
5
+  (lambda (s c b)
6
+    (declare (ignore c b))
7
+    (let ((class-name (coerce (loop for next-char = (peek-char nil s nil nil t)
8
+                                 while next-char
9
+                                 until (funcall test next-char)
10
+                                 collect (read-char s t nil t)
11
+                                 finally (when (and (not (member next-char
12
+                                                                 stop-before-chars))
13
+                                                    (funcall test next-char))
14
+                                           (read-char s t nil t)))
15
+
16
+                              'string)))
17
+      `(,symbol-prefix ,class-name))))
18
+
3 19
 (named-readtables:defreadtable :objc-readtable
4 20
   (:merge :standard)
5 21
   (:syntax-from :standard #\) #\])
... ...
@@ -13,10 +29,16 @@
13 29
   (:dispatch-macro-char #\# #\@
14 30
                         (lambda (s c b)
15 31
                           c b
16
-                          (let ((class-name (coerce (loop for c = (read-char s nil nil t)
32
+                          (let ((class-name (coerce (loop for c = (peek-char nil s nil nil t)
17 33
                                                        until (or (null c)
18 34
                                                                  (serapeum:whitespacep c)
19
-                                                                 (member c '(#\) #\(  #\[ #\])))
20
-                                                       collect c)
35
+                                                                 (member c
36
+                                                                         '(#\) #\(  #\[ #\])))
37
+                                                       collect (read-char s t nil t))
21 38
                                                     'string)))
22
-                            `(objc-look-up-class ,class-name)))))
39
+                            `(objc-look-up-class ,class-name))))
40
+  (:macro-char #\@ :dispatch t)
41
+  (:dispatch-macro-char #\@ #\( (read-until (serapeum:op (char= _ #\)))
42
+                                            'ensure-selector))
43
+  (:dispatch-macro-char #\@ #\" (read-until (serapeum:op (char= _ #\"))
44
+                                            'make-nsstring)))