1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2024-11-19 05:12:48 +00:00
arikawa/state/store/defaultstore/voicestate.go
diamondburned efde3f4ea6
state, handler: Refactor state storage and sync handlers
This commit refactors a lot of packages.

It refactors the handler package, removing the Synchronous field and
replacing it the AddSyncHandler API, which allows each handler to
control whether or not it should be ran synchronously independent of
other handlers. This is useful for libraries that need to guarantee the
incoming order of events.

It also refactors the store interfaces to accept more interfaces. This
is to make the API more consistent as well as reducing potential useless
copies. The public-facing state API should still be the same, so this
change will mostly concern users with their own store implementations.

Several miscellaneous functions (such as a few in package gateway) were
modified to be more suitable to other packages, but those functions
should rarely ever be used, anyway.

Several tests are also fixed within this commit, namely fixing state's
intents bug.
2021-11-03 15:16:02 -07:00

106 lines
2 KiB
Go

package defaultstore
import (
"sync"
"github.com/diamondburned/arikawa/v3/discord"
"github.com/diamondburned/arikawa/v3/internal/moreatomic"
"github.com/diamondburned/arikawa/v3/state/store"
)
type VoiceState struct {
guilds moreatomic.Map
}
var _ store.VoiceStateStore = (*VoiceState)(nil)
type voiceStates struct {
mut sync.RWMutex
voiceStates map[discord.UserID]discord.VoiceState
}
func NewVoiceState() *VoiceState {
return &VoiceState{
guilds: *moreatomic.NewMap(func() interface{} {
return &voiceStates{
voiceStates: make(map[discord.UserID]discord.VoiceState, 1),
}
}),
}
}
func (s *VoiceState) Reset() error {
return s.guilds.Reset()
}
func (s *VoiceState) VoiceState(
guildID discord.GuildID, userID discord.UserID) (*discord.VoiceState, error) {
iv, ok := s.guilds.Load(guildID)
if !ok {
return nil, store.ErrNotFound
}
vs := iv.(*voiceStates)
vs.mut.RLock()
defer vs.mut.RUnlock()
v, ok := vs.voiceStates[userID]
if ok {
return &v, nil
}
return nil, store.ErrNotFound
}
func (s *VoiceState) VoiceStates(guildID discord.GuildID) ([]discord.VoiceState, error) {
iv, ok := s.guilds.Load(guildID)
if !ok {
return nil, store.ErrNotFound
}
vs := iv.(*voiceStates)
vs.mut.RLock()
defer vs.mut.RUnlock()
var states = make([]discord.VoiceState, 0, len(vs.voiceStates))
for _, state := range vs.voiceStates {
states = append(states, state)
}
return states, nil
}
func (s *VoiceState) VoiceStateSet(
guildID discord.GuildID, voiceState *discord.VoiceState, update bool) error {
iv, _ := s.guilds.LoadOrStore(guildID)
vs := iv.(*voiceStates)
vs.mut.Lock()
if _, ok := vs.voiceStates[voiceState.UserID]; !ok || update {
vs.voiceStates[voiceState.UserID] = *voiceState
}
vs.mut.Unlock()
return nil
}
func (s *VoiceState) VoiceStateRemove(guildID discord.GuildID, userID discord.UserID) error {
iv, ok := s.guilds.Load(guildID)
if !ok {
return nil
}
vs := iv.(*voiceStates)
vs.mut.Lock()
delete(vs.voiceStates, userID)
vs.mut.Unlock()
return nil
}