chiark / gitweb /
Added pseudo type 'referenced' and a few other changes
[clg] / glib / gobject.lisp
index 361086f94b27caddb9457d8ad337f3145b1a34b1..359a3412926faf1019f2ce313bd6cda9d997a7b2 100644 (file)
@@ -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)