Skip to content

Instantly share code, notes, and snippets.

@mike-lawrence
Created November 12, 2011 09:20
Show Gist options
  • Save mike-lawrence/1360283 to your computer and use it in GitHub Desktop.
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
#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)
@smathot
Copy link

smathot commented Nov 12, 2011

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?)

@mike-lawrence
Copy link
Author

mike-lawrence commented Nov 12, 2011 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment