- (if (eq 'boolean type) "-p" ""))))
-
-(defun expand-gobject-type (type-number &optional slots)
- (let* ((super (supertype type-number))
- (class (type-from-number type-number))
- (expanded-slots
- (mapcar
- #'(lambda (param)
- (with-slots (name flags type documentation) param
- (let* ((slot-name (default-slot-name name))
- (slot-type (type-from-number type))
- (accessor
- (default-slot-accessor class slot-name slot-type)))
- `(,slot-name
- :allocation :param
- :param ,name
- ,@(when (member :writable flags)
- (list :writer `(setf ,accessor)))
- ,@(when (member :readable flags)
- (list :reader accessor))
- ,@(when (member :construct flags)
- (list :initarg (intern (string slot-name) "KEYWORD")))
- :type ,slot-type
- ,@(when documentation
- (list :documentation documentation))))))
- (query-object-class-properties type-number))))
-
- `(defclass ,class (,super)
- ,expanded-slots
- (:metaclass gobject-class)
- (:alien-name ,(find-type-name type-number)))))
-
-(register-derivable-type
- 'gobject "GObject"
- :query 'query-object-class-dependencies
- :expand 'expand-gobject-type)
-
+ (if (eq type 'boolean) "-P" ""))))
+
+
+(defun slot-definition-from-property (class property)
+ (with-slots (name flags value-type documentation) property
+ (let* ((slot-name (default-slot-name name))
+ (slot-type (or (type-from-number value-type) value-type))
+ (accessor (default-slot-accessor class slot-name slot-type)))
+
+ `(,slot-name
+ :allocation :property :pname ,name
+
+ ;; accessors
+ ,@(cond
+ ((and
+ (member :writable flags) (member :readable flags)
+ (not (member :construct-only flags)))
+ (list :accessor accessor))
+ ((and (member :writable flags) (not (member :construct-only flags)))
+ (list :writer `(setf ,accessor)))
+ ((member :readable flags)
+ (list :reader accessor)))
+
+ ;; readable/writable/construct
+ ,@(when (or (not (member :writable flags))
+ (member :construct-only flags))
+ '(:writable nil))
+ ,@(when (not (member :readable flags))
+ '(:readable nil))
+ ,@(when (or (member :construct flags)
+ (member :construct-only flags))
+ '(:construct t))
+
+ ;; initargs
+ ,@(when (or (member :construct flags)
+ (member :construct-only flags)
+ (member :writable flags))
+ (list :initarg (intern (string slot-name) "KEYWORD")))
+
+ :type ,slot-type
+ :documentation ,documentation))))
+
+
+(defun slot-definitions (class properties slots)
+ (loop
+ with manual-slots = slots
+ for property in properties
+ unless (find-if
+ #'(lambda (slot)
+ (destructuring-bind (name &rest args) slot
+ (or
+ (equal (param-name property) (getf args :pname))
+ (eq (default-slot-name (param-name property)) name))))
+ manual-slots)
+ do (push (slot-definition-from-property class property) slots))
+ (delete-if #'(lambda (slot) (getf (rest slot) :ignore)) slots))
+
+
+(defun expand-gobject-type (type &optional options (metaclass 'gobject-class))
+ (let ((supers (cons (supertype type) (implements type)))
+ (class (type-from-number type))
+ (slots (getf options :slots)))
+ `(defclass ,class ,supers
+ ,(slot-definitions class (query-object-class-properties type) slots)
+ (:metaclass ,metaclass)
+ (:alien-name ,(find-type-name type)))))
+
+
+(register-derivable-type 'gobject "GObject" 'expand-gobject-type)