package client import ( "fmt" "galaxy/client/widget/calculator" "galaxy/client/world" mc "galaxy/model/client" "galaxy/model/report" "slices" "fyne.io/fyne/v2" ) func (e *client) initLatestReport() { e.stateMu.Lock() if e.state.ActiveGameID != nil { if stateIdx := slices.IndexFunc(e.state.GameState, func(gs mc.GameState) bool { return gs.ID == *e.state.ActiveGameID }); stateIdx >= 0 { e.initReportAsync(*e.state.ActiveGameID, e.state.GameState[stateIdx].ActiveTurn) } } e.stateMu.Unlock() } func (e *client) initReportAsync(gid mc.GameID, t uint) { e.s.ReportExistsAsync(gid, t, func(b bool, err error) { e.reportAtStorageExists(gid, t, b, err) }) } func (e *client) reportAtStorageExists(gid mc.GameID, t uint, exists bool, err error) { if err != nil { e.handlerError(err) return } if exists { e.s.LoadReportAsync(gid, t, func(r report.Report, err error) { e.loadReportHandler(gid, r, err) }) return } e.conn.FetchReport(gid, t, func(r report.Report, err error) { e.fetchReportHandler(gid, r, err) }) } func (e *client) fetchReportHandler(gid mc.GameID, r report.Report, err error) { if err != nil { e.handlerError(err) return } e.s.SaveReportAsync(gid, r.Turn, r, func(err error) { e.loadReportHandler(gid, r, err) }) } func (e *client) loadReportHandler(gid mc.GameID, r report.Report, err error) { if err != nil { e.handlerError(err) return } e.stateMu.Lock() needSaveState := false stateIdx := slices.IndexFunc(e.state.GameState, func(gs mc.GameState) bool { return gs.ID == gid }) if stateIdx < 0 { e.state.GameState = append(e.state.GameState, mc.GameState{ID: gid, LastTurn: r.Turn, ActiveTurn: r.Turn}) stateIdx = len(e.state.GameState) - 1 needSaveState = true } if e.state.ActiveGameID == nil { e.state.ActiveGameID = new(gid) needSaveState = true } if e.state.GameState[stateIdx].LastTurn < r.Turn { e.state.GameState[stateIdx].LastTurn = r.Turn e.state.GameState[stateIdx].ActiveTurn = r.Turn needSaveState = true } if needSaveState { if err := e.s.SaveState(*e.state); err != nil { e.handlerError(err) return } } e.stateMu.Unlock() e.setReport(r) } func (e *client) setReport(r report.Report) { w := world.NewWorld(int(r.Width), int(r.Height)) e.reg.clear(&r) for i := range r.LocalPlanet { p := r.LocalPlanet[i] id, err := w.AddCircle(p.X.F(), p.Y.F(), p.Size.F(), world.CircleWithClass(world.CircleClassLocalPlanet)) if err != nil { e.handlerError(err) return } e.reg.registerLocalPlanet(id, i) } for i := range r.UnidentifiedPlanet { p := r.UnidentifiedPlanet[i] id, err := w.AddPoint(p.X.F(), p.Y.F(), world.PointWithClass(world.PointClassTrackIncoming)) if err != nil { e.handlerError(err) return } e.reg.registerUnidentifiedPlanet(id, i) } e.loadWorld(w) selfIdx := slices.IndexFunc(r.Player, func(p report.Player) bool { return p.Name == r.Race }) if selfIdx >= 0 { fyne.Do(func() { e.calculator.Init( calculator.WithPlayerDrives(r.Player[selfIdx].Drive.F()), calculator.WithPlayerWeapons(r.Player[selfIdx].Weapons.F()), calculator.WithPlayerShields(r.Player[selfIdx].Shields.F()), calculator.WithPlayerCargo(r.Player[selfIdx].Cargo.F()), ) }) } else { e.OnServiceError(fmt.Errorf("race %q not found at report players list", r.Race)) } }