source: project/release/3/objc/trunk/objc.scm @ 9966

Last change on this file since 9966 was 9966, checked in by Kon Lovett, 13 years ago

Using canonical directory structure.

File size: 4.0 KB
1;;; Chicken ObjC bridge -- basic proxies
3(require-extension objc-base)
5;;; Class definition macro
7;; objc:ivar-ref and objc:ivar-set! use the instance variable type qualifiers
8;; to manage memory correctly and transparently provide access to scheme objects.
10;; The type qualifiers:
11;;    #:slot    An ID containing a GC root pointer to a scheme object.
12;;               Scheme objects are transparently read from and assigned to these.
13;;    #:wrapper An ID containing a Scheme_Object_Wrapper (which contains a GC root).
14;;               Same as #:slot, with higher overhead.  Uses objc:wrap and unwrap.
15;;    #:outlet  An ID whose reference count is not managed.
16;;               Use these for Interface Builder outlets.
17;;    ID        An ID whose reference count is automatically managed.
18;;               Use these for normal Objective C instances.
19;;    DBL, &c.  A regular Objective C instance variable.
21;; NB!! In the interpreter, if you assign a closure to a slot: or
22;; wrapper: var, it will capture self.  There is then a deadlock: self
23;; cannot be released until the closure is released; the closure
24;; cannot be released until the GC root is deleted, the GC root can't
25;; be deleted until objc-self's dealloc is called; objc-self's dealloc
26;; can't be called until its retain count is 0; and retain count
27;; remains at 1 until self is released.
28;;      The compiler however is smart enough to know when the closure
29;; does not depend on self.  Finalization works fine in that case.
31;; The superclass will be looked up for you; it does not need to be imported.
32(define-macro (define-objc-class class super ivars . methods)
33  (let ((instance-variables (gensym)))
34  `(begin
35     ;; register class
36     (if (string-to-class ,(symbol->string class))
37         ((if (objc:allow-class-redefinition)
38              warning error)
39          ,(string-append "(define-objc-class): class already registered: "
40                          (symbol->string class)))
41         (objc:register-class ,(symbol->string class)
42                              (objc:string->class ,(symbol->string super))))
43     ;; import class
44     (define-objc-classes ,class)
45     (objc:class-objc?-set! ,class #f)   ;; This class is not pure ObjC.
47     ;; set instance variables
48     (let ((,instance-variables
49            (list ,@(map (lambda (ivar)
50                           (let ((qualified-ID? (memq (car ivar)
51                                                      '(slot: wrapper: outlet:))))
52                             (let ((name        (cadr ivar))
53                                   (type        (if qualified-ID? 'ID (car ivar)))
54                                   (function    (if qualified-ID? (car ivar) ivar:)))
55                               `(make-objc:ivar ,(symbol->string name)
56                                                ,(macro:type->encoding type)
57                                                0
58                                                ,function))))
59                         ivars))))
60       ;; Set instance vars on the Objective C side...
61       (objc:set-ivars! ,class (map objc:ivar->raw ,instance-variables))
62       ;; ... and in the Scheme class proxy.
63       (objc:class-ivars-set! ,class
64             (map (lambda (x)
65                    (cons (objc:ivar-name x) x))
66                  ,instance-variables))
68     ;; add user methods
69     ,@(map (lambda (method)
70              (let ((definer (case (car method)
71                               ((define-method -) 'objc:define-method)
72                               ((define-class-method +) 'objc:define-class-method)
73                               (else (error "invalid method definition keyword" (car method))))))
74                `(,definer ,class ,@(cdr method))))
75            methods)
77     ;; Add convenience methods.  The dealloc-scheme comments explain why it gets
78     ;; added to every class, not just the first Scheme generation.
79     (objc:add-convenience-method! ,class
80                                   "dealloc"
81                                   "v@:"
82                                   objc_method_dealloc)))))
Note: See TracBrowser for help on using the repository browser.