package stages import ( "encoding/json" "fmt" "inp2025/models" "inp2025/tcp" "strings" tea "github.com/charmbracelet/bubbletea" ) type GameModel struct { state models.GameState conn *tcp.SocketConn err error } func NewGameModel() *GameModel { return &GameModel{} } func (m *GameModel) getState() tea.Cmd { return func() tea.Msg { if m.conn == nil { socket, err := tcp.Dial("localhost", "/state") if err != nil { m.err = fmt.Errorf("failed to dial socket, %w", err) return nil } m.conn = socket } b, err := m.conn.Read() if err != nil { m.err = fmt.Errorf("failed to read from socket conn, %w", err) return nil } var cState models.CompressedGameState if err := json.Unmarshal(b, &cState); err != nil { m.err = fmt.Errorf("failed to unmarshal state from json, %w", err) return nil } state, err := cState.Uncompress() if err != nil { m.err = fmt.Errorf("failed to uncompress, %w", err) return nil } return state } } func (m *GameModel) Init() tea.Cmd { return tea.Sequence( tea.ClearScreen, m.getState(), ) } func (m *GameModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmds []tea.Cmd switch msg := msg.(type) { case tea.KeyMsg: switch msg.String() { case "ctrl+c": return m, tea.Quit } case models.GameState: m.state = msg cmds = append(cmds, m.getState()) } return m, tea.Batch(cmds...) } func (m *GameModel) View() string { var b strings.Builder fmt.Fprintf(&b, "%+##v\n", *m) fmt.Fprintf(&b, "%w\n", m.err) return b.String() }