diff options
Diffstat (limited to 'user')
| -rw-r--r-- | user/state.go | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/user/state.go b/user/state.go new file mode 100644 index 0000000..bef2f53 --- /dev/null +++ b/user/state.go @@ -0,0 +1,80 @@ +package user + +import ( + "sync" + + "github.com/nyttikord/gokord/state" +) + +type CopaingCached struct { + ID uint `gorm:"primarykey"` + DiscordID string `gorm:"not null"` + GuildID string `gorm:"not null"` + XPs uint + XPToAdd uint +} + +const KeyCopaingCachedPrefix = "cc:" + +func KeyCopaingCached(c *Copaing) state.Key { + return KeyCopaingCachedRaw(c.GuildID, c.DiscordID) +} + +func KeyCopaingCachedRaw(guildID, copaingID string) state.Key { + return KeyCopaingCachedPrefix + state.Key(guildID+":"+copaingID) +} + +type State struct { + mu sync.RWMutex + storage state.MapStorage[CopaingCached] +} + +func (s *State) Copaing(guildID, copaingID string) (*CopaingCached, error) { + s.mu.RLock() + defer s.mu.RUnlock() + + c, err := s.storage.Get(KeyCopaingCachedRaw(guildID, copaingID)) + if err != nil { + return nil, err + } + mC := c.(CopaingCached) + return &mC, nil +} + +// CopaingAdd does not call Copaing.Load! +func (s *State) CopaingAdd(c *Copaing, xpToAdd uint) error { + s.mu.Lock() + defer s.mu.Unlock() + + sum := calcXP(c) + var err error + var cc *CopaingCached + if cc, err = s.Copaing(c.GuildID, c.DiscordID); err != nil { + cc.XPs = sum + cc.XPToAdd = xpToAdd + } else { + cc = &CopaingCached{ + ID: c.ID, + DiscordID: c.DiscordID, + GuildID: c.GuildID, + XPs: sum, + XPToAdd: xpToAdd, + } + } + return s.storage.Write(KeyCopaingCached(c), *cc) +} + +func (s *State) CopaingRemove(c *Copaing) error { + s.mu.Lock() + defer s.mu.Unlock() + + return s.storage.Delete(KeyCopaingCached(c)) +} + +func calcXP(c *Copaing) uint { + var sum uint + for _, entry := range c.CopaingXPs { + sum += entry.XP + } + return sum +} |
