;;; ******************************************************************** ;;; message.ss ;;; Susan Fox ;;; January 1, 2001 ;;; Contains the Message ADT, which gets messages that are posted to ;;; its stream, and provides them in a nice format to the rest of ;;; the program ;;; Requires utilities to be loaded (if (not (top-level-bound? 'UTIL.SSLOADED)) (load "util.ss")) ;;; Requires map in order to talk about locations (if (not (top-level-bound? 'MAP.SSLOADED)) (load "map.ss")) (define MESSAGE.SSLOADED #t) ;;; ******************************************************************** ;;; make-message takes a string associated with a message, ;;; a coordinate pair which specifies the goal location for ;;; delivery of the message, and two values, urgency and ;;; deadline, which is given for now as a number of ticks ;;; into the future (Should be made more sophisticated later) ;;; (define make-message (lambda (str loc urgency deadline) (list str loc urgency deadline))) ;;; Accessors (define mess-descrip car) (define mess-location cadr) (define mess-urgency caddr) (define mess-deadline cadddr) ;;; print-message prints a message in a pretty format ;;; (define print-message (lambda (mess) (printf "Message: ~s~n" (mess-descrip mess)) (printf "Deliver To: ") (print-location (mess-location mess)) (newline) (printf "Urgency: ~s~n" (mess-urgency mess)) (printf "Deadline: ~s~n" (mess-deadline mess)))) ;;; ******************************************************************** ;;; Messages are written by a separate process to the file messages.dat ;;; They are read by these operations, copied into messages.log ;;; and deleted from the file messages.dat for future (define semaphore-file "semaphore") (define log-file "messages.log") (define message-file "messages.dat") ;;; get-messages examines the file to see if it has anything in it. ;;; It reads the data and removes the data from the file ;;; (define get-messages (lambda () (if (and (file-exists? message-file) (not (file-exists? semaphore-file))) (let ([semport (open-output-file semaphore-file)]) (write "foo" semport) (close-output-port semport) (let ([ip (open-input-file message-file)] [op (open-output-file log-file 'append)]) (let ([message-list (read-all (read ip) ip)]) (close-input-port ip) (write message-list op) (close-output-port op) (delete-file message-file) (delete-file semaphore-file) message-list)))) '())) (define read-all (lambda (mess ip) (if (eof-object? mess) '() (cons mess (read-all (read ip) ip))))) ;;; write-message takes a message and writes it to the ;;; message file ;;; (define write-message (lambda (message) (if (file-exists? semaphore-file) (write-message message) (let ([semport (open-output-file semaphore-file)]) (write "foo" semport) (close-output-port semport) (let ([op (open-output-file message-file 'append)]) (write message op) (newline op) (close-output-port op) (delete-file semaphore-file)))))) ;;; The following program is a tester program, which simply ;;; waits for the user to type something at the current input ;;; port, then does a get-message, prints the result to the current ;;; output port, and loops again ;;; (define test-reads (lambda () (let ([messages (get-messages)]) (pretty-print messages) (test-reads))))