Files
galaxy-game/internal/controller/cache.go
T
2026-02-08 16:35:58 +02:00

101 lines
2.7 KiB
Go

package controller
import (
"fmt"
"slices"
"github.com/google/uuid"
"github.com/iliadenisov/galaxy/internal/model/game"
)
type Cache struct {
g *game.Game
cacheRaceIndexByID map[uuid.UUID]int
cacheFleetIndexByID map[uuid.UUID]int
cacheRaceIndexByShipGroupIndex map[int]int
cacheShipClassByShipGroupIndex map[int]*game.ShipType
cachePlanetByPlanetNumber map[uint]*game.Planet
cacheRelation map[int]map[int]game.Relation
}
func NewCache(g *game.Game) *Cache {
if g == nil {
panic("NewCache: nil Game passed")
}
c := &Cache{
g: g,
}
return c
}
func (c Cache) Stage() uint {
return c.g.Stage
}
func (c *Cache) ShipGroupShipClass(groupIndex int) *game.ShipType {
if len(c.cacheShipClassByShipGroupIndex) == 0 {
c.cacheShipsAndGroups()
}
c.validateShipGroupIndex(groupIndex)
if v, ok := c.cacheShipClassByShipGroupIndex[groupIndex]; ok {
return v
} else {
panic(fmt.Sprintf("ShipClassByShipGroupIndex: group not found by index=%v", groupIndex))
}
}
func (c *Cache) RaceIndex(ID uuid.UUID) int {
if c.cacheRaceIndexByID == nil {
c.cacheRaceIndexByID = make(map[uuid.UUID]int)
for i := range c.listRaceIdx() {
c.cacheRaceIndexByID[c.g.Race[i].ID] = i
}
}
if v, ok := c.cacheRaceIndexByID[ID]; ok {
return v
} else {
panic(fmt.Sprintf("RaceIndex: race not found by ID=%v", ID))
}
}
func (c *Cache) cacheShipsAndGroups() {
if c.cacheRaceIndexByShipGroupIndex != nil {
clear(c.cacheRaceIndexByShipGroupIndex)
} else {
c.cacheRaceIndexByShipGroupIndex = make(map[int]int)
}
if c.cacheShipClassByShipGroupIndex != nil {
clear(c.cacheShipClassByShipGroupIndex)
} else {
c.cacheShipClassByShipGroupIndex = make(map[int]*game.ShipType)
}
for groupIndex := range c.g.ShipGroups {
ri := c.RaceIndex(c.g.ShipGroups[groupIndex].OwnerID)
c.cacheRaceIndexByShipGroupIndex[groupIndex] = ri
sti, ok := ShipClassIndex(c.g, ri, c.g.ShipGroups[groupIndex].TypeID)
if !ok {
panic(fmt.Sprintf("CollectPlanetGroups: ship class not found for race=%q group=%v", c.g.Race[ri].Name, c.g.ShipGroups[groupIndex].Index))
}
c.cacheShipClassByShipGroupIndex[groupIndex] = &c.g.Race[ri].ShipTypes[sti]
}
}
func (c *Cache) invalidateShipGroupCache() {
clear(c.cacheRaceIndexByShipGroupIndex)
clear(c.cacheShipClassByShipGroupIndex)
}
func (c *Cache) invalidateFleetCache() {
clear(c.cacheFleetIndexByID)
}
// Helpers
func ShipClassIndex(g *game.Game, ri int, classID uuid.UUID) (int, bool) {
if len(g.Race) < ri+1 {
panic(fmt.Sprintf("ShipClass: game race index %d invalid: len=%d", ri, len(g.Race)))
}
sti := slices.IndexFunc(g.Race[ri].ShipTypes, func(st game.ShipType) bool { return st.ID == classID })
return sti, sti >= 0
}