I\'m trying to write a networked game with Pygame and asyncio, but I can\'t work out how to avoid hanging on reads. Here is my code for the client:
@asyncio.coro
The point of yield from
is to switch the execution to the asyncio's event loop and to block the current coroutine until the result is available. To schedule a task without blocking the current coroutine, you could use asyncio.async()
.
To print read-so-far data without blocking the pygame loop:
@asyncio.coroutine
def read(reader, callback):
while True:
data = yield from reader.read(2**12)
if not data: # EOF
break
callback(data)
@asyncio.coroutine
def echo_client():
reader, ...
chunks = []
asyncio.async(read(reader, chunks.append))
while True:
pygame.event.pump() # advance pygame event loop
...
if chunks: # print read-so-far data
print(b''.join(chunks).decode())
del chunks[:]
yield from asyncio.sleep(0.016) # advance asyncio loop
There should be no blocking calls inside the while
loop.
read()
and sleep()
coroutines run concurrently in the same thread (obviously you could run other coroutines concurrently too).