93 lines
2.0 KiB
Go
93 lines
2.0 KiB
Go
package controller
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/iliadenisov/galaxy/internal/model/game"
|
|
"github.com/iliadenisov/galaxy/internal/model/report"
|
|
"github.com/iliadenisov/galaxy/internal/repo"
|
|
)
|
|
|
|
type Repo interface {
|
|
// Lock must be called before any repository operations
|
|
Lock() error
|
|
|
|
// Release must be called after first and only repository operation
|
|
Release() error
|
|
|
|
// SaveTurn stores just generated new turn
|
|
SaveTurn(uint, *game.Game) error
|
|
|
|
// SaveState stores current game state updated between turns
|
|
SaveState(*game.Game) error
|
|
|
|
// LoadState retrieves game current state with required lock acquisition
|
|
LoadState() (*game.Game, error)
|
|
|
|
// LoadStateSafe retrieves game current state without preliminary locking
|
|
LoadStateSafe() (*game.Game, error)
|
|
|
|
// SaveBattle stores a new battle protocol and battle meta data for turn t
|
|
SaveBattle(t uint, b *report.BattleReport, m *game.BattleMeta) error
|
|
|
|
// SaveBombing stores all prodused bombings for turn t
|
|
SaveBombings(t uint, b []*game.Bombing) error
|
|
|
|
// SaveReport stores latest report for a race
|
|
SaveReport(t uint, rep *report.Report) error
|
|
}
|
|
|
|
type Controller struct {
|
|
Repo Repo
|
|
Cache *Cache
|
|
}
|
|
|
|
type Param struct {
|
|
StoragePath string
|
|
}
|
|
|
|
type Config func(*Param)
|
|
|
|
func NewController(config Config) (*Controller, error) {
|
|
c := &Param{
|
|
StoragePath: ".",
|
|
}
|
|
if config != nil {
|
|
config(c)
|
|
}
|
|
r, err := repo.NewFileRepo(c.StoragePath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &Controller{
|
|
Repo: r,
|
|
}, nil
|
|
}
|
|
|
|
func NewRepoController(r Repo) *Controller {
|
|
return &Controller{
|
|
Repo: r,
|
|
}
|
|
}
|
|
|
|
func (c *Controller) ExecuteState(consumer func(Repo)) error {
|
|
if err := c.Repo.Lock(); err != nil {
|
|
return fmt.Errorf("execute: lock failed: %s", err)
|
|
}
|
|
consumer(c.Repo)
|
|
return c.Repo.Release()
|
|
}
|
|
|
|
func (c *Controller) ExecuteGame(consumer func(Repo, *game.Game)) error {
|
|
if err := c.Repo.Lock(); err != nil {
|
|
return fmt.Errorf("execute: lock failed: %s", err)
|
|
}
|
|
g, err := c.Repo.LoadState()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
c.Cache = NewCache(g)
|
|
consumer(c.Repo, g)
|
|
return c.Repo.Release()
|
|
}
|