vail/book.go

93 lines
1.4 KiB
Go
Raw Normal View History

2020-04-12 20:40:52 -06:00
package main
import (
"io"
"log"
)
type Book struct {
entries map[string]*Repeater
2020-05-30 22:23:53 -06:00
events chan bookEvent
2020-04-12 20:40:52 -06:00
}
func NewBook() Book {
return Book{
entries: make(map[string]*Repeater),
2020-05-30 22:23:53 -06:00
events: make(chan bookEvent, 5),
2020-04-12 20:40:52 -06:00
}
}
type bookEventType int
2020-05-30 22:23:53 -06:00
2020-04-12 20:40:52 -06:00
const (
joinEvent = bookEventType(iota)
partEvent
sendEvent
)
type bookEvent struct {
eventType bookEventType
2020-05-30 22:23:53 -06:00
name string
w io.Writer
p []byte
2020-04-12 20:40:52 -06:00
}
func (b Book) Join(name string, w io.Writer) {
b.events <- bookEvent{
eventType: joinEvent,
2020-05-30 22:23:53 -06:00
name: name,
w: w,
2020-04-12 20:40:52 -06:00
}
}
func (b Book) Part(name string, w io.Writer) {
b.events <- bookEvent{
eventType: partEvent,
2020-05-30 22:23:53 -06:00
name: name,
w: w,
2020-04-12 20:40:52 -06:00
}
}
func (b Book) Send(name string, p []byte) {
b.events <- bookEvent{
eventType: sendEvent,
2020-05-30 22:23:53 -06:00
name: name,
p: p,
2020-04-12 20:40:52 -06:00
}
}
func (b Book) Run() {
for {
b.loop()
}
}
func (b Book) loop() {
event := <-b.events
repeater, ok := b.entries[event.name]
switch event.eventType {
case joinEvent:
2020-05-30 22:23:53 -06:00
if !ok {
2020-04-12 20:40:52 -06:00
repeater = NewRepeater()
b.entries[event.name] = repeater
}
repeater.Join(event.w)
case partEvent:
2020-05-30 22:23:53 -06:00
if !ok {
2020-04-12 20:40:52 -06:00
log.Println("WARN: Parting an empty channel:", event.name)
break
}
repeater.Part(event.w)
2020-04-12 20:46:51 -06:00
if repeater.Listeners() == 0 {
2020-04-12 20:40:52 -06:00
delete(b.entries, event.name)
}
case sendEvent:
2020-05-30 22:23:53 -06:00
if !ok {
2020-04-12 20:40:52 -06:00
log.Println("WARN: Sending to an empty channel:", event.name)
break
}
repeater.Send(event.p)
}
}