run multiple games in parallel

This commit is contained in:
Settel 2021-08-05 01:42:21 +02:00
parent 105a063acf
commit 0b8cbd154b
8 changed files with 77 additions and 26 deletions

View File

@ -0,0 +1,4 @@
{
"players": [
]
}

View File

@ -0,0 +1,5 @@
{
"name": "Player #3",
"role": "player",
"game": "26be8ee5-090d-48f7-845c-f829e668a7d2"
}

View File

@ -0,0 +1,14 @@
package application
import (
"fmt"
"sirlab.de/go/knyt/game"
)
func (app Application) GetGameById(id string) (*game.Game, error) {
gm := app.games[id]
if gm == nil {
return nil, fmt.Errorf("unknown id")
}
return gm, nil
}

View File

@ -0,0 +1,19 @@
package application
import (
"fmt"
"net/http"
)
func (app *Application) SyncHandler(w http.ResponseWriter, r *http.Request) {
gameRef := r.URL.Query().Get("g")
gm, err := app.GetGameById(gameRef)
if err != nil {
w.WriteHeader(http.StatusNotFound)
fmt.Fprintf(w, "game not found")
return
}
eng := gm.GetEngine()
eng.SyncHandler(w, r)
}

View File

@ -3,6 +3,7 @@ package engine
import (
"fmt"
"github.com/imkira/go-observer"
"math/rand"
"sirlab.de/go/knyt/syncdata"
"time"
)
@ -16,10 +17,14 @@ func NewEngine(id string) *Engine {
}
func (engine *Engine) Run() {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for {
value := engine.obs.Value().(syncdata.SyncData)
fmt.Printf("sleep: %d\n", value.VersionRef)
time.Sleep(2 * time.Second)
fmt.Printf("game %s: %d\n", engine.id, value.VersionRef)
wait := int(1 + r.Float32()*2)
for i := 0; i < wait; i++ {
time.Sleep(1 * time.Second)
}
value.VersionRef++
engine.obs.Update(value)
}

View File

@ -8,29 +8,27 @@ import (
"strconv"
)
func (eng *Engine) GetHttpHandler() HandleFunc {
return func(w http.ResponseWriter, r *http.Request) {
versionRef, err := strconv.Atoi(r.URL.Query().Get("v"))
if err != nil {
versionRef = -1
}
stream := eng.obs.Observe()
var value syncdata.SyncData
for {
value = stream.Value().(syncdata.SyncData)
if value.VersionRef >= versionRef {
break
}
select {
case <-stream.Changes():
stream.Next()
}
}
jsonString, _ := json.MarshalIndent(value, "", " ")
w.Header().Add("Content-Type", "application/json")
fmt.Fprintf(w, string(jsonString))
func (eng *Engine) SyncHandler(w http.ResponseWriter, r *http.Request) {
versionRef, err := strconv.Atoi(r.URL.Query().Get("v"))
if err != nil {
versionRef = -1
}
stream := eng.obs.Observe()
var value syncdata.SyncData
for {
value = stream.Value().(syncdata.SyncData)
if value.VersionRef >= versionRef {
break
}
select {
case <-stream.Changes():
stream.Next()
}
}
jsonString, _ := json.MarshalIndent(value, "", " ")
w.Header().Add("Content-Type", "application/json")
fmt.Fprintf(w, string(jsonString))
}

View File

@ -19,6 +19,7 @@ func NewGameFromFile(id, fileName string) (*Game, error) {
} else {
gm.id = id
gm.eng = engine.NewEngine(id)
go gm.eng.Run()
return &gm, nil
}
}
@ -26,3 +27,7 @@ func NewGameFromFile(id, fileName string) (*Game, error) {
func (gm *Game) GetId() string {
return gm.id
}
func (gm *Game) GetEngine() *engine.Engine {
return gm.eng
}

View File

@ -22,6 +22,7 @@ func main() {
mux.PublicHandleFunc("/api/login", mux.Login)
mux.PublicHandleFunc("/api/logout", mux.Logout)
mux.PrivateHandleFunc("/api/userinfo", mux.GetUserInfo)
mux.PrivateHandleFunc("/api/sync", app.SyncHandler)
// default handler
fsHandler := http.FileServer(http.Dir("../../client/dist/"))