[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: catch-cancel
Although I can't tell you exactly where the mysterious and
omnipresent CATCH-CANCEL sits, I can suggest a way to avoid
the problem in general.
Rather than using CATCH/THROW (and kin) with their dynamic
tags, use BLOCK/RETURN-FROM. These are lexically scoped
and a lot less prone to funny interactions with other code.
Below is a simple example how to interrupt a process with a
button action using BLOCK/RETURN-FROM.
;;; Implementation notes:
;;;
;;; 1. The window created is initially hidden, so that the cancel
;;; button can't be clicked until after the UNWIND-PROTECT
;;; starts.
;;; 2. The BLOCK is not really needed here. We could just say
;;; (RETURN-FROM TEST-CANCEL ...).
;;; 3. For maintenance and generality, I deliberately set things
;;; up so that the example-specific return values (:CANCELLED
;;; and :FINISHED) appear in the same place (the calling function).
(defun test-cancel ()
(block search-loop
(let ((w (make-button-window
#'(lambda (dialog-item)
(declare (ignore dialog-item))
(return-from search-loop :cancelled)))))
(unwind-protect
(progn (window-show w)
(dotimes (i 200 :finished) ;; standing in for a real search
(princ ".")))
(window-close w)))))
(defun make-button-window (exit-fn)
(make-instance 'window
:window-show nil
:view-position :centered
:view-size #@(100 100)
:view-subviews (list (make-cancel-button exit-fn))))
(defun make-cancel-button (exit-fn)
(make-dialog-item 'button-dialog-item
#@(20 30) #@(60 20)
"Cancel"
exit-fn))
--
Chris