[Openmcl-devel] wrapping foreign objects in lisp classes
Cyrus Harmon
ch-openmcl at bobobeach.com
Mon Aug 16 16:49:53 PDT 2004
Conceptually, I like the slots approach. Here's what I cooked up to
deal with the problem before I read about the slot-value-using-class
stuff:
(in-package :vimage)
(defmacro def-foreign-slot (lclass lslot pslot ffield)
`(progn
(defmethod ,lslot ((obj ,lclass))
(pref (,pslot obj) ,ffield))
(defmethod ,(make-intern (strcat "set-" (symbol-name lslot)))
((obj ,lclass) value)
(setf (pref (,pslot obj) ,ffield) value))
(defsetf ,lslot ,(make-intern (strcat "set-" (symbol-name lslot))))
))
(defclass vimage-buffer-8888 ()
((mac-vimage-buffer :accessor mac-vimage-buffer :initform
(make-record :v<I>mage_<B>uffer))
(height :reader height :writer set-height)
(width :reader width :writer set-width)
(rowbytes :reader rowbytes :writer set-rowbytes)
(data :reader data :writer set-data)))
(def-foreign-slot vimage-buffer-8888 height mac-vimage-buffer
:v<I>mage_<B>uffer.height)
(def-foreign-slot vimage-buffer-8888 width mac-vimage-buffer
:v<I>mage_<B>uffer.width)
(def-foreign-slot vimage-buffer-8888 data mac-vimage-buffer
:v<I>mage_<B>uffer.data)
(def-foreign-slot vimage-buffer-8888 rowbytes mac-vimage-buffer
:v<I>mage_<B>uffer.row<B>ytes)
Not exactly the most elegant approach, but it's getting the job done
for the moment.
Cyrus
On Aug 16, 2004, at 4:29 PM, Gary Byers wrote:
>
>
> On Mon, 16 Aug 2004, Dan Knapp wrote:
>>
>> Using the metaobject protocol doesn't avoid having to write the
>> custom readers and
>> writers; you still need to do that. However, you should be able to do
>> it in such a way
>> that you only need to do it once instead of for every slot of every
>> class.
>>
>
> The methods that a custom metaclass would have to override are
> SLOT-VALUE-USING-CLASS and (SETF SLOT-VALUE-USING-CLASS). Reader and
> writer methods do the equivalent of calls to these methods in general
> (in a case where a user-defined [SETF ]SLOT-VALUE-USING-CLASS method
> could be applicable, the user-defined method will be invoked.)
>
> The Cocoa bridge implements SLOT-VALUE-USING-CLASS (and SETF thereof)
> by storing getter/setter functions (defined in terms of low-level
> memory accessors) in specialized SLOT-DEFINITION objects.
>
> In the bridge's case, it seemed natural to treat ObjC instance
> variables
> as CLOS slots. It may be simpler (in some ways) to simply define
> methods
> on the fields of an encapsulated foreign structure, without trying to
> make those methods be accessor methods. As a poor example:
>
> ;; This definition might be encoded in a .cdb file
> (def-foreign-type nil (:struct :point ; this is a hypothetical example
> (:x :float)
> (:y :float)))
>
> (defclass point ()
> ((real-point :initarg :real-point
> :accessor real-point
> :documentation "a pointer to a real point")))
>
> (defmethod point-x ((p point))
> (let* ((real-point (real-point p)))
> (pref real-point :point.x)))
>
>
> (defmethod (setf point-x) (new (p point))
> (let* ((real-point (real-point p)))
> (setf (pref real-point :point.x) new)))
>
>
> You might want these methods to do a little more type- and
> sanity-checking
> than is shown here, but it seems like most/all of that is boilerplate:
> given a foreign structure definition, it's probably not too hard to
> generate an encapsulating class and methods to access that structure's
> fields.
>
> (You wouldn't have the ability to use SLOT-VALUE or WITH-SLOTS on the
> foreign field, but you'd be able to deal with a foreign structure and
> its fields at a fairly high level.)
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
More information about the Openmcl-devel
mailing list