;; 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.5 2006/09/29 13:14:19 espen Exp $
+;; $Id: proxy.lisp,v 1.10 2007/12/11 14:26:11 espen Exp $
(in-package "GFFI")
(defvar *foreign-instance-locations*
(make-hash-table #+clisp :weak #+sbcl :weakness :key))
-;; TODO: add a ref-counted-proxy subclass
+
(eval-when (:compile-toplevel :load-toplevel :execute)
(defclass proxy (virtual-slots-object)
(#?-(or (sbcl>= 0 9 17) (featurep :clisp))(%location :special t :type pointer))
;; :FINALZIE given to MAKE-PROXY-INSTANCE or non NIL if the proxy was
;; created with MAKE-INSTANCE
(defmethod invalidate-instance ((instance proxy) &optional finalize-p)
+ #+clisp(declare (ignore finalize-p))
(remove-cached-instance (foreign-location instance))
#+(or sbcl cmu)
(progn
#'(lambda (value object)
(unless writer
(setq writer (mkbinding setter nil 'pointer type)))
+ ;; First argument in foreign setters is the object and second
+ ;; is value
(funcall writer (foreign-location object) value)))
(call-next-method)))
(cache-instance instance)
instance))
+;;;; Superclass for ref-counted objects
+
+(defclass ref-counted-object (proxy)
+ ()
+ (:metaclass proxy-class))
+
+(define-type-method from-alien-form ((type ref-counted-object) form
+ &key (ref :copy))
+ (call-next-method type form :ref ref))
+
+(define-type-method from-alien-function ((type ref-counted-object)
+ &key (ref :copy))
+ (call-next-method type :ref ref))
+
;;;; Superclasses for wrapping of C structures
(define-type-method callback-wrapper ((type struct) var arg form)
(let ((class (type-expand type)))
- `(let ((,var (ensure-proxy-instance ',class ,arg :finalize nil)))
+ `(let ((,var (ensure-proxy-instance ',class ,arg :reference nil :finalize nil)))
(unwind-protect
,form
(invalidate-instance ,var)))))