Created
November 12, 2011 09:20
-
-
Save mike-lawrence/1360283 to your computer and use it in GitHub Desktop.
Example of using multiprocessing module for seperating input and output from a main pygame display loop. The code creates a window that displays any key that is typed (escape quits) and writes data to a file called "output.txt" containing some timing data
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import used modules | |
import pygame | |
import sys | |
import time | |
import multiprocessing | |
#initialize pygame | |
pygame.init() | |
#create a window | |
screen = pygame.display.set_mode((400,400)) | |
#initialize a font | |
defaultFontName = pygame.font.get_default_font() | |
feedbackFont = pygame.font.Font(defaultFontName, 10) | |
#create a multiprocessing Queue object for sending messages to an input process | |
queueToInputProcess = multiprocessing.Queue() | |
#create a multiprocessing Queue object for receiving messages from an input process | |
queueFromInputProcess = multiprocessing.Queue() | |
#define a function to run continuously in a seperate process that monitors the pygame event queue for keypress events | |
def inputProcessLoop(queueToInputProcess,queueFromInputProcess): | |
done = False | |
while not done: | |
now = time.time() | |
pygame.event.pump() | |
for event in pygame.event.get() : | |
if event.type == pygame.KEYDOWN : | |
response = event.unicode | |
response_time = now | |
queueFromInputProcess.put([response,response_time]) | |
if not queueToInputProcess.empty(): | |
from_queue = queueToInputProcess.get() | |
if from_queue == 'quit': | |
done = True | |
#start up the input detector in a separate process | |
inputProcess = multiprocessing.Process(target=inputProcessLoop, args=(queueToInputProcess,queueFromInputProcess,)) | |
inputProcess.start() | |
#create a multiprocessing Queue object for sending messages to an output process | |
queueToOutputProcess = multiprocessing.Queue() | |
#define a function to run continuously in a seperate process that monitors the output queue for messages and writes data as necessary | |
def outputProcessLoop(queueToOutputProcess): | |
outfile = open('outfile.txt','w') | |
done = False | |
while not done: | |
if not queueToOutputProcess.empty(): | |
from_queue = queueToOutputProcess.get() | |
if from_queue == 'quit': | |
outfile.close() | |
done = True | |
else: | |
outfile.write(from_queue+'\n') | |
#start up the output process in a separate process | |
outputProcess = multiprocessing.Process(target=outputProcessLoop, args=(queueToOutputProcess,)) | |
outputProcess.start() | |
#start the diaplay loop | |
done = False | |
updateDisplay = False | |
while not done: | |
if not queueFromInputProcess.empty(): | |
from_queue = queueFromInputProcess.get() | |
if from_queue[0]=='\x1b': | |
queueToInputProcess.put('quit') | |
queueToOutputProcess.put('quit') | |
inputProcess.join() | |
outputProcess.join() | |
pygame.quit() | |
sys.exit() | |
else: | |
toDisplay = from_queue[0] | |
updateDisplay = True | |
if updateDisplay: | |
updateDisplay = False | |
thisRender = feedbackFont.render(toDisplay, True, (255,255,255)) | |
x = screen.get_width()/2-thisRender.get_width()/2 | |
y = screen.get_height()/2-thisRender.get_height()/2 | |
screen.fill((0,0,0)) | |
screen.blit(thisRender,(x,y)) | |
pygame.display.flip() | |
flipLatency = str(time.time()-from_queue[1]) | |
queueToOutputProcess.put(flipLatency) |
Author
mike-lawrence
commented
Nov 12, 2011
via email
I've seen big benefits with forking off writing data to disk when
there is a large amount of data to write (eg. continuously polled
mouse position). There are likely smaller benefits to forking input
detection as pygame (via SDL) already uses an event queue. However, I
like that when you put input detection in a separate queue you can
immediately assign input a timestamp so that if you are doing
time-consuming computations in your main stimulus presentation loop,
you may see slightly more accurate timing.
…On Sat, Nov 12, 2011 at 12:32 PM, Sebastiaan Mathot ***@***.*** wrote:
Zhiguo forwarded your email discussion to me. This looks very interesting, and it works fine for me on Ubuntu 11.10 (although it crashes when closing). Any idea whether it would significantly improve performance in a real-life setting? (I'm thinking that perhaps SDL already does something similar in its event loop?)
---
Reply to this email directly or view it on GitHub:
https://gist.github.com/1360283
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment