X-Git-Url: https://git.distorted.org.uk/~mdw/clg/blobdiff_plain/3d36c5d66c327143ac12c3c2222352618da3123c..bba7e2d90c17a0bdb8f7c3519faa595bb9cb85f3:/glib/proxy.lisp diff --git a/glib/proxy.lisp b/glib/proxy.lisp index 83a4a99..3a27b33 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.19 2005/02/03 23:09:04 espen Exp $ +;; $Id: proxy.lisp,v 1.23 2006/02/02 22:35:14 espen Exp $ (in-package "GLIB") @@ -35,31 +40,42 @@ ((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)) @@ -221,15 +237,19 @@ (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*)) @@ -238,11 +258,11 @@ (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)) @@ -251,9 +271,9 @@ ;;;; 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)) @@ -333,7 +353,7 @@ (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) @@ -516,6 +536,11 @@ (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))) @@ -533,3 +558,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)