1

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() + "\n")
  } 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\n", 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.

1 Answer 1

4

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()
     }
  }()
Sign up to request clarification or add additional context in comments.

5 Comments

I removed the time calculations to keep the example simple. Right now playerFactory.Update() does nothing but print a message (assuming clients are connected). Again, this loop runs, but the code never seems to reach the connection handling loop which is the part that is confusing me.
I've just tested the code I gave you : the line following it is executed. Are you sure you're connecting properly ? Are you sure you used the timer properly (for example as I did) ? This is not about time calculations but about blocking until a tick happens (every 100 ms).
I am not exactly sure what I was doing wrong, but I changed my timer code to yours and now everything works as I was expecting. Thanks for the help! (Ah ok, your edited comment explains it, got it now).
Upon further inspection I was just testing things wrong, and everything was actually working correctly. Thanks again though dystroy.
I believe that as of Go 1.2, with pre-emptive scheduling, the potential for blocking other goroutines from running should be gone.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.