source: project/release/4/objc/trunk/objc.scm @ 14899

Last change on this file since 14899 was 14899, checked in by Alex Shinn, 12 years ago

initial conversion, not yet working

File size: 5.5 KB
Line 
1;;; Chicken ObjC bridge -- basic proxies
2
3(require-library srfi-69 foreigners)
4
5(module objc
6
7    (*class-proxies*
8     dealloc-scheme
9     lookup-class-proxy
10     make-class-proxy
11     make-objc:class
12     make-objc:ivar
13     objc:add-convenience-method!
14     objc:class-all-ivars
15     objc:class-ivar-lookup
16     objc:class-ivars
17     objc:class-ivars-set!
18     objc:class-objc?
19     objc:class-objc?-set!
20     objc:class-ptr
21     objc:class-ptr-set!
22     objc:class?
23     objc:ivar->raw
24     objc:ivar-function
25     objc:ivar-function-set!
26     objc:ivar-name
27     objc:ivar-name-set!
28     objc:ivar-offset
29     objc:ivar-offset-set!
30     objc:ivar-ref
31     objc:ivar-set!
32     objc:ivar-type
33     objc:ivar-type-set!
34     objc:ivar?
35     objc:pointer->class
36     objc:scheme-object->ref/cnt
37     register-class-proxy
38     dealloc_scheme
39     gc-root-delete!
40     gc-root-ref
41     gc-root-set!
42     objc:unwrap
43     objc:wrap
44     objc_method_dealloc
45     scheme-object-wrapper-delete!
46     scheme-object-wrapper-ref
47     scheme-object-wrapper-set!)
48
49(import scheme chicken srfi-69 foreigners)
50(require-extension objc-base)
51(include "objc-class-proxies.scm")
52(include "objc-class-proxies-bin.scm")
53
54;;; Class definition macro
55
56;; objc:ivar-ref and objc:ivar-set! use the instance variable type qualifiers
57;; to manage memory correctly and transparently provide access to scheme objects.
58
59;; The type qualifiers:
60;;    #:slot    An ID containing a GC root pointer to a scheme object.
61;;               Scheme objects are transparently read from and assigned to these.
62;;    #:wrapper An ID containing a Scheme_Object_Wrapper (which contains a GC root).
63;;               Same as #:slot, with higher overhead.  Uses objc:wrap and unwrap.
64;;    #:outlet  An ID whose reference count is not managed.
65;;               Use these for Interface Builder outlets.
66;;    ID        An ID whose reference count is automatically managed.
67;;               Use these for normal Objective C instances.
68;;    DBL, &c.  A regular Objective C instance variable.
69
70;; NB!! In the interpreter, if you assign a closure to a slot: or
71;; wrapper: var, it will capture self.  There is then a deadlock: self
72;; cannot be released until the closure is released; the closure
73;; cannot be released until the GC root is deleted, the GC root can't
74;; be deleted until objc-self's dealloc is called; objc-self's dealloc
75;; can't be called until its retain count is 0; and retain count
76;; remains at 1 until self is released.
77;;      The compiler however is smart enough to know when the closure
78;; does not depend on self.  Finalization works fine in that case.
79
80;; The superclass will be looked up for you; it does not need to be imported.
81(define-syntax define-objc-class
82  (er-macro-transformer
83   (lambda (e r c)
84     (let ((class (cadr e))
85           (super (caddr e))
86           (ivars (cadddr e))
87           (methods (cddddr e))
88           (instance-variables (gensym)))
89       `(begin
90          ;; register class
91          (if (string-to-class ,(symbol->string class))
92              ((if (objc:allow-class-redefinition)
93                   warning error)
94               ,(string-append "(define-objc-class): class already registered: "
95                               (symbol->string class)))
96              (objc:register-class ,(symbol->string class)
97                                   (objc:string->class ,(symbol->string super))))
98          ;; import class
99          (define-objc-classes ,class)
100          (objc:class-objc?-set! ,class #f) ;; This class is not pure ObjC.
101
102          ;; set instance variables
103          (let ((,instance-variables
104                 (list ,@(map (lambda (ivar)
105                                (let ((qualified-ID? (memq (car ivar)
106                                                           '(slot: wrapper: outlet:))))
107                                  (let ((name        (cadr ivar))
108                                        (type        (if qualified-ID? 'ID (car ivar)))
109                                        (function    (if qualified-ID? (car ivar) ivar:)))
110                                    `(make-objc:ivar ,(symbol->string name)
111                                                     ,(macro:type->encoding type)
112                                                     0
113                                                     ,function))))
114                              ivars))))
115            ;; Set instance vars on the Objective C side...
116            (objc:set-ivars! ,class (map objc:ivar->raw ,instance-variables))
117            ;; ... and in the Scheme class proxy.
118            (objc:class-ivars-set! ,class
119                                   (map (lambda (x)
120                                          (cons (objc:ivar-name x) x))
121                                        ,instance-variables))
122
123            ;; add user methods
124            ,@(map (lambda (method)
125                     (let ((definer (case (car method)
126                                      ((define-method -) 'objc:define-method)
127                                      ((define-class-method +) 'objc:define-class-method)
128                                      (else (error "invalid method definition keyword" (car method))))))
129                       `(,definer ,class ,@(cdr method))))
130                   methods)
131
132            ;; Add convenience methods.  The dealloc-scheme comments explain why it gets
133            ;; added to every class, not just the first Scheme generation.
134            (objc:add-convenience-method! ,class
135                                          "dealloc"
136                                          "v@:"
137                                          objc_method_dealloc)))))))
138
139)
Note: See TracBrowser for help on using the repository browser.