async-input-port added by klm` on Sun Feb 19 11:59:04 2012


;; using continuations to allow program-state
;; to 'buffer' input instead of manual buffering

(define-record async-input-port input-port continuation)


(define (new-async-input-port input-port proc)
  (define new-aip (make-async-input-port input-port #f))
  (define reset-proc
    (lambda (ret)
      (begin
        (let [(final-return-value (proc))]
          (async-input-port-continuation-set! new-aip reset-proc)
          final-return-value))))
  (async-input-port-continuation-set! new-aip
                                      reset-proc)
  new-aip)

;; 
(define (read-async-input-port async-input-port)
  (assert (async-input-port? async-input-port))
  (assert (procedure? (async-input-port-continuation async-input-port)))

  (call/cc
   (lambda (return)
     (let* [(my-read
             (lambda ()
               (print "enter read")
               (call/cc
                (lambda (cc) (async-input-port-continuation-set! async-input-port cc)))
               (print "cc saved")
               (if (char-ready? (async-input-port-input-port async-input-port))
                   (read-char i)
                   (return #f )))) ; not ready jet
            
            (my-ready (lambda () (char-ready? i)))
            (my-close (lambda () (close-input-port i)))
            (p (make-input-port
                my-read
                my-ready
                my-close))]
       (with-input-from-port p
         (lambda () 
           ((async-input-port-continuation async-input-port) #f) ))))))

(define aip (new-async-input-port i (lambda () (read))))

; will not block! returns #f is still waiting, otherwise returns what lambda above returns(read)
(read-async-input-port
 aip)