;;; Coderacks are lists of procedures, each of two arguments (connection, rack)
;;; The first codelet on a coderack is always executed first
;;; Codelets may also be continuations, application hooks, or entities
;; maximum number of codelets in a coderack
(define max-coderack-size 1000)
;; create a new coderack
(define (make-coderack)
(cons 0 nil))
;; add a codelet to the front of the coderack
;; if no room deletes a random codelet
(define (add-codelet-front proc rack)
(if (< (car rack) max-coderack-size)
(set-car! rack (inc (car rack)))
(remove-codelet (random max-codelet-size)))
(set-cdr! rack (cons proc (cdr rack))))
;; add a codelet randomly into the queue
;; if no room, replaces a random codelet
(define (add-codelet-rand proc rack)
(define (add-in n crack)
(if (= n 0)
(set-cdr! crack (cons proc (cdr rack)))
(add-in (dec n) (cdr crack))))
(define (replace-in n crack)
(if (= n 0)
(if (null? crack)
(set-cdr! crack (cons proc nil))
(set-car! (cdr crack) proc))
(replace-in (dec n) (cdr crack))))
(let ((prevn (car rack)))
(if (< prevn max-coderack-size)
(begin
(set-car! rack (inc prevn))
(add-in (random prevn) rack))
(replace-in (random prevn) rack))))
;; adds a codelet further back based on a probability of being near the front
;; if no room, removes the last codelet
(define (add-codelet-prob proc prob rack)
(define (helper crack)
(if (or (< (random 1.0) prob) (null? (cdr crack)))
(if (< (car rack) max-coderack-size)
(set-cdr! crack (cons proc (cdr crack)))
(if (not (null? (cdr crack)))
(set-cdr! crack (cons proc (cdr crack)))
(except-last-pair! (cdr crack))))
(helper (cdr crack) after)))
(helper rack))
;; Remove the nth codelet
(define (remove-codelet n rack)
(if (not (null? (cdr rack)))
(if (= n 0)
(set-cdr! rack (cddr rack))
(remove-codelet (dec n) (cdr rack)))))
;; First remove codelet, then execute
(define (execute-codelet c rack)
(if (null? (cdr rack))
nil
(let ((codelet (cadr rack)))
(set-cdr! rack (cddr rack))
(codelet c))))
;; Useful codelets
;; executes for codelets that were not added as "front-most"
(define (make-not-urgent-codelet proc)
(lambda (c rack)
(proc c rack)
(execute-codelet c rack)
(add-codelet-front not-urgent-codelet rack)))