git.fiddlerwoaroof.com
event-loop.lisp
f013defe
 (in-package :fwoar.event-loop)
 
 (defgeneric run (task event-loop)
   (:method :around (task event-loop)
     (bb:with-promise (resolve reject)
       (enqueue (queue event-loop)
                (lambda ()
                  (handler-case (resolve (call-next-method))
                    (serious-condition (c)
                      (reject c))))))))
 
 
 (defgeneric enqueue (queue fn))
 
 (defgeneric prepare-loop (event-loop)
   (:method (event-loop)
     (declare (ignore event-loop))))
 
c91ca263
 (defgeneric cleanup (event-loop)
   (:method (event-loop)
     (declare (ignore event-loop))))
 
f013defe
 (defgeneric queue (event-loop))
 
4c75f56d
 (defgeneric (setf finish-cb) (cb event-loop))
 (defgeneric finish-cb (event-loop))
f013defe
 
4c75f56d
 (defgeneric tick (event-loop)
   (:method :around (event-loop)
     (call-next-method)))
f013defe
 
 (defparameter *task-depth* 10)
 
c91ca263
 (defmacro until-finished (finished-var &body body)
   `(loop until ,finished-var do
          ,@body))
 
f013defe
 (defun run-loop (event-loop)
   (let ((finished nil))
4c75f56d
     (setf (finish-cb event-loop)
           (lambda ()
             (setf finished t)))
f013defe
     (prepare-loop event-loop)
c91ca263
     (unwind-protect (until-finished finished
4c75f56d
                       (with-simple-restart (continue "continue event loop")
                         (tick event-loop)))
       (format t "unwinding...")
c91ca263
       (cleanup event-loop))))
f013defe
 
 (defun wait-for-promise (promise)
   (let* ((result-queue (make-instance 'chanl:bounded-channel)))
     (bb:alet ((v promise))
       (chanl:send result-queue v))
     (loop
       (return (chanl:recv result-queue)))))