2022-01-10 23:16:22 +01:00
|
|
|
package term_conn
|
2022-01-10 04:04:23 +01:00
|
|
|
|
|
|
|
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 {
|
2022-01-10 15:35:05 +01:00
|
|
|
mtx sync.Mutex
|
|
|
|
players map[string]*TermConn
|
2022-01-10 04:04:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
var registry Registry
|
|
|
|
|
|
|
|
func (reg *Registry) init() {
|
2022-01-10 15:35:05 +01:00
|
|
|
reg.players = make(map[string]*TermConn)
|
2022-01-10 04:04:23 +01:00
|
|
|
}
|
|
|
|
|
2022-01-10 15:35:05 +01:00
|
|
|
func (d *Registry) addPlayer(name string, tc *TermConn) {
|
2022-01-10 04:04:23 +01:00
|
|
|
d.mtx.Lock()
|
2022-01-10 15:35:05 +01:00
|
|
|
if _, ok := d.players[name]; ok {
|
|
|
|
log.Println(name, "already exist in the dispatcher, skip registration")
|
|
|
|
} else {
|
|
|
|
d.players[name] = tc
|
2022-01-10 04:04:23 +01:00
|
|
|
}
|
|
|
|
d.mtx.Unlock()
|
|
|
|
}
|
|
|
|
|
2022-01-10 15:35:05 +01:00
|
|
|
func (d *Registry) removePlayer(name string) error {
|
2022-01-10 04:04:23 +01:00
|
|
|
d.mtx.Lock()
|
|
|
|
var err error = errors.New("not found")
|
|
|
|
|
2022-01-10 15:35:05 +01:00
|
|
|
if _, ok := d.players[name]; ok {
|
|
|
|
delete(d.players, name)
|
2022-01-10 04:04:23 +01:00
|
|
|
err = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2022-01-10 15:35:05 +01:00
|
|
|
func (d *Registry) sendToPlayer(name string, ws *websocket.Conn) bool {
|
2022-01-10 04:04:23 +01:00
|
|
|
d.mtx.Lock()
|
2022-01-10 15:35:05 +01:00
|
|
|
tc, ok := d.players[name]
|
2022-01-10 04:04:23 +01:00
|
|
|
|
|
|
|
if ok {
|
|
|
|
tc.vchan <- ws
|
|
|
|
}
|
|
|
|
|
|
|
|
d.mtx.Unlock()
|
|
|
|
return ok
|
|
|
|
}
|