I've only begun tinkering with Go for about a week now, and am quite impressed with it. However, I'm still having a few issues I can't get my head around yet.
The main problem right now is that while I have the connection handling code working, I want to add a main game loop independent of the connection loop. How does one do this?
package main
import (
"fmt"
"net"
"strconv"
"time"
"galaxy"
)
const PORT = 5555
func main() {
playerFactory := galaxy.NewPlayerFactory()
server, err := net.Listen("tcp", ":" + strconv.Itoa(PORT))
if server == nil {
panic("listen failed: " + err.Error() + "
")
} else {
defer server.Close()
}
// main loop
go func() {
for {
// entity updates
playerFactory.Update()
}
}() // adding this just blocks everything after the goroutine
// connection handling
for {
conn, err := server.Accept()
if err != nil {
fmt.Printf("client error: %s
", err.Error())
} else {
playerFactory.CreatePlayer(conn)
}
}
}
With the way it is currently written the main loop runs (this is the part I am trying to add), but the connection handling code gets ignored. Is this where one uses channels to pass control around? I'm sure the solution is apparent to a more seasoned Go programmer, I look forward to your answers.
If playerFactory.Update()
never releases the CPU (for example by blocking on a resource), there is no guarantee for other goroutines to run
You could try to change GOMAXPROCS but that would depend on your number of CPU and the problem would reappear later with other non blocking goroutines.
And I can't see any reason for a game loop to run without interruption. The most frequent case is when you have to do something at regular interval.
In this case, your code would be
// main loop
go func() {
timer := time.Tick(100 * time.Millisecond)
for now := range timer {
// entity updates (you could use now for physic engine calculs)
// this is called every 100 millisecondes
playerFactory.Update()
}
}()