X-Git-Url: https://git.distorted.org.uk/~mdw/clg/blobdiff_plain/3b16765261486cdcd536d770fed5e2f091897a0d..177abaa0c3347e6de9389348cbb06cfe2cc3aa11:/glib/proxy.lisp diff --git a/glib/proxy.lisp b/glib/proxy.lisp index ef1a9b9..fe17afd 100644 --- a/glib/proxy.lisp +++ b/glib/proxy.lisp @@ -1,21 +1,26 @@ -;; Common Lisp bindings for GTK+ v2.0 -;; Copyright (C) 2000 Espen S. Johnsen +;; Common Lisp bindings for GTK+ v2.x +;; Copyright 2000-2005 Espen S. Johnsen ;; -;; This library is free software; you can redistribute it and/or -;; modify it under the terms of the GNU Lesser General Public -;; License as published by the Free Software Foundation; either -;; version 2 of the License, or (at your option) any later version. +;; Permission is hereby granted, free of charge, to any person obtaining +;; a copy of this software and associated documentation files (the +;; "Software"), to deal in the Software without restriction, including +;; without limitation the rights to use, copy, modify, merge, publish, +;; distribute, sublicense, and/or sell copies of the Software, and to +;; permit persons to whom the Software is furnished to do so, subject to +;; the following conditions: ;; -;; This library is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; Lesser General Public License for more details. +;; The above copyright notice and this permission notice shall be +;; included in all copies or substantial portions of the Software. ;; -;; You should have received a copy of the GNU Lesser General Public -;; License along with this library; if not, write to the Free Software -;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +;; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +;; CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +;; 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.16 2004-12-19 23:33:57 espen Exp $ +;; $Id: proxy.lisp,v 1.21 2005-04-24 13:26:40 espen Exp $ (in-package "GLIB") @@ -35,7 +40,7 @@ ((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))) + (boundp :reader slot-definition-boundp :initarg :boundp)))) (defvar *unbound-marker* (gensym "UNBOUND-MARKER-")) @@ -47,7 +52,7 @@ instances))) (if object (slot-value object slot) - default)))) + default)));) @@ -84,23 +89,20 @@ (setf (slot-value slotd 'reader-function) #'(lambda (object) (unless reader - (setq reader - (mkbinding getter - (slot-definition-type slotd) 'pointer))) + (setq reader + (mkbinding getter + (slot-definition-type slotd) 'pointer))) (funcall reader (proxy-location object)))))))))) (setf (slot-value slotd 'boundp-function) (cond - ((and - (not (slot-boundp slotd 'unbound)) - (not (slot-boundp slotd 'boundp))) - #'(lambda (object) (declare (ignore object)) t)) ((slot-boundp slotd 'unbound) (let ((unbound-value (slot-value slotd 'unbound))) - (lambda (object) - (not (eq (funcall getter-function object) unbound-value))))) - ((let ((boundp (slot-value slotd 'boundp))) + #'(lambda (object) + (not (eq (funcall getter-function object) unbound-value))))) + ((slot-boundp slotd 'boundp) + (let ((boundp (slot-value slotd 'boundp))) (etypecase boundp (function boundp) (symbol #'(lambda (object) @@ -111,7 +113,13 @@ (setq reader (mkbinding boundp (slot-definition-type slotd) 'pointer))) - (funcall reader (proxy-location object)))))))))) + (funcall reader (proxy-location object)))))))) + ((multiple-value-bind (unbound-p unbound-value) + (unbound-value (slot-definition-type slotd)) + (when unbound-p + #'(lambda (object) + (not (eq (funcall getter-function object) unbound-value)))))) + (#'(lambda (object) (declare (ignore object)) t)))) (setf (slot-value slotd 'reader-function) @@ -119,17 +127,26 @@ ((slot-boundp slotd 'unbound) (let ((unbound (slot-value slotd 'unbound)) (slot-name (slot-definition-name slotd))) - (lambda (object) - (let ((value (funcall getter-function object))) - (if (eq value unbound) - (slot-unbound (class-of object) object slot-name) - value))))) + #'(lambda (object) + (let ((value (funcall getter-function object))) + (if (eq value unbound) + (slot-unbound (class-of object) object slot-name) + value))))) ((slot-boundp slotd 'boundp) (let ((boundp-function (slot-value slotd 'boundp-function))) - (lambda (object) - (and - (funcall boundp-function object) - (funcall getter-function object))))) + #'(lambda (object) + (and + (funcall boundp-function object) + (funcall getter-function object))))) + ((multiple-value-bind (unbound-p unbound-value) + (unbound-value (slot-definition-type slotd)) + (let ((slot-name (slot-definition-name slotd))) + (when unbound-p + #'(lambda (object) + (let ((value (funcall getter-function object))) + (if (eq value unbound-value) + (slot-unbound (class-of object) object slot-name) + value))))))) (getter-function))))) (setf @@ -211,26 +228,26 @@ (defun cache-instance (instance) (setf - (gethash (system:sap-int (proxy-location instance)) *instance-cache*) - (ext:make-weak-pointer instance))) + (gethash (sap-int (proxy-location instance)) *instance-cache*) + (make-weak-pointer instance))) (defun find-cached-instance (location) - (let ((ref (gethash (system:sap-int location) *instance-cache*))) + (let ((ref (gethash (sap-int location) *instance-cache*))) (when ref - (ext:weak-pointer-value ref)))) + (weak-pointer-value ref)))) (defun instance-cached-p (location) - (gethash (system:sap-int location) *instance-cache*)) + (gethash (sap-int location) *instance-cache*)) (defun remove-cached-instance (location) - (remhash (system:sap-int location) *instance-cache*)) + (remhash (sap-int location) *instance-cache*)) ;; For debuging (defun cached-instances () (let ((instances ())) (maphash #'(lambda (location ref) (declare (ignore location)) - (push (ext:weak-pointer-value ref) instances)) + (push (weak-pointer-value ref) instances)) *instance-cache*) instances)) @@ -271,7 +288,7 @@ (setf (slot-value instance 'location) location) (call-next-method)) (cache-instance instance) - (ext:finalize instance (instance-finalizer instance)) + (finalize instance (instance-finalizer instance)) instance) (defmethod instance-finalizer ((instance proxy)) @@ -286,6 +303,10 @@ ;;;; Metaclass used for subclasses of proxy +(defgeneric most-specific-proxy-superclass (class)) +(defgeneric direct-proxy-superclass (class)) + + (eval-when (:compile-toplevel :load-toplevel :execute) (defclass proxy-class (virtual-slots-class) ((size :reader proxy-instance-size))) @@ -297,13 +318,12 @@ (defclass effective-alien-slot-definition (effective-virtual-slot-definition) ((offset :reader slot-definition-offset :initarg :offset))) - (defmethod most-specific-proxy-superclass ((class proxy-class)) (find-if #'(lambda (class) (subtypep (class-name class) 'proxy)) (cdr (compute-class-precedence-list class)))) - + (defmethod direct-proxy-superclass ((class proxy-class)) (find-if #'(lambda (class) @@ -390,6 +410,9 @@ (defmethod proxy-instance-size (class) (declare (ignore class)) 0) + + (defmethod proxy-instance-size ((class-name symbol)) + (proxy-instance-size (find-class class-name))) ) (defmethod alien-type ((class proxy-class) &rest args) @@ -433,7 +456,7 @@ `(reference-foreign ',(class-name class) (proxy-location ,instance))) (defmethod copy-to-alien-function ((class proxy-class) &rest args) - (declare (ignore class args)) + (declare (ignore args)) #'(lambda (instance) (reference-foreign class (proxy-location instance)))) @@ -457,6 +480,9 @@ #'(lambda (location &optional (offset 0)) (unreference-foreign class (sap-ref-sap location offset)))) +(defmethod unbound-value ((class proxy-class) &rest args) + (declare (ignore args)) + (values t nil)) (defgeneric ensure-proxy-instance (class location) (:documentation "Returns a proxy object representing the foreign object at the give location.")) @@ -486,7 +512,7 @@ (let ((size (proxy-instance-size (class-of struct)))) (if (zerop size) (error "~A has zero size" (class-of struct)) - (setf (slot-value struct 'location) (allocate-memory size))))) + (setf (slot-value struct 'location) (allocate-memory size))))) (call-next-method)) @@ -512,3 +538,24 @@ (defmethod unreference-foreign ((class static-struct-class) location) (declare (ignore class location)) nil) + + +;;; Pseudo type for structs which are inlined in other objects + +(defmethod size-of ((type (eql 'inlined)) &rest args) + (declare (ignore type)) + (proxy-instance-size (first args))) + +(defmethod reader-function ((type (eql 'inlined)) &rest args) + (declare (ignore type)) + (destructuring-bind (class) args + #'(lambda (location &optional (offset 0)) + (ensure-proxy-instance class + (reference-foreign class (sap+ location offset)))))) + +(defmethod destroy-function ((type (eql 'inlined)) &rest args) + (declare (ignore args)) + #'(lambda (location &optional (offset 0)) + (declare (ignore location offset)))) + +(export 'inlined)