- (if (eq 'boolean type) "-P" ""))))
-
-(defun expand-gobject-type (type-number &optional options
- (metaclass 'gobject-class))
- (let* ((supers (cons (supertype type-number) (implements type-number)))
- (class (type-from-number type-number))
- (override-slots (getf options :slots))
- (expanded-slots
- (mapcar
- #'(lambda (param)
- (with-slots (name flags value-type documentation) param
- (let* ((slot-name (default-slot-name name))
- (slot-type value-type) ;(type-from-number value-type t))
- (accessor
- (default-slot-accessor class slot-name (type-from-number slot-type)))) ; temporary workaround for wrong topological sorting of types
- `(,slot-name
- :allocation :property
- :pname ,name
- ,@(cond
- ((and
- (member :writable flags)
- (member :readable flags))
- (list :accessor accessor))
- ((member :writable flags)
- (list :writer `(setf ,accessor)))
- ((member :readable flags)
- (list :reader accessor)))
- ,@(when (or
- (member :construct flags)
- (member :writable flags))
- (list :initarg (intern (string slot-name) "KEYWORD")))
- :type ,slot-type
- ,@(when documentation
- (list :documentation documentation))))))
- (query-object-class-properties type-number))))
-
- (dolist (slot-def override-slots)
- (let ((name (car slot-def))
- (pname (getf (cdr slot-def) :pname)))
- (setq
- expanded-slots
- (delete-if
- #'(lambda (expanded-slot-def)
- (or
- (eq name (car expanded-slot-def))
- (and
- pname
- (string= pname (getf (cdr expanded-slot-def) :pname)))))
- expanded-slots))
-
- (unless (getf (cdr slot-def) :ignore)
- (push slot-def expanded-slots))))
-
- `(progn
- (defclass ,class ,supers
- ,expanded-slots
- (:metaclass ,metaclass)
- (:alien-name ,(find-type-name type-number))))))
+ (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)))))