X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/clg/blobdiff_plain/bde0b9062598a7e5d7360b0e6a0473c4e03404ba..e2ebafb115b201d38b16f2ee7064b8514ea6b2e3:/glib/proxy.lisp diff --git a/glib/proxy.lisp b/glib/proxy.lisp index fe17afd..927e539 100644 --- a/glib/proxy.lisp +++ b/glib/proxy.lisp @@ -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)))