Most of the network code is working, it seems
[mudsync.git] / mudsync.scm
index 3d1d21463fc363f128e0ac0cdf7cf292b6983561..6913ac23f2b5aad572e8bf3b2b4dd07e5c25b258 100644 (file)
 
 (define-class <network-manager> (<actor>)
   (server-socket #:accessor nm-server-socket)
+  ;; mapping of client -> local-id
   (clients #:accessor nm-clients
            #:init-thunk make-hash-table)
+  ;; send input to this actor
+  (send-input-to #:getter nm-send-input-to
+                 #:init-keyword #:send-input-to)
   (message-handler
    #:init-value
    (make-action-dispatch
                         (message-ref message 'port %default-port))))))
 
 (define-method (nm-close-everything (nm <network-manager>) remove-from-agenda)
+  "Shut it down!"
   ;; close all clients
   (hash-for-each
-   (lambda (client _)
+   (lambda (_ client)
      (close client)
      (if remove-from-agenda
          (8sync-port-remove client)))
    (nm-clients nm))
+  ;; reset the clients list
+  (set! (nm-clients) (make-hash-table))
   ;; close the server
   (close (nm-server-socket nm))
   (if remove-from-agenda
 
     (format #t "Listening for clients in pid: ~s\n" (getpid))
     (8sync-port s #:read (lambda (s) (nm-new-client nm s)))
-    ;; TODO: set up periodic close of idle connections
+    ;; TODO: set up periodic close of idle connections?
     ))
 
 (define-method (nm-new-client (nm <network-manager>) s)
+  "Handle new client coming in to socket S"
   (let* ((client-connection (accept s))
          (client-details (cdr client-connection))
          (client (car client-connection)))
             (gethostbyaddr
              (sockaddr:addr client-details)))
 
-    (hash-set! (nm-clients nm) client #f)
-    (8sync-port client #:read (nm-make-client-receive nm))))
+    (let ((local-id (big-random-number)))
+      (hash-set! (nm-clients nm) local-id client)
+      (8sync-port client #:read (nm-make-client-receive nm local-id)))))
 
-(define-method (nm-make-client-receive (nm <network-manager>))
+(define-method (nm-make-client-receive (nm <network-manager>) local-id)
+  "Make a method to receive client data"
   (let ((buffer '()))
     (define (reset-buffer)
       (set! buffer '()))
            (char-ready? client)
            (not (eof-object? (peek-char client)))))
     (define (receive-handler client)
-      (display "Horray, we got something!\n")
       (while (should-read-char client)
         (set! buffer (cons (read-char client) buffer))
         (match buffer
           (;; @@: Do we need the "char?"
-           (#\newline #\newline (? char? line-chars) ...)
+           (#\newline #\return (? char? line-chars) ...)
            (let ((ready-line (list->string (reverse line-chars))))
              ;; reset buffer
              (set! buffer '())
              ;; run it
-             (nm-handle-line nm client ready-line)))
+             (nm-handle-line nm client local-id ready-line)))
           (_ #f)))
       ;; Shut things down on closed port or EOF object
       (cond
        ((port-closed? client)
-        ;; TODO: replace with nm-handle-port-closed
-        (display "port closed time\n")
-        (8sync-port-remove client))
+        (nm-handle-port-closed nm client local-id))
        ((and (char-ready? client)
              (eof-object? (peek-char client)))
-        (display "port eof time\n")
-        ;; TODO: replace with nm-handle-port-eof
-        (close client)
-        (8sync-port-remove client))))
+        (nm-handle-port-eof nm client local-id))))
     receive-handler))
 
-(define-method (nm-handle-line (nm <network-manager>) client line)
+(define-method (nm-handle-port-closed (nm <network-manager>) client local-id)
+  "Handle a closed port"
+  (format #t "DEBUG: handled closed port ~x\n" local-id)
+  (8sync-port-remove client)
+  (hash-remove! (nm-clients nm) local-id))
+
+(define-method (nm-handle-port-eof (nm <network-manager>) client local-id)
+  "Handle seeing an EOF on port"
+  (format #t "DEBUG: handled eof-object on port ~x\n" local-id)
+  (close client)
+  (8sync-port-remove client)
+  (hash-remove! (nm-clients nm) local-id))
+
+(define-method (nm-handle-line (nm <network-manager>) client local-id line)
   "Handle an incoming line of input from a client"
-  (format #t "Got line: ~s\n" line))
+  (format #t "~x got line: ~s\n" local-id line))
+
+; (ez-run-hive hive (list (bootstrap-message hive (actor-id nm) 'start-listening)))
 
 
 ;; (define-method (nm-close-port (nm <network-manager>)))
     ;; init-world
     )))
 
+