chiark / gitweb /
Made toggle reference depend on glib2.8
[clg] / glib / proxy.lisp
index fe17afdea2078ba241ef2a59bbca0b04d92b0703..927e539a85111bf788fccd0455a9863ff38bb14a 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.21 2005-04-24 13:26:40 espen Exp $
+;; $Id: proxy.lisp,v 1.23 2006-02-02 22:35:14 espen Exp $
 
 (in-package "GLIB")
 
@@ -40,31 +40,42 @@   (defclass effective-virtual-slot-definition (standard-effective-slot-definitio
     ((setter :reader slot-definition-setter :initarg :setter)
      (getter :reader slot-definition-getter :initarg :getter)
      (unbound :reader slot-definition-unbound :initarg :unbound)
-     (boundp :reader slot-definition-boundp :initarg :boundp))))
-  
-  (defvar *unbound-marker* (gensym "UNBOUND-MARKER-"))
-
-  (defun most-specific-slot-value (instances slot &optional 
-                                  (default *unbound-marker*))
-    (let ((object (find-if
-                  #'(lambda (ob)
-                      (and (slot-exists-p ob slot) (slot-boundp ob slot)))
-                  instances)))
-      (if object
-         (slot-value object slot)
-         default)));)
+     (boundp :reader slot-definition-boundp :initarg :boundp)))
 
+  (defclass direct-special-slot-definition (standard-direct-slot-definition)
+    ())
   
+  (defclass effective-special-slot-definition (standard-effective-slot-definition)
+    ()))
+
+(defvar *unbound-marker* (gensym "UNBOUND-MARKER-"))
+
+(defun most-specific-slot-value (instances slot &optional (default *unbound-marker*))
+  (let ((object (find-if
+                #'(lambda (ob)
+                    (and (slot-exists-p ob slot) (slot-boundp ob slot)))
+                instances)))
+    (if object
+       (slot-value object slot)
+      default)))
+
+(defmethod initialize-instance ((slotd effective-special-slot-definition) &rest initargs)
+  (declare (ignore initargs))
+  (call-next-method)
+  (setf (slot-value slotd 'allocation) :instance))
+
 
 (defmethod direct-slot-definition-class ((class virtual-slots-class) &rest initargs)
-  (if (eq (getf initargs :allocation) :virtual)
-      (find-class 'direct-virtual-slot-definition)
-    (call-next-method)))
+  (case (getf initargs :allocation)
+    (:virtual (find-class 'direct-virtual-slot-definition))
+    (:special (find-class 'direct-special-slot-definition))
+    (t (call-next-method))))
 
 (defmethod effective-slot-definition-class ((class virtual-slots-class) &rest initargs)
-  (if (eq (getf initargs :allocation) :virtual)
-      (find-class 'effective-virtual-slot-definition)
-    (call-next-method)))
+  (case (getf initargs :allocation)
+    (:virtual (find-class 'effective-virtual-slot-definition))
+    (:special (find-class 'effective-special-slot-definition))
+    (t (call-next-method))))
 
 
 (defmethod initialize-internal-slot-functions ((slotd effective-virtual-slot-definition))
@@ -226,15 +237,19 @@ (defmethod validate-superclass
 (internal *instance-cache*)
 (defvar *instance-cache* (make-hash-table :test #'eql))
 
-(defun cache-instance (instance)
+(defun cache-instance (instance &optional (weak-ref t))
   (setf
    (gethash (sap-int (proxy-location instance)) *instance-cache*)
-   (make-weak-pointer instance)))
+   (if weak-ref
+       (make-weak-pointer instance)
+     instance)))
 
 (defun find-cached-instance (location)
   (let ((ref (gethash (sap-int location) *instance-cache*)))
     (when ref
-      (weak-pointer-value ref))))
+      (if (weak-pointer-p ref)
+         (weak-pointer-value ref)
+       ref))))
 
 (defun instance-cached-p (location)
   (gethash (sap-int location) *instance-cache*))
@@ -243,11 +258,11 @@ (defun remove-cached-instance (location)
   (remhash (sap-int location) *instance-cache*))
 
 ;; For debuging
-(defun cached-instances ()
+(defun list-cached-instances ()
   (let ((instances ()))
     (maphash #'(lambda (location ref)
                 (declare (ignore location))
-                (push (weak-pointer-value ref) instances))
+                (push ref instances))
             *instance-cache*)
     instances))
                        
@@ -256,9 +271,9 @@ (defun cached-instances ()
 ;;;; Proxy for alien instances
 
 (defclass proxy ()
-  ((location :reader proxy-location :type system-area-pointer)))
+  ((location :allocation :special :reader proxy-location :type system-area-pointer))
+  (:metaclass virtual-slots-class))
 
-(defgeneric initialize-proxy (object &rest initargs))
 (defgeneric instance-finalizer (object))
 (defgeneric reference-foreign (class location))
 (defgeneric unreference-foreign (class location))
@@ -338,7 +353,7 @@   (defmethod shared-initialize ((class proxy-class) names &key size)
   
   (defmethod direct-slot-definition-class ((class proxy-class) &rest initargs)
     (case (getf initargs :allocation)
-      ((nil :alien) (find-class 'direct-alien-slot-definition))
+      (:alien (find-class 'direct-alien-slot-definition))
       (t (call-next-method))))
   
   (defmethod effective-slot-definition-class ((class proxy-class) &rest initargs)
@@ -521,6 +536,11 @@ (defmethod initialize-instance ((struct struct) &rest initargs)
 (defclass struct-class (proxy-class)
   ())
 
+(defmethod direct-slot-definition-class ((class struct-class) &rest initargs)
+  (if (not (getf initargs :allocation))
+      (find-class 'direct-alien-slot-definition)
+    (call-next-method)))
+
 (defmethod reference-foreign ((class struct-class) location)
   (copy-memory location (proxy-instance-size class)))