The basic background to this project is that I am trying to move my level generation code into a separate thread so that I can generate the next level in advance while the player is still on the previous level, or while the game is loading. I have a pretty fancy system now that allows my main program to send a variety of signals to the thread, including "quit" "start generating" "whats your status?" and "I am ready to receive the level when you are."
Right now, I have a loop that calls "status" repeatedly, waits for a reply, and if the reply is success, sets up to receive the level. However, at the end of the loop, one pesky value somehow got stuck in the pipe buffer during the process. The specific value is the number 0, used to signal the loop completing. However, I know I received at least one 0 already, which triggered the loop to stop, so I have no idea where the extra 0 came from.
I have been spending too much time trying to fix this problem, so if someone who has experience with this type of things sees some obvious mistake or at least knows some things I could try to diagnose the mistake, that would be very helpfull.
This is my code for the loop in the main program:
assert not self.pipe[0].poll(), "Some leftover information got stuck"
status=1
while status:
self.pipe[0].send("stat")
status=self.pipe[0].recv()
print status,"numstats=",numstats
assert not self.pipe[0].poll(), "Some leftover information got stuck"
And this is my code for the other thread:
def generate(pipe1):
pipe1.send("starting...")
generating=False
g=None
level=None
objects=None
size=None
roomsdone=0
roomstodo=0
running=True
waitingfor=None
while running:
if pipe1.poll() or not generating:
t=pipe1.recv()
if t=="quit":
running=False
elif not generating:
if waitingfor=="level":
level=t
print "level: ",level
waitingfor="size"
elif waitingfor=="size":
size=t
print "size:",size
waitingfor="start"
generating=True
roomsdone=0
g=generator.Generator(size, level)
elif t=="gener":
waitingfor="level"
elif t=="retu":
print "sending Grid",g
pipe1.send(g)
print "sending object",objects
pipe1.send(objects)
print "returned object"
elif t=="stat":
pipe1.send(0)
else:
raise ValueError(str(t)+" is not a option I know of")
else:
if t=="stat":
pipe1.send(roomsdone+1) #0 is the quit code, so I add one so it can never be 0
elif t=="retu":
pipe1.send(None)
else:
raise ValueError(str(t)+" is not an option I know of while generating")
elif generating:
if waitingfor=="start":
g.start()
waitingfor=None
roomstodo=g.numrooms
elif roomsdone<roomstodo:
f=g.step()
if f:
roomsdone+=1
else:
objects=g.finish()
generating=False
roomsdone=0
else:
objects=g.finish()
generating=False
roomsdone=0
Some things I have tried:
- Counting how many times I called stat from both sides, they seem to be equal
- Sleeping for a second between calls to stat to check if calls somehow change order because of sending many things fast, no difference
- popping the extra 0 from the pipe, the code compiles, but I don't know where the 0 comes from
- checking in the middle of the loop if ever two things are added, the extra 0 seems to have been put in in the last iteration i.e the last else in the code, or the second to last else, depending on whether the maximal amount of rooms where built or not (usually, they aren't) or the call to stat after generating is false.
- The top line in the code checks that the pipe is empty before the loop, so the problem must be in this line.
I know people don't have time to read long pieces of code, so I shortened it a lot. I was afraid I might take out something important though.