Browse code
Cleanup reader macros / objc-bridge
Ed L authored on 08/01/2018 22:00:42
Showing 4 changed files
Showing 4 changed files
... | ... |
@@ -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))) |