witty/term_conn/reg.go

82 lines
1.6 KiB
Go
Raw Normal View History

2022-01-29 03:25:15 +01:00
package term_conn
import (
"errors"
"log"
"sync"
"github.com/gorilla/websocket"
)
// a simple registry for actors and their channels. It is possible to
// design this using channels, but it is simple enough with mutex
type Registry struct {
mtx sync.Mutex
players map[string]*TermConn
}
var registry Registry
func (reg *Registry) init() {
reg.players = make(map[string]*TermConn)
}
func (d *Registry) addPlayer(tc *TermConn) {
d.mtx.Lock()
if _, ok := d.players[tc.Name]; ok {
log.Println(tc.Name, "Already exist in the dispatcher, skip registration")
} else {
d.players[tc.Name] = tc
log.Println("Add interactive session to registry", tc.Name)
}
d.mtx.Unlock()
}
func (d *Registry) removePlayer(name string) error {
d.mtx.Lock()
var err error = errors.New("not found")
if _, ok := d.players[name]; ok {
delete(d.players, name)
err = nil
log.Println("Removed interactive session to registry", name)
}
d.mtx.Unlock()
return err
}
// we do not want to return the channel to viewer so it won't be used out of the critical section
func (d *Registry) sendToPlayer(name string, ws *websocket.Conn) bool {
d.mtx.Lock()
tc, ok := d.players[name]
if ok {
tc.viewChan <- ws
}
d.mtx.Unlock()
return ok
}
// Send a command to the session to start, stop recording
func (d *Registry) recordSession(id string, cmd int) bool {
d.mtx.Lock()
tc, ok := d.players[id]
if ok {
tc.recordChan <- cmd
}
d.mtx.Unlock()
return ok
}
func ForEachSession(fp func(tc *TermConn)) {
registry.mtx.Lock()
for _, v := range registry.players {
fp(v)
}
registry.mtx.Unlock()
}