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  }