106 lines
2.4 KiB
Go
106 lines
2.4 KiB
Go
package roomstate
|
|
|
|
import (
|
|
"sort"
|
|
"sync"
|
|
|
|
kitlog "github.com/go-kit/kit/log"
|
|
"go.cryptoscope.co/muxrpc/v2"
|
|
|
|
"github.com/ssb-ngi-pointer/go-ssb-room/internal/broadcasts"
|
|
refs "go.mindeco.de/ssb-refs"
|
|
)
|
|
|
|
type Manager struct {
|
|
logger kitlog.Logger
|
|
|
|
endpointsUpdater broadcasts.RoomChangeSink
|
|
endpointsbroadcaster *broadcasts.RoomChangeBroadcast
|
|
|
|
roomMu *sync.Mutex
|
|
room roomStateMap
|
|
}
|
|
|
|
func NewManager(log kitlog.Logger) *Manager {
|
|
var m Manager
|
|
m.logger = log
|
|
m.endpointsUpdater, m.endpointsbroadcaster = broadcasts.NewRoomChanger()
|
|
m.roomMu = new(sync.Mutex)
|
|
m.room = make(roomStateMap)
|
|
|
|
return &m
|
|
}
|
|
|
|
// roomStateMap is a single room
|
|
type roomStateMap map[string]muxrpc.Endpoint
|
|
|
|
// copy map entries to list for broadcast update
|
|
func (rsm roomStateMap) AsList() []string {
|
|
memberList := make([]string, 0, len(rsm))
|
|
for m := range rsm {
|
|
memberList = append(memberList, m)
|
|
}
|
|
sort.Strings(memberList)
|
|
return memberList
|
|
}
|
|
|
|
// Register listens to changes to the room
|
|
func (m *Manager) RegisterLegacyEndpoints(sink broadcasts.RoomChangeSink) {
|
|
m.broadcaster.Register(sink)
|
|
}
|
|
|
|
// List just returns a list of feed references
|
|
func (m *Manager) List() []string {
|
|
m.roomMu.Lock()
|
|
defer m.roomMu.Unlock()
|
|
return m.room.AsList()
|
|
}
|
|
|
|
// AddEndpoint adds the endpoint to the room
|
|
func (m *Manager) AddEndpoint(who refs.FeedRef, edp muxrpc.Endpoint) {
|
|
m.roomMu.Lock()
|
|
// add ref to to the room map
|
|
m.room[who.Ref()] = edp
|
|
// update all the connected tunnel.endpoints calls
|
|
m.updater.Update(m.room.AsList())
|
|
m.roomMu.Unlock()
|
|
}
|
|
|
|
// Remove removes the peer from the room
|
|
func (m *Manager) Remove(who refs.FeedRef) {
|
|
m.roomMu.Lock()
|
|
// remove ref from lobby
|
|
delete(m.room, who.Ref())
|
|
// update all the connected tunnel.endpoints calls
|
|
m.updater.Update(m.room.AsList())
|
|
m.roomMu.Unlock()
|
|
}
|
|
|
|
// AlreadyAdded returns true if the peer was already added to the room.
|
|
// if it isn't it will be added.
|
|
func (m *Manager) AlreadyAdded(who refs.FeedRef, edp muxrpc.Endpoint) bool {
|
|
m.roomMu.Lock()
|
|
|
|
// if the peer didn't call tunnel.announce()
|
|
_, has := m.room[who.Ref()]
|
|
if !has {
|
|
// register them as if they didnt
|
|
m.room[who.Ref()] = edp
|
|
|
|
// update everyone
|
|
m.updater.Update(m.room.AsList())
|
|
}
|
|
|
|
m.roomMu.Unlock()
|
|
return has
|
|
}
|
|
|
|
// Has returns true and the endpoint if the peer is in the room
|
|
func (m *Manager) Has(who refs.FeedRef) (muxrpc.Endpoint, bool) {
|
|
m.roomMu.Lock()
|
|
// add ref to to the room map
|
|
edp, has := m.room[who.Ref()]
|
|
m.roomMu.Unlock()
|
|
return edp, has
|
|
}
|