X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/clg/blobdiff_plain/eeda1c2da2663832d114329d58e92f77c86cf2fa..8beedfa0f30e6f332112485c3e739937e45155f9:/glib/gobject.lisp diff --git a/glib/gobject.lisp b/glib/gobject.lisp index 8292772..7eb4b41 100644 --- a/glib/gobject.lisp +++ b/glib/gobject.lisp @@ -15,7 +15,7 @@ ;; License along with this library; if not, write to the Free Software ;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -;; $Id: gobject.lisp,v 1.23 2004-12-16 23:19:17 espen Exp $ +;; $Id: gobject.lisp,v 1.25 2004-12-28 20:29:05 espen Exp $ (in-package "GLIB") @@ -103,7 +103,7 @@ (defmethod initialize-internal-slot-functions ((slotd effective-property-slot-de (let ((reader nil)) #'(lambda (object) (unless reader - (setq reader (reader-function (type-from-number type-number)))) + (setq reader (reader-function type))) ;(type-from-number type-number)))) (let ((gvalue (gvalue-new type-number))) (%object-get-property object pname gvalue) (unwind-protect @@ -116,7 +116,7 @@ (defmethod initialize-internal-slot-functions ((slotd effective-property-slot-de (let ((writer nil)) #'(lambda (value object) (unless writer - (setq writer (writer-function (type-from-number type-number)))) + (setq writer (writer-function type))) ;(type-from-number type-number)))) (let ((gvalue (gvalue-new type-number))) (funcall writer value gvalue +gvalue-value-offset+) (%object-set-property object pname gvalue) @@ -152,49 +152,50 @@ (defun initial-apply-add (object function initargs key pkey) (defmethod initialize-instance ((object gobject) &rest initargs) - ;; Extract initargs which we should pass directly to the GObeject - ;; constructor - (let* ((slotds (class-slots (class-of object))) - (args (when initargs - (loop - as (key value . rest) = initargs then rest - as slotd = (find-if - #'(lambda (slotd) - (member key (slot-definition-initargs slotd))) - slotds) - when (and (typep slotd 'effective-property-slot-definition) - (slot-value slotd 'construct)) - collect (progn - (remf initargs key) - (list - (slot-definition-pname slotd) - (slot-definition-type slotd) - value)) - while rest)))) - (if args - (let* ((string-size (size-of 'string)) - (string-writer (writer-function 'string)) - (string-destroy (destroy-function 'string)) - (params (allocate-memory - (* (length args) (+ string-size +gvalue-size+))))) - (loop - for (pname type value) in args - as tmp = params then (sap+ tmp (+ string-size +gvalue-size+)) - do (funcall string-writer pname tmp) - (gvalue-init (sap+ tmp string-size) type value)) - (unwind-protect - (setf - (slot-value object 'location) - (%gobject-newv (type-number-of object) (length args) params)) + (unless (slot-boundp object 'location) + ;; Extract initargs which we should pass directly to the GObeject + ;; constructor + (let* ((slotds (class-slots (class-of object))) + (args (when initargs + (loop + as (key value . rest) = initargs then rest + as slotd = (find-if + #'(lambda (slotd) + (member key (slot-definition-initargs slotd))) + slotds) + when (and (typep slotd 'effective-property-slot-definition) + (slot-value slotd 'construct)) + collect (progn + (remf initargs key) + (list + (slot-definition-pname slotd) + (slot-definition-type slotd) + value)) + while rest)))) + (if args + (let* ((string-size (size-of 'string)) + (string-writer (writer-function 'string)) + (string-destroy (destroy-function 'string)) + (params (allocate-memory + (* (length args) (+ string-size +gvalue-size+))))) (loop - repeat (length args) + for (pname type value) in args as tmp = params then (sap+ tmp (+ string-size +gvalue-size+)) - do (funcall string-destroy tmp) - (gvalue-unset (sap+ tmp string-size))) - (deallocate-memory params))) + do (funcall string-writer pname tmp) + (gvalue-init (sap+ tmp string-size) type value)) + (unwind-protect + (setf + (slot-value object 'location) + (%gobject-newv (type-number-of object) (length args) params)) + (loop + repeat (length args) + as tmp = params then (sap+ tmp (+ string-size +gvalue-size+)) + do (funcall string-destroy tmp) + (gvalue-unset (sap+ tmp string-size))) + (deallocate-memory params))) (setf (slot-value object 'location) - (%gobject-new (type-number-of object))))) + (%gobject-new (type-number-of object)))))) (apply #'call-next-method object initargs)) @@ -313,10 +314,8 @@ (defun slot-definition-from-property (class property &optional args) `(,slot-name :allocation :property :pname ,name - ;; temporary hack ,@(cond - ((find :unbound args) (list :unbound (getf args :unbound))) - ((type-is-p slot-type 'gobject) (list :unbound nil))) + ((find :unbound args) (list :unbound (getf args :unbound)))) ;; accessors ,@(cond @@ -379,3 +378,24 @@ (defun expand-gobject-type (type &optional options (metaclass 'gobject-class)) (register-derivable-type 'gobject "GObject" 'expand-gobject-type) + + +;;; Pseudo type for gobject instances which have their reference count +;;; increased by the returning function + +(defmethod alien-type ((type (eql 'referenced)) &rest args) + (declare (ignore type args)) + (alien-type 'gobject)) + +(defmethod from-alien-form (form (type (eql 'referenced)) &rest args) + (declare (ignore type)) + (destructuring-bind (type) args + (if (subtypep type 'gobject) + (let ((instance (make-symbol "INSTANCE"))) + `(let ((,instance ,(from-alien-form form type))) + (when ,instance + (%object-unref (proxy-location ,instance))) + ,instance)) + (error "~A is not a subclass of GOBJECT" type)))) + +(export 'referenced)