Files
inp2025/stages/game.go
2025-11-10 14:52:16 +08:00

86 lines
1.5 KiB
Go

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()
}