Browse code
WIP
Ed Langley authored on 13/08/2018 08:43:03
Showing 6 changed files
Showing 6 changed files
... | ... |
@@ -11,6 +11,8 @@ demo-app: dylib |
11 | 11 |
--eval '(ql:quickload :objc-runtime)' \ |
12 | 12 |
--eval '(load (compile-file "demo-app.lisp"))' \ |
13 | 13 |
--eval '(ccl:save-application "demo-app" :toplevel-function '"'"'demo-app::main :prepend-kernel t)' |
14 |
+ #--eval '(sb-ext:save-lisp-and-die "demo-app" :toplevel '"'"'demo-app::main :executable t)' |
|
15 |
+ |
|
14 | 16 |
demo-app.iconset: demo-app.svg |
15 | 17 |
rm -rf demo-app.iconset |
16 | 18 |
mkdir -p demo-app.iconset |
... | ... |
@@ -117,26 +117,28 @@ |
117 | 117 |
(declare (ignore a b sender)) |
118 | 118 |
(show-alert "That Was Profitable!")) |
119 | 119 |
|
120 |
+(defun alloc-init (cls) |
|
121 |
+ [[cls @(alloc)] @(init)]) |
|
122 |
+ |
|
120 | 123 |
(defun make-button-delegate (button cb) |
121 | 124 |
(let ((my-class (objc-runtime::objc-allocate-class-pair #@NSObject "ButtonDel" 0))) |
122 |
- (with-selectors ((do-magic "doMagic:") (set-target "setTarget:") (set-action "setAction:") |
|
123 |
- alloc init) |
|
124 |
- (objc-runtime::class-add-method my-class do-magic cb "v@:@") |
|
125 |
- (fw.lu:prog1-bind (result [[my-class alloc] init]) |
|
126 |
- [button set-target :pointer result] |
|
127 |
- [button set-action :pointer do-magic])))) |
|
125 |
+ (objc-runtime::class-add-method my-class @(doMagic) cb "v@:@") |
|
126 |
+ (fw.lu:prog1-bind (result (alloc-init my-class)) |
|
127 |
+ [button @(setTarget) :pointer result] |
|
128 |
+ [button @(setAction) :pointer @(doMagic)]))) |
|
128 | 129 |
|
129 | 130 |
(defun make-app-delegate-class (outlets) |
130 | 131 |
(let ((app-delegate-class (objc-runtime::objc-allocate-class-pair |
131 | 132 |
#@NSObject "AppDelegate" 0))) |
132 |
- (objc-runtime::add-pointer-ivar app-delegate-class "window") |
|
133 |
- (objc-runtime::add-pointer-ivar app-delegate-class "delegate") |
|
133 |
+ (objc-runtime:add-pointer-ivar app-delegate-class "window") |
|
134 |
+ (objc-runtime:add-pointer-ivar app-delegate-class "delegate") |
|
134 | 135 |
|
135 | 136 |
(loop for outlet in outlets do |
136 |
- (objc-runtime::add-pointer-ivar app-delegate-class outlet)) |
|
137 |
+ (objc-runtime:add-pointer-ivar app-delegate-class outlet)) |
|
137 | 138 |
|
138 | 139 |
app-delegate-class)) |
139 | 140 |
|
141 |
+ |
|
140 | 142 |
(defun load-nib (name) |
141 | 143 |
;; find and activate the nib |
142 | 144 |
(let* ((bundle [#@NSBundle @(mainBundle)]) |
... | ... |
@@ -150,6 +152,7 @@ |
150 | 152 |
:pointer objc-runtime::ns-app |
151 | 153 |
:pointer p]))) |
152 | 154 |
|
155 |
+;#+null |
|
153 | 156 |
(defun main () |
154 | 157 |
#+sbcl |
155 | 158 |
(sb-int:set-floating-point-modes :traps '()) |
... | ... |
@@ -178,3 +181,72 @@ |
178 | 181 |
|
179 | 182 |
[objc-runtime::ns-app @(activateIgnoringOtherApps:) :boolean t] |
180 | 183 |
[objc-runtime::ns-app @(run)])) |
184 |
+ |
|
185 |
+(defclass application-shim () |
|
186 |
+ ((%main-view :initarg :main-view :accessor main-view))) |
|
187 |
+ |
|
188 |
+(defparameter *application-shim* (make-instance 'application-shim)) |
|
189 |
+ |
|
190 |
+#+nil |
|
191 |
+(defun old-code () |
|
192 |
+ (trivial-main-thread:with-body-in-main-thread (:blocking t) |
|
193 |
+ (sb-int:with-float-traps-masked |
|
194 |
+ (:underflow :overflow :inexact |
|
195 |
+ :invalid :divide-by-zero) |
|
196 |
+ (with-selectors ((shared-application "sharedApplication") |
|
197 |
+ (process-info "processInfo") |
|
198 |
+ (process-name "processName") |
|
199 |
+ (set-activation-policy "setActivationPolicy:") |
|
200 |
+ ;; (init-with-content-rect "initWithContentRect:styleMask:backing:defer:") |
|
201 |
+ (set-title "setTitle:") |
|
202 |
+ (run "run") |
|
203 |
+ (activate-ignoring-other-apps "activateIgnoringOtherApps:") |
|
204 |
+ (make-key-and-order-front "makeKeyAndOrderFront:") |
|
205 |
+ (cascade-top-left-from-point "cascadeTopLeftFromPoint:") |
|
206 |
+ (add-item "addItem:") |
|
207 |
+ (set-main-menu "setMainMenu:") |
|
208 |
+ (init-with-title "initWithTitle:action:keyEquivalent:") |
|
209 |
+ (set-submenu "setSubmenu:") |
|
210 |
+ (init-with-encoding "initWithCString:length:") |
|
211 |
+ (content-view "contentView") |
|
212 |
+ (add-subview "addSubview:") |
|
213 |
+ (set-target "setTarget:") |
|
214 |
+ (set-action "setAction:") |
|
215 |
+ terminate? |
|
216 |
+ ;; (application-should-terminate "applicationShouldTerminate:") |
|
217 |
+ ;; (set-delegate "setDelegate:") |
|
218 |
+ ;; (finish-launching "finishLaunching") |
|
219 |
+ alloc new autorelease |
|
220 |
+ ) |
|
221 |
+ [#@NSAutoReleasePool new] |
|
222 |
+ [#@NSApplication shared-application] |
|
223 |
+ [objc-runtime::ns-app set-activation-policy :int 0] |
|
224 |
+ |
|
225 |
+ |
|
226 |
+ |
|
227 |
+ ;; (break) |
|
228 |
+ (let* ((application-name [[#@NSProcessInfo process-info] process-name])) |
|
229 |
+ (let* ((menubar [[#@NSMenu new] autorelease]) |
|
230 |
+ (app-menu-item [[#@NSMenuItem new] autorelease]) |
|
231 |
+ (app-menu [[#@NSMenu new] autorelease]) |
|
232 |
+ (quit-name [[#@NSString alloc] init-with-encoding :string "Quit" :uint 4]) |
|
233 |
+ (key [[#@NSString alloc] init-with-encoding :string "q" :uint 1]) |
|
234 |
+ (quit-menu-item |
|
235 |
+ [[[#@NSMenuItem alloc] init-with-title :pointer quit-name :pointer terminate? :string key] autorelease])) |
|
236 |
+ [menubar add-item :pointer app-menu-item] |
|
237 |
+ [app-menu add-item :pointer quit-menu-item] |
|
238 |
+ [app-menu-item set-submenu :pointer app-menu] |
|
239 |
+ [objc-runtime::ns-app set-main-menu :pointer menubar] ) |
|
240 |
+ |
|
241 |
+ (setf (main-view *application-shim*) |
|
242 |
+ [#@NSStackView @(stackViewWithViews:) :pointer [[#@NSArray @(alloc)] @(init)]]) |
|
243 |
+ (with-point (p (20 20)) |
|
244 |
+ (let* ((foreign-rect (make-rect 10 10 120 120)) |
|
245 |
+ (the-window (init-window [#@NSWindow alloc] foreign-rect 1 2 nil))) |
|
246 |
+ |
|
247 |
+ [(value-for-key the-window "contentView") add-subview :pointer (main-view *application-shim*)] |
|
248 |
+ [the-window cascade-top-left-from-point :pointer p] |
|
249 |
+ [the-window set-title :pointer application-name] |
|
250 |
+ [the-window make-key-and-order-front :pointer (cffi:null-pointer)] |
|
251 |
+ [ objc-runtime::ns-app activate-ignoring-other-apps :boolean t] |
|
252 |
+ [ objc-runtime::ns-app run]))))))) |
181 | 253 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,32 @@ |
1 |
+(defpackage :mop-test |
|
2 |
+ (:shadowing-import-from :closer-mop |
|
3 |
+ :standard-method :standard-generic-function |
|
4 |
+ :defmethod :defgeneric :standard-class) |
|
5 |
+ (:use :cl :closer-mop) |
|
6 |
+ (:export )) |
|
7 |
+(in-package :mop-test) |
|
8 |
+ |
|
9 |
+(defclass slot-logging-class (standard-class) |
|
10 |
+ ((%log-stream :accessor log-stream :initform (make-synonym-stream '*trace-output*)))) |
|
11 |
+ |
|
12 |
+(defmethod validate-superclass ((class slot-logging-class) (super standard-class)) |
|
13 |
+ t) |
|
14 |
+ |
|
15 |
+(defmethod slot-value-using-class ((class slot-logging-class) instance slotd) |
|
16 |
+ (format (log-stream class) "~&Instance ~s of class ~s read slot ~s~%" |
|
17 |
+ (class-name class) |
|
18 |
+ instance |
|
19 |
+ (slot-definition-name slotd)) |
|
20 |
+ (call-next-method)) |
|
21 |
+ |
|
22 |
+(defmethod (setf slot-value-using-class) (new-value (class slot-logging-class) instance slotd) |
|
23 |
+ (format (log-stream class) "~&Instance ~s of class ~s write slot ~s: ~s~%" |
|
24 |
+ (class-name class) |
|
25 |
+ instance |
|
26 |
+ (slot-definition-name slotd) |
|
27 |
+ new-value) |
|
28 |
+ (call-next-method)) |
|
29 |
+ |
|
30 |
+(defclass tmp (standard-object) |
|
31 |
+ ((%a :reader a :initform :b)) |
|
32 |
+ (:metaclass slot-logging-class)) |
... | ... |
@@ -81,12 +81,27 @@ |
81 | 81 |
o-selector |
82 | 82 |
(name :string)) |
83 | 83 |
|
84 |
+(defcfun (objc-msg-send-int "objc_msgSend") |
|
85 |
+ :int |
|
86 |
+ (cls o-class) |
|
87 |
+ (sel o-selector) |
|
88 |
+ &rest) |
|
89 |
+ |
|
90 |
+(defcfun (objc-msg-send-string "objc_msgSend") |
|
91 |
+ :string |
|
92 |
+ (cls o-class) |
|
93 |
+ (sel o-selector) |
|
94 |
+ &rest) |
|
95 |
+ |
|
84 | 96 |
(defcfun (objc-msg-send "objc_msgSend") |
85 | 97 |
:pointer |
86 | 98 |
(cls o-class) |
87 | 99 |
(sel o-selector) |
88 | 100 |
&rest) |
89 | 101 |
|
102 |
+(defun objc-msg-send-nsstring (thing selector &rest args) |
|
103 |
+ [(apply 'objc-msg-send thing selector args) @(UTF8String)]s) |
|
104 |
+ |
|
90 | 105 |
(defcfun (class-copy-method-list "class_copyMethodList" :library foundation) |
91 | 106 |
:pointer |
92 | 107 |
(cls o-class) |
... | ... |
@@ -143,6 +158,15 @@ |
143 | 158 |
:string |
144 | 159 |
(prop :pointer)) |
145 | 160 |
|
161 |
+(defun get-classes () |
|
162 |
+ (let ((num-classes (objc-get-class-list (null-pointer) 0))) |
|
163 |
+ (with-foreign-object (classes :pointer num-classes) |
|
164 |
+ (objc-get-class-list classes num-classes) |
|
165 |
+ (let ((result (list))) |
|
166 |
+ (dotimes (n num-classes (nreverse result)) |
|
167 |
+ (push (mem-aref classes :pointer n) |
|
168 |
+ result)))))) |
|
169 |
+ |
|
146 | 170 |
(defgeneric get-methods (class) |
147 | 171 |
(:method ((class string)) |
148 | 172 |
(get-methods (objc-look-up-class class))) |
... | ... |
@@ -334,3 +358,4 @@ |
334 | 358 |
`(let (,@(mapcar #'second expanded-defs)) |
335 | 359 |
(flet (,@(mapcar #'first expanded-defs)) |
336 | 360 |
,@body)))) |
361 |
+ |
... | ... |
@@ -26,10 +26,16 @@ |
26 | 26 |
(:syntax-from :standard #\) #\]) |
27 | 27 |
(:macro-char #\[ (lambda (s char) |
28 | 28 |
char |
29 |
- (let ((info (read-delimited-list #\] s t))) |
|
29 |
+ (let ((info (read-delimited-list #\] s t)) |
|
30 |
+ (msg-send (case (peek-char nil s nil #\p t) |
|
31 |
+ (#\# (read-char s t nil t) 'objc-msg-send-int) |
|
32 |
+ (#\s (read-char s t nil t) 'objc-msg-send-string) |
|
33 |
+ (#\@ (read-char s t nil t) 'objc-msg-send-nsstring) |
|
34 |
+ (#\& (read-char s t nil t) 'objc-msg-send) |
|
35 |
+ (t 'objc-msg-send)))) |
|
30 | 36 |
(when info |
31 | 37 |
(destructuring-bind (obj message . args) info |
32 |
- `(objc-msg-send ,obj ,message ,@args))))) |
|
38 |
+ `(,msg-send ,obj ,message ,@args))))) |
|
33 | 39 |
nil) |
34 | 40 |
(:dispatch-macro-char #\# #\@ |
35 | 41 |
(lambda (s c b) |