[gsharp-cvs] CVS update: gsharp/Flexichain/flexicursor.lisp gsharp/Flexichain/utilities.lisp
Timothy Moore
tmoore at common-lisp.net
Fri Jan 14 16:12:43 UTC 2005
Update of /project/gsharp/cvsroot/gsharp/Flexichain
In directory common-lisp.net:/tmp/cvs-serv18364
Modified Files:
flexicursor.lisp utilities.lisp
Log Message:
Generalized weak pointer support and added an implementation for OpenMCL.
Date: Fri Jan 14 17:12:42 2005
Author: tmoore
Index: gsharp/Flexichain/flexicursor.lisp
diff -u gsharp/Flexichain/flexicursor.lisp:1.9 gsharp/Flexichain/flexicursor.lisp:1.10
--- gsharp/Flexichain/flexicursor.lisp:1.9 Mon Jan 3 07:44:42 2005
+++ gsharp/Flexichain/flexicursor.lisp Fri Jan 14 17:12:41 2005
@@ -96,18 +96,11 @@
(defgeneric (setf element>) (object cursor)
(:documentation "Replaces the element immediately after the cursor."))
-(defclass standard-cursorchain (cursorchain standard-flexichain)
+(defclass standard-cursorchain
+ (weak-pointer-container-mixin cursorchain standard-flexichain)
((cursors :initform '()))
(:documentation "The standard instantiable subclass of CURSORCHAIN"))
-(defun make-wp (value)
- #+sbcl (sb-ext:make-weak-pointer value)
- #+cmu (ext:make-weak-pointer value))
-
-(defun wp-value (wp)
- #+sbcl (sb-ext:weak-pointer-value wp)
- #+cmu (ext:weak-pointer-value wp))
-
(defclass standard-flexicursor (flexicursor)
((chain :reader chain :initarg :chain)
(index :accessor flexicursor-index))
@@ -123,7 +116,7 @@
(with-slots (index chain) cursor
(setf index (position-index chain (1- position)))
(with-slots (cursors) chain
- (push (make-wp cursor) cursors))))
+ (push (make-weak-pointer cursor chain) cursors))))
(defmethod initialize-instance :after ((cursor right-sticky-flexicursor)
&rest initargs &key (position 0))
@@ -131,30 +124,32 @@
(with-slots (index chain) cursor
(setf index (position-index chain position))
(with-slots (cursors) chain
- (push (make-wp cursor) cursors))))
+ (push (make-weak-pointer cursor chain) cursors))))
-(defun adjust-cursors (cursors start end increment)
+(defun adjust-cursors (chain cursors start end increment)
(let ((acc '()))
- (loop while cursors
- do (cond ((null (wp-value (car cursors)))
- (pop cursors))
- ((<= start (flexicursor-index (wp-value (car cursors))) end)
- (incf (flexicursor-index (wp-value (car cursors))) increment)
+ (loop
+ for cursor = (and cursors (weak-pointer-value (car cursors) chain))
+ while cursors
+ do (cond ((null cursor)
+ (pop cursors))
+ ((<= start (flexicursor-index cursor) end)
+ (incf (flexicursor-index cursor) increment)
(let ((rest (cdr cursors)))
(setf (cdr cursors) acc
acc cursors
cursors rest)))
- (t
- (let ((rest (cdr cursors)))
- (setf (cdr cursors) acc
- acc cursors
- cursors rest)))))
+ (t
+ (let ((rest (cdr cursors)))
+ (setf (cdr cursors) acc
+ acc cursors
+ cursors rest)))))
acc))
(defmethod move-elements :after ((cc standard-cursorchain) to from start1 start2 end2)
(declare (ignore to from))
(with-slots (cursors) cc
- (setf cursors (adjust-cursors cursors start2 (1- end2) (- start1 start2)))))
+ (setf cursors (adjust-cursors cc cursors start2 (1- end2) (- start1 start2)))))
(defmethod clone-cursor ((cursor standard-flexicursor))
(make-instance (class-of cursor)
@@ -200,7 +195,7 @@
(with-slots (cursors) chain
(let* ((old-index (position-index chain position)))
(loop for cursor-wp in cursors
- as cursor = (wp-value cursor-wp)
+ as cursor = (weak-pointer-value cursor-wp chain)
when (and cursor (= old-index (flexicursor-index cursor)))
do (typecase cursor
(right-sticky-flexicursor (incf (cursor-pos cursor)))
Index: gsharp/Flexichain/utilities.lisp
diff -u gsharp/Flexichain/utilities.lisp:1.1 gsharp/Flexichain/utilities.lisp:1.2
--- gsharp/Flexichain/utilities.lisp:1.1 Sun Aug 1 17:27:19 2004
+++ gsharp/Flexichain/utilities.lisp Fri Jan 14 17:12:41 2005
@@ -34,17 +34,52 @@
(values nil nil)
(values (elt sequence position) t))))
-(defun make-weak-pointer (object)
- "Returns a weak pointer to OBJECT."
- #+cmu (extensions:make-weak-pointer object)
- #+sbcl (sb-ext:make-weak-pointer object)
- #-(or cmu sbcl) (error "MAKE-WEAK-POINTER not implemented."))
-
-(defun weak-pointer-value (weak-pointer)
- ;; TODO: check other CL implementations behavior wrt. return values
- "Returns the object pointed to by WEAK-POINTER or NIL if the pointer
-is broken."
+;;; CMUCL and SBCL have direct support for weak pointers. In OpenMCL weak
+;;; references are only supported via weak hash tables. This class provides
+;;; the means for other classes to manage their weak references.
+;;;
+;;; TODO: check other CL implementations behavior wrt. return values
+(defclass weak-pointer-container-mixin ()
+ #+openmcl
+ ((weak-hash :initform (make-hash-table :test #'eq :weak :value)))
+ (:documentation "Support for weak references, if needed"))
+
+(defgeneric make-weak-pointer (object container))
+
+#+(or sbcl cmu)
+(defmethod make-weak-pointer (object container)
+ (declare (ignore container))
+ #+cmu (extensions:make-weak-pointer object)
+ #+sbcl (sb-ext:make-weak-pointer object))
+
+#+openmcl
+(defmethod make-weak-pointer (object (container weak-pointer-container-mixin))
+ (let ((key (cons nil nil)))
+ (setf (gethash key (slot-value container 'weak-hash)) object)
+ key))
+
+(defgeneric weak-pointer-value (weak-pointer container))
+
+#+(or sbcl cmu)
+(defmethod weak-pointer-value (weak-pointer container)
+ (declare (ignore container))
#+cmu (extensions:weak-pointer-value weak-pointer)
- #+sbcl (sb-ext:weak-pointer-value weak-pointer)
- #-(or cmu sbcl) (error "WEAK-POINTER-VALUE not implemented."))
+ #+sbcl (sb-ext:weak-pointer-value weak-pointer))
+
+#+openmcl
+(defmethod weak-pointer-value
+ (weak-pointer (container weak-pointer-container-mixin))
+ (gethash weak-pointer (slot-value container 'weak-hash) nil))
+#-(or sbcl cmu openmcl)
+(progn
+ (eval-when (:evaluate :compile-toplevel :load-toplevel)
+ (warning "No support for weak pointers in this implementation. Things may
+get big and slow")
+ )
+ (defmethod make-weak-pointer (object container)
+ (declare (ignore container))
+ object)
+ (defmethod weak-pointer-value (weak-pointer container)
+ (declare (ignore container))
+ weak-pointer))
More information about the Gsharp-cvs
mailing list