chiark / gitweb /
More improvements to virtual slot access
authorespen <espen>
Wed, 16 Aug 2006 12:09:03 +0000 (12:09 +0000)
committerespen <espen>
Wed, 16 Aug 2006 12:09:03 +0000 (12:09 +0000)
gffi/defpackage.lisp
gffi/proxy.lisp
gffi/virtual-slots.lisp
glib/defpackage.lisp
glib/gobject.lisp
gtk/gtkobject.lisp

index db6b134e1c1ef628d2a563ad909ab4a8ac461627..1bbe9075576c6a0e97127d679fe34540bc9bd1c8 100644 (file)
@@ -20,7 +20,7 @@
 ;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 ;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-;; $Id: defpackage.lisp,v 1.3 2006-06-30 08:14:14 espen Exp $
+;; $Id: defpackage.lisp,v 1.4 2006-08-16 12:09:03 espen Exp $
 
 (defpackage "GFFI"
   (:use "COMMON-LISP" "AUTOEXPORT" "PKG-CONFIG" "CLG-UTILS")
@@ -78,7 +78,7 @@ (defpackage "GFFI"
           "COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGS" "BOUNDP-FUNCTION"
           "COMPUTE-SLOT-READER-FUNCTION" "COMPUTE-SLOT-BOUNDP-FUNCTION"
           "COMPUTE-SLOT-WRITER-FUNCTION" "COMPUTE-SLOT-MAKUNBOUND-FUNCTION"
-          #+clisp"SLOT-DEFINITION-TYPE")
+          "SLOT-READABLE-P" "SLOT-WRITABLE-P" #+clisp"SLOT-DEFINITION-TYPE")
   ;; Symbols from proxy.lisp  
   (:export "CACHE-INSTANCE" "FIND-CACHED-INSTANCE" "LIST-CACHED-INSTANCES"
            "REMOVE-CACHED-INSTANCE" "PROXY" "INSTANCE-FINALIZER" 
index c2c3fbccec91a10150b076a7afc3e9858b1049eb..9cf15ca54608b7a4f39fa4adcb5d57802aeb8570 100644 (file)
@@ -20,7 +20,7 @@
 ;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 ;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-;; $Id: proxy.lisp,v 1.3 2006-08-16 11:02:45 espen Exp $
+;; $Id: proxy.lisp,v 1.4 2006-08-16 12:09:03 espen Exp $
 
 (in-package "GFFI")
 
@@ -241,6 +241,9 @@   (defmethod compute-effective-slot-definition-initargs ((class proxy-class) dir
         (call-next-method))
       (call-next-method)))
   
+  (defmethod slot-readable-p ((slotd effective-alien-slot-definition))
+    (declare (ignore slotd))
+    t)
 
   (defmethod compute-slot-reader-function ((slotd effective-alien-slot-definition) &optional signal-unbound-p)
     (declare (ignore signal-unbound-p))
@@ -250,6 +253,10 @@   (defmethod compute-slot-reader-function ((slotd effective-alien-slot-definitio
       #'(lambda (object)
          (funcall reader (foreign-location object) offset))))
 
+  (defmethod slot-writable-p ((slotd effective-alien-slot-definition))
+    (declare (ignore slotd))
+    t)
+
   (defmethod compute-slot-writer-function ((slotd effective-alien-slot-definition))
     (let* ((type (slot-definition-type slotd))
           (offset (slot-definition-offset slotd))
index b57082c562b161a77b53391b19bab25714c9174e..6551210bf1bb6c5d1151afba26986db29fdc0102 100644 (file)
@@ -20,7 +20,7 @@
 ;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 ;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-;; $Id: virtual-slots.lisp,v 1.2 2006-08-16 11:02:45 espen Exp $
+;; $Id: virtual-slots.lisp,v 1.3 2006-08-16 12:09:03 espen Exp $
 
 (in-package "GFFI")
 
@@ -58,12 +58,21 @@ (defclass effective-special-slot-definition (standard-effective-slot-definition)
 (defclass virtual-slots-object (standard-object)
   ())
 
-
+(defgeneric slot-readable-p (slotd))
+(defgeneric slot-writable-p (slotd))
 (defgeneric compute-slot-reader-function (slotd &optional signal-unbound-p))
 (defgeneric compute-slot-boundp-function (slotd))
 (defgeneric compute-slot-writer-function (slotd))
 (defgeneric compute-slot-makunbound-function (slotd))
 
+(defmethod slot-readable-p ((slotd standard-effective-slot-definition))
+  (declare (ignore slotd))
+  t)
+
+(defmethod slot-writable-p ((slotd standard-effective-slot-definition))
+  (declare (ignore slotd))
+  t)
+
 
 #+clisp
 (defmethod slot-definition-type ((slotd t))
@@ -87,6 +96,9 @@ (defmethod effective-slot-definition-class ((class virtual-slots-class) &rest in
    (t (call-next-method))))
 
 
+(defmethod slot-readable-p ((slotd effective-virtual-slot-definition))
+  (slot-boundp slotd 'getter))
+
 (define-condition unreadable-slot (cell-error)
   ((instance :reader unreadable-slot-instance :initarg :instance))
   (:report (lambda (condition stream)
@@ -95,45 +107,50 @@ (define-condition unreadable-slot (cell-error)
              (unreadable-slot-instance condition)))))
 
 (defmethod compute-slot-reader-function :around ((slotd effective-virtual-slot-definition) &optional (signal-unbound-p t))
-  (let ((reader-function (call-next-method)))
-    (cond
-     ((not signal-unbound-p) reader-function)
-
-     ;; An explicit boundp function has been supplied
-     ((slot-boundp slotd 'boundp) 
-      (let ((unbound-value (slot-value slotd 'boundp)))
-       #'(lambda (object)
-           (let ((value (funcall reader-function object)))
-             (if (eq value unbound-value)
-                 (slot-unbound (class-of object) object (slot-definition-name slotd))
-               value)))))
-
-     ;; A type unbound value exists
-     ((let ((unbound-method (find-applicable-type-method 'unbound-value 
-                            (slot-definition-type slotd) nil)))
-       (when unbound-method
-         (let ((unbound-value (funcall unbound-method (slot-definition-type slotd))))
-           #'(lambda (object)
-               (let ((value (funcall reader-function object)))
-                 (if (eq value unbound-value)
-                     (slot-unbound (class-of object) object (slot-definition-name slotd))
-                   value)))))))
-
-     ((let ((boundp-function (compute-slot-boundp-function slotd)))
-       #'(lambda (object)
-           (if (funcall boundp-function object)
-               (funcall reader-function object)
-             (slot-unbound (class-of object) object (slot-definition-name slotd)))))))))
+  (if (not (slot-readable-p slotd))
+      #'(lambda (object)
+         (error 'unreadable-slot :name (slot-definition-name slotd) :instance object))
+    (let ((reader-function (call-next-method)))
+      (cond
+       ;; Don't create an wrapper to signal unbound value
+       ((not signal-unbound-p) reader-function)
+       
+       ;; An explicit boundp function has been supplied
+       ((slot-boundp slotd 'boundp) 
+       (let ((unbound-value (slot-value slotd 'boundp)))
+         #'(lambda (object)
+             (let ((value (funcall reader-function object)))
+               (if (eq value unbound-value)
+                   (slot-unbound (class-of object) object (slot-definition-name slotd))
+                 value)))))
+       
+       ;; A type unbound value exists
+       ((let ((unbound-method (find-applicable-type-method 'unbound-value 
+                              (slot-definition-type slotd) nil)))
+         (when unbound-method
+           (let ((unbound-value (funcall unbound-method (slot-definition-type slotd))))
+             #'(lambda (object)
+                 (let ((value (funcall reader-function object)))
+                   (if (eq value unbound-value)
+                       (slot-unbound (class-of object) object (slot-definition-name slotd))
+                     value)))))))
+       
+       ((let ((boundp-function (compute-slot-boundp-function slotd)))
+         #'(lambda (object)
+             (if (funcall boundp-function object)
+                 (funcall reader-function object)
+               (slot-unbound (class-of object) object (slot-definition-name slotd))))))))))
 
 (defmethod compute-slot-reader-function ((slotd effective-virtual-slot-definition) &optional signal-unbound-p)
   (declare (ignore signal-unbound-p))
-  (if (slot-boundp slotd 'getter)
-      (slot-value slotd 'getter)
-    #'(lambda (object)
-       (error 'unreadable-slot :name (slot-definition-name slotd) :instance object))))
+  (slot-value slotd 'getter))
 
 (defmethod compute-slot-boundp-function ((slotd effective-virtual-slot-definition))
   (cond
+   ;; Non readable slots are not bound per definition
+   ((not (slot-readable-p slotd))
+    #'(lambda (object) (declare (ignore object)) nil))
+
    ;; An explicit boundp function has been supplied
    ((slot-boundp slotd 'boundp) (slot-value slotd 'boundp))
    
@@ -156,6 +173,9 @@ (defmethod compute-slot-boundp-function ((slotd effective-virtual-slot-definitio
    ;; Slot has no unbound state
    (#'(lambda (object) (declare (ignore object)) t))))
 
+(defmethod slot-writable-p ((slotd effective-virtual-slot-definition))
+  (slot-boundp slotd 'setter))
+
 (define-condition unwritable-slot (cell-error)
   ((instance :reader unwritable-slot-instance :initarg :instance))
   (:report (lambda (condition stream)
@@ -163,22 +183,35 @@ (define-condition unwritable-slot (cell-error)
              (cell-error-name condition)
              (unwritable-slot-instance condition)))))
 
+(defmethod compute-slot-writer-function :around ((slotd effective-virtual-slot-definition))
+  (if (not (slot-writable-p slotd))
+      #'(lambda (value object)
+         (declare (ignore value))
+         (error 'unwritable-slot :name (slot-definition-name slotd) :instance object))
+    (call-next-method)))
+
 (defmethod compute-slot-writer-function ((slotd effective-virtual-slot-definition))
-  (if (slot-boundp slotd 'setter)
-      (slot-value slotd 'setter)
-    #'(lambda (value object)
-       (declare (ignore value))
-       (error 'unwritable-slot :name (slot-definition-name slotd) :instance object))))
+  (slot-value slotd 'setter))
+
+(define-condition slot-can-not-be-unbound (cell-error)
+  ((instance :reader slot-can-not-be-unbound-instance :initarg :instance))
+  (:report (lambda (condition stream)
+            (format stream "~@<The slot ~S in the object ~S can not be made unbound.~@:>"
+             (cell-error-name condition)
+             (slot-can-not-be-unbound-instance condition)))))
 
 (defmethod compute-slot-makunbound-function ((slotd effective-virtual-slot-definition))
   (cond
+   ((not (slot-writable-p slotd))
+    #'(lambda (object)
+       (error 'unwritable-slot :name (slot-definition-name slotd) :instance object)))
    ((slot-boundp slotd 'makunbound) (slot-value slotd 'makunbound))
    ((slot-boundp slotd 'unbound)
     #'(lambda (object)
        (funcall (slot-value slotd 'writer-function) (slot-value slotd 'unbound) object)))
    (t
     #'(lambda (object)
-       (error 'unwritable-slot :name (slot-definition-name slotd) :instance object)))))
+       (error 'slot-can-not-be-unbound :name (slot-definition-name slotd) :instance object)))))
 
 
 #-clisp
index 27293c2a5dda9c329561883bb68b36663cd00fb5..79766c6bb884dbeca889baea7c0d4102c42577fd 100644 (file)
@@ -20,7 +20,7 @@
 ;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 ;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-;; $Id: defpackage.lisp,v 1.14 2006-04-25 20:56:26 espen Exp $
+;; $Id: defpackage.lisp,v 1.15 2006-08-16 12:09:03 espen Exp $
 
 
 (defpackage "GLIB"
@@ -76,8 +76,8 @@ (defpackage "GLIB"
           "WITH-CALLBACK-FUNCTION")
   ;; Symbols from gobject.lisp  
   (:export "GOBJECT-CLASS" "INSTANCE-SLOTS-P" "DIRECT-PROPERTY-SLOT-DEFINITION"
-          "SLOT-DEFINITION-PNAME" "SLOT-READABLE-P" "SLOT-WRITABLE-P"
-          "CONSTRUCT-ONLY-PROPERTY-P" "EFFECTIVE-PROPERTY-SLOT-DEFINITION"
+          "SLOT-DEFINITION-PNAME" "CONSTRUCT-ONLY-PROPERTY-P" 
+          "EFFECTIVE-PROPERTY-SLOT-DEFINITION"
           "DIRECT-USER-DATA-SLOT-DEFINITION" "EFFECTIVE-USER-DATA-SLOT-DEFINITION"
           "GOBJECT" "OBJECT-FREEZE-NOTIFY" "OBJECT-THAW-NOTIFY" "USER-DATA"
           "USER-DATA-DESTROY-CALLBACK" "USER-DATA-P" "UNSET-USER-DATA"
index ae5995a52da0dd44fb922a4fb980a78df3247588..115a04ca75cfee7063c39a822c9eca918ac52c67 100644 (file)
@@ -20,7 +20,7 @@
 ;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 ;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-;; $Id: gobject.lisp,v 1.53 2006-08-16 11:02:46 espen Exp $
+;; $Id: gobject.lisp,v 1.54 2006-08-16 12:09:03 espen Exp $
 
 (in-package "GLIB")
 
@@ -63,15 +63,6 @@ (defclass effective-user-data-slot-definition (effective-virtual-slot-definition
   ())
 
 
-(defmethod slot-readable-p ((slotd standard-effective-slot-definition))
-  (declare (ignore slotd))
-  t)
-
-(defmethod slot-writable-p ((slotd standard-effective-slot-definition))
-  (declare (ignore slotd))
-  t)
-
-
 (defbinding %object-ref () pointer
   (location pointer))
 
@@ -151,38 +142,39 @@ (declaim (special *ignore-setting-construct-only-property*))
 
 (defmethod compute-slot-reader-function ((slotd effective-property-slot-definition) &optional signal-unbound-p)
   (declare (ignore signal-unbound-p))
-  (if (slot-readable-p slotd)
-      (let* ((type (slot-definition-type slotd))
-            (pname (slot-definition-pname slotd))
-            (reader (reader-function type :ref :get)))
-       #'(lambda (object)
-           (with-memory (gvalue +gvalue-size+)
-             (%gvalue-init gvalue (find-type-number type))
-             (%object-get-property object pname gvalue)
-             (funcall reader gvalue +gvalue-value-offset+))))
+  (let* ((type (slot-definition-type slotd))
+        (pname (slot-definition-pname slotd))
+        (reader (reader-function type :ref :get)))
+    #'(lambda (object)
+       (with-memory (gvalue +gvalue-size+)
+         (%gvalue-init gvalue (find-type-number type))
+         (%object-get-property object pname gvalue)
+         (funcall reader gvalue +gvalue-value-offset+)))))
+
+(defmethod compute-slot-writer-function :around ((slotd effective-property-slot-definition))
+  (if (construct-only-property-p slotd)
+      #'(lambda (value object)
+         (declare (ignore value object))
+         (unless *ignore-setting-construct-only-property*
+           (error 'unwritable-slot :name (slot-definition-name slotd) :instance object)))
     (call-next-method)))
 
 (defmethod compute-slot-writer-function ((slotd effective-property-slot-definition))
-  (cond
-   ((slot-writable-p slotd)
-    (let* ((type (slot-definition-type slotd))
-          (pname (slot-definition-pname slotd))
-          (writer (writer-function type :temp t))
-          (destroy (destroy-function type :temp t)))
-      #'(lambda (value object)
-         (with-memory (gvalue +gvalue-size+)
-           (%gvalue-init gvalue (find-type-number type))
-           (funcall writer value gvalue +gvalue-value-offset+)
-           (%object-set-property object pname gvalue)
-           (funcall destroy gvalue +gvalue-value-offset+))
-         value)))
-
-   ((construct-only-property-p slotd)
+  (let* ((type (slot-definition-type slotd))
+        (pname (slot-definition-pname slotd))
+        (writer (writer-function type :temp t))
+        (destroy (destroy-function type :temp t)))
     #'(lambda (value object)
-       (declare (ignore value object))
-       (unless *ignore-setting-construct-only-property*
-         (error 'unwritable-slot :name (slot-definition-name slotd) :instance object))))
-   ((call-next-method))))
+       (with-memory (gvalue +gvalue-size+)
+         (%gvalue-init gvalue (find-type-number type))
+         (funcall writer value gvalue +gvalue-value-offset+)
+         (%object-set-property object pname gvalue)
+         (funcall destroy gvalue +gvalue-value-offset+))
+       value)))
+
+(defmethod slot-readable-p ((slotd effective-user-data-slot-definition))
+  (declare (ignore slotd))
+  t)
 
 (defmethod compute-slot-reader-function ((slotd effective-user-data-slot-definition) &optional signal-unbound-p)
   (declare (ignore signal-unbound-p))
@@ -195,6 +187,10 @@ (defmethod compute-slot-boundp-function ((slotd effective-user-data-slot-definit
     #'(lambda (object)
        (user-data-p object slot-name))))
 
+(defmethod slot-writable-p ((slotd effective-user-data-slot-definition))
+  (declare (ignore slotd))
+  t)
+
 (defmethod compute-slot-writer-function ((slotd effective-user-data-slot-definition))
   (let ((slot-name (slot-definition-name slotd)))
     #'(lambda (value object)
index bd6ec8d7898cc27f575516083d5ecc77f43a2a64..10b8fc74884fefbb74ec7e0a2101b8bc4a43b8a7 100644 (file)
@@ -20,7 +20,7 @@
 ;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 ;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-;; $Id: gtkobject.lisp,v 1.36 2006-08-16 11:02:46 espen Exp $
+;; $Id: gtkobject.lisp,v 1.37 2006-08-16 12:09:03 espen Exp $
 
 
 (in-package "GTK")
@@ -135,6 +135,10 @@ (defmethod compute-effective-slot-definition-initargs ((class container-child-cl
        (call-next-method))
     (call-next-method)))
 
+(defmethod slot-readable-p ((slotd effective-child-slot-definition))
+  (declare (ignore slotd))
+  t)
+
 (defmethod compute-slot-reader-function ((slotd effective-child-slot-definition) &optional signal-unbound-p)
   (declare (ignore signal-unbound-p))
   (let* ((type (slot-definition-type slotd))
@@ -147,6 +151,10 @@ (defmethod compute-slot-reader-function ((slotd effective-child-slot-definition)
            (%container-child-get-property parent child pname gvalue)
            (funcall reader gvalue +gvalue-value-offset+))))))
 
+(defmethod slot-writable-p ((slotd effective-child-slot-definition))
+  (declare (ignore slotd))
+  t)
+
 (defmethod compute-slot-writer-function ((slotd effective-child-slot-definition))
   (let* ((type (slot-definition-type slotd))
         (pname (slot-definition-pname slotd))