> - let's suppose to have an event (a lambda) registered to an opened file. The
> fileevent will continue to call the lambda even if the eof was reached.
> I know I can check the eof in the lambda, but how much time the function
> takes?
Testing for eof shouldn't significantly slow you down (provided you delete
the fileevent handler once you get eof, so it doesn't keep on uselessly
calling your lambda forever). It's just a few added statements every time
you go through a loop.
I don't know how you would do it if you're reading with read-line or
read, but if you're using read-char, the following code would be
reasonable in a callback:
(let loop ((c (read-char f)))
(if (eof-object? c)
(begin
;;; ... code to do any necessary cleanup goes here ...
;;; ... and then:
(fileevent f 'readable ""))
(begin
;;; ... code to do the real work goes here ...
;;; ... and then:
(if (char-ready? f)
(loop (read-char f))))))
The extra eof-object? each time through the loop is pretty insignificant;
the cleanup section lets you do things like remove windows related to
file reading (e.g., a "stop" button); and the call to fileevent ensures
that the callback won't be called any more times than needed.
If you're doing character-by-character input, you _can_ get a significant
speed increase by coding in C a function that simply returns _all_ the
characters waiting to be read on a given input port. Just moving the read
loop into C sped my program up quite a bit, and it could be rewritten for
still more efficiency by peeking at buffer structures and such. My
read-ready function is in
<
ftp://kaolin.unice.fr/pub/Incoming/callbacks-0.1.tar.gz>
somewhere. (The main point of the callbacks package was to provide
exactly what fileevent does for input ports.)
> - let's suppose the lambda is a general purpose function that does not know
> which is the calling file trigger. It could be a great improvement to
> provide the lambda the fileid (using a lambda parameter). I know this is
> not compatible with the Tk, but...
This is simple enough to accomplish without changing fileevent:
(define (general-purpose-callback f)
;;; read from f and do appropriate things
)
(define (attach-general-purpose-callback-to f)
(fileevent f 'readable (lambda () (general-purpose-callback f))))
... i.e., for the fileevent script, just use a closure that captures
the appropriate input port in its environment, and then calls your
general-purpose function with that argument. This keeps the Tk
compatibility, and I think feels more scheme-like than having fileevent
call back with an argument. If you want, though, you can redefine
fileevent to accomplish what you want:
(define fileevent
(let ((old-fileevent fileevent))
(lambda (file mode . script)
(if (and (pair? script) (procedure? (car script)))
(old-fileevent file mode (lambda () ((car script) file)))
(apply old-fileevent file mode script)))))
This will work just like fileevent, but you give it callbacks that
take a file as argument: (fileevent f 'readable general-purpose-callback).
All the code in this message is untested, but it should work with minimal
tweaking. Apologies if these responses aren't helpful.
Received on Wed Nov 15 1995 - 20:22:57 CET