package controller import ( "fmt" "github.com/iliadenisov/galaxy/internal/model/game" "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 LoadState() (game.Game, error) } type Controller struct { param Param Repo Repo } type Param struct { StoragePath string } func NewController(configure func(*Param)) (*Controller, error) { c := &Param{ StoragePath: ".", } if configure != nil { configure(c) } r, err := repo.NewFileRepo(c.StoragePath) if err != nil { return nil, err } return &Controller{ param: *c, Repo: r, }, nil } func (c *Controller) ExecuteInit(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) Execute(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 } consumer(c.Repo, g) return c.Repo.Release() }