1 (import srfi-69 matchable)
3 (define trace-enabled #f)
9 (define actor-table (make-hash-table))
11 (define (make-actor-with-address address behaviour)
12 (hash-table-set! actor-table address behaviour)
15 (define next-actor-address 1)
17 (define (make-actor behaviour)
18 (make-actor-with-address next-actor-address behaviour)
19 (let ((address next-actor-address))
20 (set! next-actor-address (+ next-actor-address 1))
27 (define (dispatch-message address message)
29 (print "Dispatching message " message " to " address))
30 (let ((behaviour (hash-table-ref/default actor-table address '())))
32 (print "Warning: discarded message " message " to unknown actor " address)
33 (let ((value (apply behaviour (cons address message))))
36 ((done) (hash-table-delete! actor-table address))
39 (print "Updating behaviour of " address))
40 (hash-table-set! actor-table address value)))))))
43 ;;; FIFO queue implementation
47 (define (cell val prev next)
50 (define cell-prev cadr)
51 (define cell-next caddr)
52 (define (set-cell-prev! cell prev-cell)
53 (set-car! (cdr cell) prev-cell))
54 (define (set-cell-next! cell next-cell)
55 (set-car! (cddr cell) next-cell))
61 ((empty?) (null? head))
62 ((push) (if (not (= (length args) 1))
63 (error "Wrong number of arguments to push.")
64 (if (not (null? head))
65 (let ((old-head head))
66 (set! head (cell (car args) '() old-head))
67 (set-cell-prev! old-head head))
70 (set! head (cell (car args) '() '()))
72 ((pop) (if (not (= (length args) 0))
73 (error "Wrong number of arguments to pop.")
76 (let ((old-tail tail))
77 (set! tail (cell-prev old-tail))
80 (set-cell-next! tail '()))
81 (cell-val old-tail)))))))))
83 (define (fifo-push fifo x)
86 (define (fifo-pop fifo)
89 (define (fifo-empty? fifo)
97 (define message-queue (make-fifo))
99 (define (next-addressed-msg)
100 (if (fifo-empty? message-queue)
102 (fifo-pop message-queue)))
104 (define (send-message actor . message)
106 (print "Queued message " message " to " actor))
107 (fifo-push message-queue (cons actor message)))
109 (define (process-next-message)
110 (let ((addressed-msg (next-addressed-msg)))
111 (if (null? addressed-msg)
113 (let ((address (car addressed-msg))
114 (message (cdr addressed-msg)))
115 (dispatch-message address message)))))
118 (unless (null? (process-next-message))
121 (define (send-and-run actor . message)
122 (apply send-message (cons actor message))