Move NATS subscription and chat room management into a dedicated GameService, following the portigo service pattern. Handlers now receive the service and call its methods instead of managing NATS connections directly.
71 lines
2.0 KiB
Go
71 lines
2.0 KiB
Go
// Package services provides the game service layer for Connect 4,
|
|
// 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/connect4"
|
|
"github.com/ryanhamamura/games/db/repository"
|
|
)
|
|
|
|
// c4ChatColors maps player slot (0-indexed) to CSS background colors.
|
|
var c4ChatColors = map[int]string{
|
|
0: "#4a2a3a", // Red player
|
|
1: "#2a4545", // Yellow player
|
|
}
|
|
|
|
func c4ChatColor(slot int) string {
|
|
if c, ok := c4ChatColors[slot]; ok {
|
|
return c
|
|
}
|
|
return "#666"
|
|
}
|
|
|
|
// GameService manages NATS subscriptions and chat for Connect 4 games.
|
|
type GameService struct {
|
|
nc *nats.Conn
|
|
queries *repository.Queries
|
|
}
|
|
|
|
// NewGameService creates a new game service.
|
|
func NewGameService(nc *nats.Conn, queries *repository.Queries) *GameService {
|
|
return &GameService{
|
|
nc: nc,
|
|
queries: queries,
|
|
}
|
|
}
|
|
|
|
// 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(connect4.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: "c4",
|
|
PostURL: fmt.Sprintf("/games/%s/chat", gameID),
|
|
Color: c4ChatColor,
|
|
}
|
|
}
|
|
|
|
// ChatRoom returns a persistent chat room for a game.
|
|
func (s *GameService) ChatRoom(gameID string) *chat.Room {
|
|
return chat.NewPersistentRoom(s.nc, connect4.ChatSubject(gameID), s.queries, gameID)
|
|
}
|
|
|
|
// PublishGameUpdate sends a notification that the game state has changed.
|
|
func (s *GameService) PublishGameUpdate(gameID string) error {
|
|
return s.nc.Publish(connect4.GameSubject(gameID), nil)
|
|
}
|