Added method to generic function PROXY-INSTANCE-SIZE
[clg] / glib / gobject.lisp
index 50c2958..c6bfe26 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.24 2004-12-21 00:04:48 espen Exp $
+;; $Id: gobject.lisp,v 1.28 2005-01-12 13:26:03 espen Exp $
 
 (in-package "GLIB")
 
   ((pname :reader slot-definition-pname :initarg :pname)
    (readable :reader slot-readable-p :initarg :readable)
    (writable :reader slot-writable-p :initarg :writable)
-   (construct :initarg :construct)));)
+   (construct :initarg :construct)))
+
+(defclass direct-user-data-slot-definition (direct-virtual-slot-definition)
+  ())
+
+(defclass effective-user-data-slot-definition (effective-virtual-slot-definition)
+  ())
+
 
 (defbinding %object-ref () pointer
   (location pointer))
 (defmethod direct-slot-definition-class ((class gobject-class) &rest initargs)
   (case (getf initargs :allocation)
     (:property (find-class 'direct-property-slot-definition))
+    (:user-data (find-class 'direct-user-data-slot-definition))
     (t (call-next-method))))
 
 (defmethod effective-slot-definition-class ((class gobject-class) &rest initargs)
   (case (getf initargs :allocation)
     (:property (find-class 'effective-property-slot-definition))
+    (:user-data (find-class 'effective-user-data-slot-definition))
     (t (call-next-method))))
 
 (defmethod compute-effective-slot-definition-initargs ((class gobject-class) direct-slotds)
        (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
        (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)
 
   (call-next-method))
 
+(defmethod initialize-internal-slot-functions ((slotd effective-user-data-slot-definition))
+  (let ((slot-name (slot-definition-name slotd)))
+    (unless (slot-boundp slotd 'getter)
+      (setf 
+       (slot-value slotd 'getter)
+       #'(lambda (object)
+          (prog1 (user-data object slot-name)))))
+    (unless (slot-boundp slotd 'setter)
+      (setf 
+       (slot-value slotd 'setter)
+       #'(lambda (value object)
+          (setf (user-data object slot-name) value))))
+    (unless (slot-boundp slotd 'boundp)
+      (setf 
+       (slot-value slotd 'boundp)
+       #'(lambda (object)
+          (user-data-p object slot-name)))))
+  (call-next-method))
+
 
 ;;;; Super class for all classes in the GObject type hierarchy
 
 
 ;;;; User data
 
-(defun (setf object-data) (data object key &key (test #'eq))
+(defun (setf user-data) (data object key)
   (%object-set-qdata-full
-   object (quark-from-object key :test test)
+   object (quark-from-object key)
    (register-user-data data) (callback %destroy-user-data))
   data)
 
+;; depecated
+(defun (setf object-data) (data object key &key (test #'eq))
+  (assert (eq test #'eq))
+  (setf (user-data object key) data))
+
 (defbinding %object-get-qdata () unsigned-long
   (object gobject)              
   (id quark))
 
+(defun user-data (object key)
+  (find-user-data (%object-get-qdata object (quark-from-object key))))
+
+;; depecated
 (defun object-data (object key &key (test #'eq))
-  (find-user-data
-   (%object-get-qdata object (quark-from-object key :test test))))
+  (assert (eq test #'eq))
+  (user-data object key))
+
+(defun user-data-p (object key)
+  (nth-value 1 (find-user-data (%object-get-qdata object (quark-from-object key)))))
 
 
 ;;;;
     (if (eq type 'boolean) "-P" ""))))
 
 
-(defun slot-definition-from-property (class property &optional args)
+(defun slot-definition-from-property (class property &optional slot-name args)
   (with-slots (name flags value-type documentation) property
-    (let* ((slot-name (default-slot-name name))
+    (let* ((slot-name (or slot-name (default-slot-name name)))
           (slot-type (or (getf args :type) (type-from-number value-type) value-type))
           (accessor (default-slot-accessor class slot-name slot-type)))
       
       `(,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
                    (member :construct-only flags)
                    (member :writable flags))
            (list :initarg (intern (string slot-name) "KEYWORD")))
+       ,@(cond
+          ((find :initarg args) (list :initarg (getf args :initarg))))
        
        :type ,slot-type
        :documentation ,documentation))))
        ((getf (rest slot) :merge)
        (setf 
         (rest slot) 
-        (rest (slot-definition-from-property class property (rest slot)))))))
+        (rest (slot-definition-from-property class property (first slot) (rest slot)))))))
   (delete-if #'(lambda (slot) (getf (rest slot) :ignore)) slots))
 
 
 
 
 (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)