145 lines
4.1 KiB
Scheme
145 lines
4.1 KiB
Scheme
(define-module (bugafriend ui)
|
|
#:use-module (bugafriend utils registry)
|
|
#:use-module (goblins)
|
|
#:use-module (goblins vat)
|
|
#:use-module (goblins ocapn ids)
|
|
#:use-module (fibers)
|
|
#:use-module (fibers channels)
|
|
#:use-module (fibers conditions)
|
|
#:use-module (srfi srfi-9)
|
|
#:use-module (srfi srfi-1)
|
|
#:use-module (ice-9 rdelim)
|
|
#:use-module (ice-9 match)
|
|
#:use-module (ice-9 exceptions)
|
|
#:use-module (ice-9 readline)
|
|
#:use-module (ice-9 suspendable-ports)
|
|
#:export (say))
|
|
|
|
|
|
(define ocapn-registry #f)
|
|
(define room-actor #f)
|
|
|
|
(define (is-command? str)
|
|
(and (> (string-length str) 0) (eq? (string-ref str 0) #\/)))
|
|
|
|
(define-record-type <console-command>
|
|
(make-console-command name help thunk)
|
|
console-command?
|
|
(name console-command-name)
|
|
(help console-command-help)
|
|
(thunk console-command-thunk))
|
|
|
|
(define commands
|
|
(list
|
|
(make-console-command
|
|
"/quit"
|
|
"- Exits the chat"
|
|
(λ (args) (loop! #f)))
|
|
(make-console-command
|
|
"/help"
|
|
"- Prints this help"
|
|
(λ (args)
|
|
(print-help)
|
|
(loop! #t)))
|
|
(make-console-command
|
|
"/create"
|
|
"- Create a new chat and join it."
|
|
(λ (args)
|
|
(define my-presence (spawn ^room-presence "user"))
|
|
(set! room-actor (spawn ^room my-presence))
|
|
(format #t "Room ID: ~a\n" ($ ocapn-registry 'register room))
|
|
(loop! #t)))
|
|
(make-console-command
|
|
"/me"
|
|
"<text> - Me command, you like roleplay or whatever"
|
|
(λ (args)
|
|
(when (room-actor)
|
|
;; eww, maybe fix mangling the input by joining
|
|
(<- room-actor 'me (string-join args " "))
|
|
(loop! #t))))
|
|
(make-console-command
|
|
"/join"
|
|
"<room-id> - Switch chats to another room"
|
|
(λ (args)
|
|
(unless (eq? 2 (length args))
|
|
(error "Need one argument, the room sturdyref!"))
|
|
|
|
(let* ((room-id (list-ref args 1))
|
|
(room-sref (string->ocapn-id room-id)))
|
|
(unless room-sref
|
|
(error "Badly formatted sturdyref!"))
|
|
(unless ocapn-registry
|
|
(error "Relay not yet connected."))
|
|
|
|
(format #t "Connecting...\n")
|
|
(on (<- ocapn-registry 'enliven room-sref)
|
|
(λ (l)
|
|
(set! room-actor l)
|
|
(format #t "Joined chat.\n")
|
|
(loop! #t))
|
|
#:catch
|
|
(λ (e)
|
|
(format #t "Failed: ~a\n" e)
|
|
(loop! #t))))))))
|
|
|
|
(define (print-help)
|
|
(format #t "Command reference:\n")
|
|
(map (λ (x) (format #t " ~a ~a\n" (console-command-name x) (console-command-help x))) commands))
|
|
|
|
(define command-names (map console-command-name commands))
|
|
|
|
(define (%eval-command cmd)
|
|
(define args (string-split cmd char-set:whitespace))
|
|
(define matching-command (find (λ (x) (equal? (console-command-name x) (car args))) commands))
|
|
(if matching-command
|
|
((console-command-thunk matching-command) args)
|
|
(begin
|
|
(format #t "Don't know how to handle ~a.\n\n" cmd)
|
|
(print-help)
|
|
(loop! #t))))
|
|
|
|
(define loop-channel (make-channel))
|
|
(define (loop! val) (put-message loop-channel val) val)
|
|
|
|
(define (%loop vat)
|
|
(with-exception-handler
|
|
(λ (e)
|
|
(format #t "Command failed: ~s\n" e)
|
|
(loop! #t))
|
|
(λ ()
|
|
(let ((line (readline)))
|
|
(with-vat vat
|
|
(cond
|
|
((eq? 0 (string-length line)) (loop! #t))
|
|
((is-command? line)
|
|
(%eval-command line))
|
|
(else (if room-actor
|
|
(on (<- room-actor 'say line) (λ (val) (loop! val)))
|
|
(begin
|
|
(format #t "Not connected to anyone yet. Use /join <sturdyref>!\n")
|
|
(loop! #t))))))))
|
|
#:unwind? #t))
|
|
|
|
(define (say setup-sref)
|
|
(define vat (spawn-vat #:name "Speaker Vat"))
|
|
|
|
(set-readline-prompt! " 🐞 > ")
|
|
|
|
(with-vat vat
|
|
(format #t "Connecting to relay...\n")
|
|
(on (prelay-sref->mycapn-registry setup-sref)
|
|
(λ (r)
|
|
(set! ocapn-registry r)
|
|
(format #t "Connected.\n")
|
|
(loop! #t))
|
|
#:catch
|
|
(λ (e)
|
|
(format #t "Failed: ~a\n" e)
|
|
(loop! #t))))
|
|
|
|
(while (get-message loop-channel)
|
|
(with-vat vat
|
|
(syscaller-free-fiber
|
|
(λ ()
|
|
(%loop vat))))))
|