Changeset 267


Ignore:
Timestamp:
Jan 12, 2004, 7:20:11 AM (21 years ago)
Author:
beer
Message:

Partial support for MAKE-INSTANCE on ObjC classes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/examples/objc-clos.lisp

    r233 r267  
    1616;;;
    1717;;; TO DO
    18 ;;;  - Need to add getter and setter functions for more foriegn slot types
     18;;;  - Write SHARED-INITIALIZE and FINALIZE-INHERITANCE for ObjC classes
    1919;;;  - OBJC-FOREIGN-ARG-TYPE in BRIDGE.LISP needs to handle BITFIELDs,
    2020;;;    ARRAYs and UNIONs
    21 ;;;  - Need to get enough of the instance initialization and XXX
    22 ;;;    protocols working so that foreign slot objects actually show up
    23 ;;;    where they're supposed to
    24 ;;;  - Implement slot access for OBJC-CLASS lisp slots
     21;;;  - Need to fully handle init keywords and ObjC init messages
     22;;;  - Need to add getter and setter functions for more foriegn slot types
     23;;;  - Canonicalization and retention for ObjC objects
     24;;;  - Provide Lisp structs for NS-POINT, NS-RECT, etc.?
    2525
    2626;;; Package and module stuff
     
    4040;;; All class names and instance variable names are interned in the NS package
    4141;;; Force all symbols interned in the NS package to be external
    42 ;;; symbols.
    4342
    4443(defpackage "NS"
     
    7675(defvar *objc-class-class*)
    7776(defvar *objc-metaclass-class*)
     77
     78(defvar *objc-object-slot-vectors* (make-hash-table :test #'eql))
    7879
    7980(defun recognize-objc-object (p)
     
    100101      (#.objc-flag-class (id->objc-metaclass index))
    101102      (#.objc-flag-metaclass *objc-metaclass-class*))))
    102 
    103103 
    104104(defun %objc-domain-classp (p)
     
    134134    (declare (fixnum type flags index))
    135135    (ecase flags
    136       (#.objc-flag-instance nil)        ;maybe soon
     136      (#.objc-flag-instance (gethash p *objc-object-slot-vectors*))
    137137      (#.objc-flag-class (id->objc-class-slots-vector index))
    138138      (#.objc-flag-metaclass (id->objc-metaclass-slots-vector index)))))
     
    150150
    151151;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    152 ;;;;                  OBJC Objects, Classes and Metaclasses                 ;;;;
     152;;;;                  ObjC Objects, Classes and Metaclasses                 ;;;;
    153153;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    154154
     
    266266
    267267;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    268 ;;;;                        OBJC-CLASS Slot Protocol                        ;;;;
     268;;;;                              Slot Protocol                             ;;;;
    269269;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    270270
     
    346346(defun compute-foreign-slot-accessors (eslotd)
    347347  (let ((ftype (%slot-definition-type eslotd)))
    348     (case ftype
    349       (:unsigned-byte (values #'%get-unsigned-byte #'%set-byte))
    350       (:signed-byte (values #'%get-signed-byte #'%set-byte))
    351       (:unsigned-word (values #'%get-unsigned-word #'%set-word))
    352       (:signed-word (values #'%get-signed-word #'%set-word))
    353       (:unsigned-fullword (values #'%get-unsigned-long #'%set-long))
    354       (:signed-fullword (values #'%get-signed-long #'%set-long))
    355       (:unsigned-longlong (values #'%%get-unsigned-longlong #'%%set-unsigned-longlong))
    356       (:signed-longlong (values #'%%get-signed-longlong #'%%set-signed-longlong))
    357       (:single-float (values #'%get-single-float #'%set-single-float))
    358       (:double-float (values #'%get-double-float #'%set-double-float))
    359       ((:id :address) (values #'%get-ptr #'%set-ptr))
    360       (t
    361        (cond
    362         ((and (consp ftype) (eq (first ftype) :*))
    363          (values #'%get-ptr #'%set-ptr))
    364         (t (values
    365             #'(lambda (ptr &optional offset)
    366                 (declare (ignore ptr offset))
    367                 (error "Unhandled foreign slot type: ~S" ftype))
    368             #'(lambda (ptr &optional offset)
    369                 (declare (ignore ptr offset))
    370                 (error "Unhandled foreign slot type: ~S" ftype)))))))))
     348    (flet ((unhandled-foreign-slot-type (ptr &optional offset)
     349             (declare (ignore ptr offset))
     350             (error "Unhandled foreign slot type: ~S" ftype)))
     351      (case ftype
     352        (:unsigned-byte (values #'%get-unsigned-byte #'%set-byte))
     353        (:signed-byte (values #'%get-signed-byte #'%set-byte))
     354        (:unsigned-word (values #'%get-unsigned-word #'%set-word))
     355        (:signed-word (values #'%get-signed-word #'%set-word))
     356        (:unsigned-fullword (values #'%get-unsigned-long #'%set-long))
     357        (:signed-fullword (values #'%get-signed-long #'%set-long))
     358        (:unsigned-longlong (values #'%%get-unsigned-longlong #'%%set-unsigned-longlong))
     359        (:signed-longlong (values #'%%get-signed-longlong #'%%set-signed-longlong))
     360        (:single-float (values #'%get-single-float #'%set-single-float))
     361        (:double-float (values #'%get-double-float #'%set-double-float))
     362        ((:id :address) (values #'%get-ptr #'%set-ptr))
     363        (t
     364         (cond
     365          ((and (consp ftype) (eq (first ftype) :*))
     366           (values #'%get-ptr #'%set-ptr))
     367          (t (values #'unhandled-foreign-slot-type #'unhandled-foreign-slot-type))))))))
    371368
    372369
     
    424421  t)
    425422
     423(defmethod slot-makunbound-using-class ((class objc:objc-class-object)
     424                                        instance
     425                                        (slotd foreign-effective-slot-definition))
     426  (declare (ignore instance))
     427  (error "Foreign slots cannot be unbound: ~S" (slot-definition-name slotd)))
     428
    426429(defmethod slot-value-using-class ((class objc:objc-class-object)
    427430                                   instance
     
    440443           value))
    441444
     445
     446;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     447;;;;            Instance Allocation and Initialization Protocols            ;;;;
     448;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     449
     450(defmethod make-instance ((class objc:objc-class) &rest initargs)
     451  (let ((instance (allocate-instance class)))
     452    (apply #'initialize-instance instance initargs)
     453    instance))
     454
     455(defmethod allocate-instance ((class objc:objc-class) &key &allow-other-keys)
     456  (unless (class-finalized-p class)
     457    (finalize-inheritance class))
     458  (let* ((instance (%send class 'alloc)) ; For now; Use SEND macro eventually
     459         (len (length (%wrapper-instance-slots (class-own-wrapper class))))
     460         (slot-vector (allocate-typed-vector :slot-vector (1+ len) (%slot-unbound-marker))))
     461    (setf (slot-vector.instance slot-vector) instance)
     462    (setf (gethash instance *objc-object-slot-vectors*) slot-vector)
     463    instance))
     464
     465(defmethod initialize-instance ((instance objc:objc-object) &rest initargs)
     466  (apply #'shared-initialize instance t initargs))
     467
     468(defmethod reinitialize-instance ((instance objc:objc-object) &rest initargs)
     469  (apply #'shared-initialize instance nil initargs))
     470
     471(defmethod shared-initialize ((instance objc:objc-object) slot-names &rest initargs)
     472  (let ((class (class-of instance)))
     473    ;; Call appropriate ObjC init method
     474    (multiple-value-bind (ks vs) (keys-and-vals initargs)
     475      (apply #'%send instance (lisp-to-objc-init ks) vs))
     476    ;; Initialize CLOS slots
     477    (dolist (slotd (class-slots class))
     478      (when (neq (slot-definition-allocation slotd) :foreign)  ; For now
     479        (let ((sname (slot-definition-name slotd))
     480              (slot-type (slot-definition-type slotd))
     481              (typepred (slot-value slotd 'type-predicate))
     482              (initfunction (slot-definition-initfunction slotd)))
     483          (multiple-value-bind (ignore newval foundp)
     484                               (get-properties initargs (slot-definition-initargs slotd))
     485            (declare (ignore ignore))
     486            (if foundp
     487                (if (funcall typepred newval)
     488                    (setf (slot-value instance sname) newval)
     489                  (report-bad-arg newval slot-type))
     490              (let ((curval (slot-value instance sname)))
     491                (when (and (or (eq slot-names t) (member sname slot-names :test #'eq))
     492                           (eq curval (%slot-unbound-marker))
     493                           initfunction)
     494                  (let ((newval (funcall initfunction)))
     495                    (unless (funcall typepred newval)
     496                      (report-bad-arg newval slot-type))))))))))
     497    instance))
     498
     499
     500;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     501;;;;              Class Definition and Finalization Protocols               ;;;;
     502;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Note: See TracChangeset for help on using the changeset viewer.