Skip to content

Instantly share code, notes, and snippets.

@bjering
Created August 23, 2010 13:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bjering/e81bb48793d311df1eea to your computer and use it in GitHub Desktop.
Save bjering/e81bb48793d311df1eea to your computer and use it in GitHub Desktop.
(ns chat.user
(:use
[clojure.contrib.def]
[chat.common])
(:require
[clojure.string]))
(defvar users (agent {}))
(defn- write
[user message]
(let
[session (user :session)]
(when session
(session :write message))
user))
(defn- say
[user channel-name message]
(let [channel ((user :channels) channel-name)]
(if channel
(channel :say (user :user-name) message)
(str "error " (user :user-name) " is not a member of channel " channel-name))))
(defn- ping
[user id]
(str "pong " id))
(defn- user-parse
[user message]
(let
[msg-seq (clojure.string/split message #" " 3)
command (msg-seq 0)]
(cond
(= "say" command) (say user (msg-seq 1) (msg-seq 2))
(= "ping" command) (ping user (msg-seq 1))
:else (str "error Unknown User Command: " command))))
(defn- add-channel
[user channel]
(conj user {:channels (conj (user :channels) {(channel :channel-name) channel})}))
(defn- set-session
[user session]
(let
[old-session (user :session)]
(if old-session
(do
(old-session :send :close)
(session :write "resume"))
(doseq
[channel (vals (user :channels))]
(channel :join (user :user-name))))
(conj user {:session session})))
(defn dispatcher
[state message & args]
(cond
(= message :agent) state
(= message :state) @state
(= message :user-name) (@state :user-name)
(= message :parse) (apply user-parse @state args)
(= message :send)
(do
(apply chat.common/send-message state args)
(partial dispatcher state))
:else (throw (IllegalArgumentException.
(str "unknown message in [" "user" "] " message)))))
(defn- logout
[user]
(doseq
[channel (vals (user :channels))]
(channel :leave (user :user-name)))
(conj user {:session nil}))
(defn create
[user-name]
(let
[
new-user
(partial dispatcher
(agent
{:user-name user-name
:channels {}
:session nil
:write write
:logout logout
:set-session set-session
:add-channel add-channel}))]
(send users conj {user-name new-user})
new-user))
(defn delete-all
[]
(defvar users (agent {})))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment