[plt-scheme] handling user-breaks in MrEd app...
At Wed, 30 Oct 2002 17:58:45 -0600, Jefferson Provost wrote:
> I'm writing a graphical MrEd app, and though most interaction will be
> through graphical objects, I want to run a repl for debugging and other
> stuff. I don't want to use MrEd's graphical repl, but when I do mred
> -z, the stdio repl never yields to give events/time to my graphical
> objects.
If you have some aversion to DrScheme, use -z and evaluate
(current-eventspace (make-eventspace))
to make the a GUI handler thread that is separate from the REPL thread.
> My solution is to instantiate my graphical objects, and then
> run a stdio repl in a separate, as in the code below.
> [...]
> (define (gui-repl)
> (let ((t (thread read-eval-print-loop)))
> (let loop ()
> (yield)
> (sleep 0.01)
> (if (thread-running? t) (loop)))))
If you keep this, here's a way to avoid polling:
(define (gui-repl)
(let ((t (thread read-eval-print-loop))
(s (make-semaphore)))
(thread (lambda () (thread-wait t) (semaphore-post s)))
(yield s)))
Hm... I should change `yield' so that it works on an arbitrary waitable
(such as a thread), and then the extra thread and semaphore won't be
necessary.
> The problem is that the with-handlers form seems to swallow all
> exceptions (other than exn:break) without any notification. Without the
> with-handlers, breaks (ctrl-C's) send the program into some inscrutable
> state in which there's still a repl running (the top-level repl?) but
> the program is basically unusable.
The disappearing exceptions is an unfortunate interaction between
`with-handlers' and `yield'. See section 2.4.4 in the MrEd manual for
details, but the short answer is that using `(current-eventspace
(make-eventspace))' will solve the problem.
Matthew