Apply the same service pattern from Connect 4 to Snake game. Handlers now receive the service and call its methods instead of managing NATS connections directly. Also aligns heartbeat to 10s and removes ConnectionIndicator patching (matching C4 changes).
63 lines
1.8 KiB
Go
63 lines
1.8 KiB
Go
// Package services provides the game service layer for Snake,
|
|
// handling NATS subscriptions and chat room management.
|
|
package services
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/nats-io/nats.go"
|
|
|
|
"github.com/ryanhamamura/games/chat"
|
|
chatcomponents "github.com/ryanhamamura/games/chat/components"
|
|
"github.com/ryanhamamura/games/snake"
|
|
)
|
|
|
|
func snakeChatColor(slot int) string {
|
|
if slot >= 0 && slot < len(snake.SnakeColors) {
|
|
return snake.SnakeColors[slot]
|
|
}
|
|
return "#666"
|
|
}
|
|
|
|
// GameService manages NATS subscriptions and chat for Snake games.
|
|
type GameService struct {
|
|
nc *nats.Conn
|
|
}
|
|
|
|
// NewGameService creates a new game service.
|
|
func NewGameService(nc *nats.Conn) *GameService {
|
|
return &GameService{
|
|
nc: nc,
|
|
}
|
|
}
|
|
|
|
// SubscribeGameUpdates returns a NATS subscription and channel for game state updates.
|
|
func (s *GameService) SubscribeGameUpdates(gameID string) (*nats.Subscription, <-chan *nats.Msg, error) {
|
|
ch := make(chan *nats.Msg, 64)
|
|
sub, err := s.nc.ChanSubscribe(snake.GameSubject(gameID), ch)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("subscribing to game updates: %w", err)
|
|
}
|
|
return sub, ch, nil
|
|
}
|
|
|
|
// ChatConfig returns the chat configuration for a game.
|
|
func (s *GameService) ChatConfig(gameID string) chatcomponents.Config {
|
|
return chatcomponents.Config{
|
|
CSSPrefix: "snake",
|
|
PostURL: fmt.Sprintf("/snake/%s/chat", gameID),
|
|
Color: snakeChatColor,
|
|
StopKeyPropagation: true,
|
|
}
|
|
}
|
|
|
|
// ChatRoom returns a chat room for a game (ephemeral, not persisted).
|
|
func (s *GameService) ChatRoom(gameID string) *chat.Room {
|
|
return chat.NewRoom(s.nc, snake.ChatSubject(gameID))
|
|
}
|
|
|
|
// PublishGameUpdate sends a notification that the game state has changed.
|
|
func (s *GameService) PublishGameUpdate(gameID string) error {
|
|
return s.nc.Publish(snake.GameSubject(gameID), nil)
|
|
}
|