2012-01-11 21:19:06 +00:00
|
|
|
#lang racket/base
|
|
|
|
|
|
|
|
(require racket/port)
|
|
|
|
(require "os-userland.rkt")
|
|
|
|
|
|
|
|
(define (rpc req)
|
|
|
|
(define reply-addr (gensym 'reply-addr)) ;;; !!! TODO: remove side-effect?
|
|
|
|
(send `(request ,reply-addr ,req))
|
|
|
|
(wait (message-handlers
|
|
|
|
[`(reply ,(? (lambda (v) (eq? v reply-addr))) ,v)
|
|
|
|
v])))
|
|
|
|
|
|
|
|
(define-syntax rpc-service
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ pattern body ...)
|
|
|
|
(let loop ()
|
|
|
|
(wait (message-handlers
|
|
|
|
[`(request ,reply-addr ,pattern)
|
|
|
|
(spawn (lambda ()
|
2012-01-11 21:38:53 +00:00
|
|
|
(define answer (let () body ...))
|
2012-01-11 21:19:06 +00:00
|
|
|
(send `(reply ,reply-addr ,answer))))
|
|
|
|
(loop)])))]))
|
|
|
|
|
|
|
|
(define (display-driver)
|
|
|
|
(define message (wait (message-handlers [`(display ,message) message])))
|
|
|
|
(meta-send (lambda ()
|
|
|
|
(display message)
|
|
|
|
(flush-output)))
|
|
|
|
(display-driver))
|
|
|
|
|
|
|
|
(define (read-line-driver)
|
|
|
|
(rpc-service `read-line
|
|
|
|
(wait (message-handlers)
|
|
|
|
(meta-message-handlers
|
|
|
|
[((read-line-evt (current-input-port) 'any) => line)
|
|
|
|
line]))))
|
|
|
|
|
|
|
|
(define (time-evt msecs)
|
|
|
|
(wrap-evt (alarm-evt msecs) (lambda (_) (current-inexact-milliseconds))))
|
|
|
|
|
|
|
|
(define (wait-until-time msecs)
|
|
|
|
(wait (message-handlers)
|
|
|
|
(meta-message-handlers
|
|
|
|
[((time-evt msecs) => current-time)
|
|
|
|
current-time])))
|
|
|
|
|
|
|
|
(define (current-time)
|
|
|
|
(wait-until-time 0))
|
|
|
|
|
|
|
|
(define (sleep-driver)
|
|
|
|
(rpc-service `(sleep ,msecs)
|
|
|
|
(send `(display (Sleeping ,msecs)))
|
2012-01-11 21:38:53 +00:00
|
|
|
(define now (wait-until-time (+ (current-time) msecs)))
|
|
|
|
(send `(display "\n"))
|
|
|
|
now))
|
2012-01-11 21:19:06 +00:00
|
|
|
|
|
|
|
(define (main)
|
|
|
|
(spawn display-driver)
|
|
|
|
(spawn read-line-driver)
|
|
|
|
(spawn sleep-driver)
|
|
|
|
(spawn (lambda ()
|
|
|
|
(send `(display "HI\n"))
|
|
|
|
(rpc `(sleep 1000))
|
|
|
|
(send `(display "THERE\n"))))
|
2012-01-11 21:20:28 +00:00
|
|
|
(poll) ;; Wait for drivers to become ready (!)
|
|
|
|
;; The Right Way to do this is to have presence integrated with subscription
|
2012-01-11 21:19:06 +00:00
|
|
|
(send `(display "Hello! Enter your name:\n"))
|
|
|
|
(define name (rpc 'read-line))
|
|
|
|
(send `(display "Hello, "))
|
|
|
|
(send `(display ,name))
|
|
|
|
(send `(display "!\n"))
|
|
|
|
(rpc `(sleep 1000))
|
|
|
|
(send `(display "Goodbye\n")))
|
|
|
|
|
2012-01-11 21:25:40 +00:00
|
|
|
(ground-vm/userland (lambda (p m) (p m)) ;; pattern-predicate
|
|
|
|
main)
|