github.com/diamondburned/arikawa/v2@v2.1.0/state/store/defaultstore/presence.go (about) 1 package defaultstore 2 3 import ( 4 "sync" 5 6 "github.com/diamondburned/arikawa/v2/discord" 7 "github.com/diamondburned/arikawa/v2/gateway" 8 "github.com/diamondburned/arikawa/v2/internal/moreatomic" 9 "github.com/diamondburned/arikawa/v2/state/store" 10 ) 11 12 type Presence struct { 13 guilds moreatomic.Map 14 } 15 16 type presences struct { 17 mut sync.Mutex 18 presences map[discord.UserID]gateway.Presence 19 } 20 21 var _ store.PresenceStore = (*Presence)(nil) 22 23 func NewPresence() *Presence { 24 return &Presence{ 25 guilds: *moreatomic.NewMap(func() interface{} { 26 return &presences{ 27 presences: make(map[discord.UserID]gateway.Presence, 1), 28 } 29 }), 30 } 31 } 32 33 func (s *Presence) Reset() error { 34 return s.guilds.Reset() 35 } 36 37 func (s *Presence) Presence(gID discord.GuildID, uID discord.UserID) (*gateway.Presence, error) { 38 iv, ok := s.guilds.Load(gID) 39 if !ok { 40 return nil, store.ErrNotFound 41 } 42 43 ps := iv.(*presences) 44 45 ps.mut.Lock() 46 defer ps.mut.Unlock() 47 48 p, ok := ps.presences[uID] 49 if ok { 50 return &p, nil 51 } 52 53 return nil, store.ErrNotFound 54 } 55 56 func (s *Presence) Presences(guildID discord.GuildID) ([]gateway.Presence, error) { 57 iv, ok := s.guilds.Load(guildID) 58 if !ok { 59 return nil, store.ErrNotFound 60 } 61 62 ps := iv.(*presences) 63 64 ps.mut.Lock() 65 defer ps.mut.Unlock() 66 67 var presences = make([]gateway.Presence, 0, len(ps.presences)) 68 for _, p := range ps.presences { 69 presences = append(presences, p) 70 } 71 72 return presences, nil 73 } 74 75 func (s *Presence) PresenceSet(guildID discord.GuildID, presence gateway.Presence) error { 76 iv, _ := s.guilds.LoadOrStore(guildID) 77 78 ps := iv.(*presences) 79 80 ps.mut.Lock() 81 defer ps.mut.Unlock() 82 83 // Shitty if check is better than a realloc every time. 84 if ps.presences == nil { 85 ps.presences = make(map[discord.UserID]gateway.Presence, 1) 86 } 87 88 ps.presences[presence.User.ID] = presence 89 90 return nil 91 } 92 93 func (s *Presence) PresenceRemove(guildID discord.GuildID, userID discord.UserID) error { 94 iv, ok := s.guilds.Load(guildID) 95 if !ok { 96 return nil 97 } 98 99 ps := iv.(*presences) 100 101 ps.mut.Lock() 102 delete(ps.presences, userID) 103 ps.mut.Unlock() 104 105 return nil 106 }