summaryrefslogtreecommitdiff
path: root/chat/rooms.go
diff options
context:
space:
mode:
Diffstat (limited to 'chat/rooms.go')
-rw-r--r--chat/rooms.go84
1 files changed, 84 insertions, 0 deletions
diff --git a/chat/rooms.go b/chat/rooms.go
new file mode 100644
index 0000000..e954e29
--- /dev/null
+++ b/chat/rooms.go
@@ -0,0 +1,84 @@
+package chat
+
+import (
+ "errors"
+)
+
+type Room struct {
+ Messages chan Message
+ Buddies map[string]*Buddy
+}
+
+func NewRoom() (r *Room) {
+ r = new(Room)
+ r.Messages = make(chan Message)
+ r.Buddies = make(map[string]*Buddy)
+ go r.Broadcast()
+ return
+}
+
+func (r *Room) Leave(nick string) {
+ if _, ok := r.Buddies[nick]; !ok {
+ return
+ }
+
+ delete(r.Buddies, nick)
+ if len(r.Buddies) == 0 {
+ close(r.Messages)
+ } else {
+ r.Messages <- Message{
+ Type: MsgLeave,
+ User: nick,
+ }
+ }
+}
+
+func (r *Room) Broadcast() {
+ for m := range r.Messages {
+ for _, buddy := range r.Buddies {
+ buddy.Push(m)
+ }
+ }
+}
+
+func (r *Room) ListBuddies() (buddies []string) {
+ for nick := range r.Buddies {
+ buddies = append(buddies, nick)
+ }
+ return
+}
+
+var (
+ rooms map[string]*Room
+ perroom int
+)
+
+func InitRooms(room_limit int) {
+ rooms = make(map[string]*Room)
+ perroom = room_limit
+}
+
+func Join(room, nick string) (*Buddy, *Room, error) {
+ r, ok := rooms[room]
+ if !ok {
+ r = NewRoom()
+ rooms[room] = r
+ }
+
+ if _, there := r.Buddies[nick]; there {
+ return nil, nil, errors.New("Nickname is already in use")
+ }
+
+ if len(r.Buddies) >= perroom {
+ return nil, nil, errors.New("Room is full")
+ }
+
+ r.Messages <- Message{
+ Type: MsgJoin,
+ User: nick,
+ }
+
+ b := NewBuddy(nick, r)
+ r.Buddies[nick] = b
+ return b, r, nil
+}