146 lines
3.1 KiB
Go
146 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
rl "github.com/gen2brain/raylib-go/raylib"
|
|
)
|
|
|
|
type Game struct {
|
|
ID int64 `json:"id"`
|
|
Name string `json:"name"`
|
|
PlatformID int64 `json:"platform_id"`
|
|
Score int32 `json:"score"`
|
|
ReleaseYear string `json:"release_year"`
|
|
Finished string `json:"finished,omitempty"`
|
|
}
|
|
|
|
type GamesResponse struct {
|
|
Body []Game `json:"body"`
|
|
}
|
|
|
|
func main() {
|
|
rl.InitWindow(800, 600, "My Game Collection - Raylib")
|
|
defer rl.CloseWindow()
|
|
|
|
rl.SetTargetFPS(60)
|
|
|
|
loading := false
|
|
var err error
|
|
var games []Game
|
|
|
|
// Channel to receive data from background goroutine
|
|
dataChan := make(chan []Game)
|
|
errChan := make(chan error)
|
|
|
|
func() {
|
|
loading = true
|
|
go fetchGames(dataChan, errChan)
|
|
}()
|
|
|
|
for !rl.WindowShouldClose() {
|
|
rl.BeginDrawing()
|
|
rl.ClearBackground(rl.RayWhite)
|
|
|
|
// Header
|
|
rl.DrawRectangle(0, 0, 800, 60, rl.NewColor(100, 100, 255, 255))
|
|
rl.DrawText("My Game Collection", 20, 15, 30, rl.White)
|
|
|
|
startY := 80
|
|
|
|
if loading {
|
|
rl.DrawText("Loading games...", 20, int32(startY), 20, rl.Gray)
|
|
// Simple spinner animation
|
|
if int(rl.GetTime()*4)%2 == 0 {
|
|
rl.DrawText(".", 180, int32(startY), 20, rl.Gray)
|
|
}
|
|
} else if err != nil {
|
|
rl.DrawText(fmt.Sprintf("Error: %v", err), 20, int32(startY), 20, rl.Red)
|
|
rl.DrawText("Press SPACE to retry", 20, int32(startY)+30, 20, rl.DarkGray)
|
|
} else {
|
|
if len(games) == 0 {
|
|
rl.DrawText("No games found in database.", 20, int32(startY), 20, rl.DarkGray)
|
|
} else {
|
|
for i, g := range games {
|
|
yPos := int32(startY + (i * 40))
|
|
|
|
// Row background (alternating)
|
|
if i%2 == 0 {
|
|
rl.DrawRectangle(20, yPos-5, 760, 35, rl.NewColor(240, 240, 240, 255))
|
|
}
|
|
|
|
// Game Name
|
|
rl.DrawText(g.Name, 30, yPos, 20, rl.Black)
|
|
|
|
// Year
|
|
rl.DrawText(g.ReleaseYear, 350, yPos, 20, rl.DarkGray)
|
|
|
|
// Score
|
|
scoreColor := rl.Orange
|
|
if g.Score >= 90 {
|
|
scoreColor = rl.Green
|
|
} else if g.Score < 70 {
|
|
scoreColor = rl.Red
|
|
}
|
|
rl.DrawText(fmt.Sprintf("%d", g.Score), 500, yPos, 20, scoreColor)
|
|
|
|
// Finished Status
|
|
if g.Finished != "" {
|
|
rl.DrawText("Finished", 600, yPos, 20, rl.NewColor(0, 200, 0, 255))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Footer / Help
|
|
rl.DrawText("Press SPACE to refresh", 20, 570, 10, rl.Gray)
|
|
|
|
rl.EndDrawing()
|
|
|
|
// Inputs
|
|
if rl.IsKeyPressed(rl.KeySpace) && !loading {
|
|
loading = true
|
|
err = nil
|
|
games = nil
|
|
go fetchGames(dataChan, errChan)
|
|
}
|
|
|
|
// Check channels (non-blocking)
|
|
select {
|
|
case data := <-dataChan:
|
|
loading = false
|
|
games = data
|
|
case e := <-errChan:
|
|
loading = false
|
|
err = e
|
|
default:
|
|
}
|
|
}
|
|
}
|
|
|
|
func fetchGames(dataChan chan<- []Game, errChan chan<- error) {
|
|
client := &http.Client{Timeout: 5 * time.Second}
|
|
resp, err := client.Get("http://localhost:8080/games")
|
|
if err != nil {
|
|
errChan <- err
|
|
return
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
errChan <- fmt.Errorf("status code: %d", resp.StatusCode)
|
|
return
|
|
}
|
|
|
|
var data GamesResponse
|
|
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
|
|
errChan <- err
|
|
return
|
|
}
|
|
|
|
dataChan <- data.Body
|
|
}
|