From d19b3f71fa9130d7c231bef8f6a7e449db54c532 Mon Sep 17 00:00:00 2001 From: Stephen McQuay Date: Fri, 18 Oct 2013 20:48:22 -0700 Subject: [PATCH] added ability to autovivify games in debug mode --- control.go | 8 +------- game.go | 32 ++++++++++++++++++++++++++++++++ main.go | 7 +------ protocol.go | 6 ++---- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/control.go b/control.go index 5be4c46..009d1fa 100644 --- a/control.go +++ b/control.go @@ -18,13 +18,7 @@ func (h JsonHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { func startGame(w http.ResponseWriter, req *http.Request) { log.Println("asked to create a game") new_game_name := idg.Hash() - - _g := NewGame(new_game_name, *width, *height) - go _g.run() - - games.Lock() - games.m[new_game_name] = _g - games.Unlock() + games.getOrCreate(new_game_name) game_json := struct { Id string `json:"id"` diff --git a/game.go b/game.go index 7d2525e..ba3b7ec 100644 --- a/game.go +++ b/game.go @@ -2,8 +2,10 @@ package main import ( v "bitbucket.org/hackerbots/vector" + "errors" "log" "sort" + "sync" "time" ) @@ -37,6 +39,36 @@ type Scanner struct { Stats Stats `json:"stats"` } +type MapLock struct { + m map[string]*game + sync.RWMutex +} + +func (ml *MapLock) getOrCreate(id string) (*game, error) { + ml.Lock() + g, ok := games.m[id] + ml.Unlock() + + if ok { + return g, nil + } + + if !*debug { + return nil, errors.New("game not found") + } + + new_game_name := idg.Hash() + + _g := NewGame(id, *width, *height) + go _g.run() + + ml.Lock() + ml.m[new_game_name] = _g + ml.Unlock() + + return _g, nil +} + type game struct { id string players map[*player]bool diff --git a/main.go b/main.go index 05cfbe0..06a3789 100644 --- a/main.go +++ b/main.go @@ -8,7 +8,6 @@ import ( "net/http" "os" "runtime/pprof" - "sync" "time" ) @@ -18,16 +17,12 @@ var verbose = flag.Bool("verbose", false, "") var width = flag.Float64("width", 800, "width of field") var height = flag.Float64("height", 550, "height of field") var profile = flag.String("pprof", "", "if specified will run with pprof") +var debug = flag.Bool("debug", false, "automatically create games if they don't exist") var delta float64 var idg *IdGenerator -type MapLock struct { - m map[string]*game - sync.RWMutex -} - // This is the main, global collection of games var games MapLock diff --git a/protocol.go b/protocol.go index ef84673..4e531ef 100644 --- a/protocol.go +++ b/protocol.go @@ -99,11 +99,9 @@ func addPlayer(ws *websocket.Conn) { return } - games.Lock() - game, ok := games.m[gid.Id] - games.Unlock() + game, err := games.getOrCreate(gid.Id) - if !ok { + if err != nil { log.Printf("ERROR: game %s not found", gid.Id) websocket.JSON.Send(ws, NewFailure("game 404")) return