Jump to content
• Advertisement

Unity Re: Python, Pygame, events, and maybe threads?

This topic is 3664 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I found this thread after a Google search, and wanted to follow up with my solution, but it seems that threads get locked after a while, so I have to start a new one. http://www.gamedev.net/community/forums/topic.asp?topic_id=511755
Quote:
 I've been writing an equation graphing utility in Python for a while, with pygame as the graphical end. The idea is that it would be controlled more or less directly by a Python interactive session. The problem is that the event queue doesn't get flushed this way. I've inserted a call to pygame.event.pump() in the update function, but I knew that it wasn't going to get called often enough to make a difference. The window generally doesn't behave well, and sometimes if it gets minimized I can't get it back up. This is a general pain in the butt.
I have been trying to do something remarkably similar. As rightly pointed out by others in that thread, you have to keep pumping the pygame/SDL event queue in order for your window to respond to the operating system. However, you really don't want to lose the benefits of the interpreter. My solution is to run Pygame in a new process and send commands to it via a queue. However, this introduces a new problem: the Pygame process wants to both listen for pygame events, *and* monitor the queue for commands. We could just have it wake up frequently, poll for events/commands and if none are there sleep for a few milliseconds, but this isn't a particularly pleasant solution. Instead, I spawn a tiny thread whose sole job is to wait for commands from the queue and to post them as Pygame events. I *believe* pygame.event.post is thread-safe, since SDL_PushEvent which it uses is thread-safe. Thus the main thread in the Pygame process needs only to keep processing Pygame events. Here's the example (which uses Python 2.6), save it as "multiprocess_example.py": http://pastebin.com/f79e512b1 You can use it like this:
python.exe
import multiprocess_example
process,queue = multiprocess_example.start_pygame_process()
queue.put("Hello World!")
queue.put("Blah blah blah")

You should see a number and some text. The number will increase every time it re-renders. Since there's no animation, we really don't want to waste resources rendering hundreds of times a second. You'll see that we only render when part of the window is obscured and revealed, when we resize and when we send commands via the queue. Since we're running in another process, it can be awkward to get back stack traces when we have an exception: depending on your set-up, the new processes might not be able to write to the console. For that reason I create a TKinter window when an exception is thrown to report it. Finally, if you want to run this inside IDLE, be aware that IDLE on Windows doesn't seem to interact well with the multiprocessing library. A symptom of this is that when you try to spawn a process you instead get a new, empty IDLE window. If you start IDLE from the start menu instead of from the "Edit with IDLE" context menu item, it should work normally, *but* you'll find that you can't start two instances of IDLE from the start menu! To find out more, see these bugs: http://bugs.python.org/issue1201569 http://bugs.python.org/issue1529142 Weeble.

Share this post

Share on other sites
Advertisement
So the idea is to communicate with my pygame process thingy just through the pygame event queue, so that I have to sort pygame events from my events? How is this different from starting pygame in another thread, and using my own queue? Is it just that you only have to check one queue, instead of the pygame event queue and your own commands?

Share this post

Share on other sites
You *might* be able to do it simply with two threads, but my understanding is that bad things will happen if you try to render or process events on a thread other than the "main" one. By starting a whole new process for Pygame, it can do its rendering and event-processing on the main thread of its own process, while the interactive prompt gets to continue being the main thread of its own process. Also, it's easy to make a mess of things when using threads, so I'm happier working with multiple processes. I don't intend to ever do anything more complicated than reading from the queue and posting events on the helper thread, so I'm not too worried about it.

I asked around, and apparently pygame.event.post isn't entirely thread-safe, but if you instead use pygame.fastevent instead of pygame.event everywhere then it will be thread-safe.

Share this post

Share on other sites
If I remember correctly, the "main" thread from the perspective of pygame is the thread that initialized pygame (self-centered little library). So as long as you're doing all the pygame-related stuff in one thread, you should be fine on that front.

Share this post

Share on other sites

• Advertisement
• Advertisement

• Popular Contributors

1. 1
2. 2
3. 3
Rutin
15
4. 4
khawk
13
5. 5
frob
12
• Advertisement

• 9
• 9
• 11
• 11
• 23
• Forum Statistics

• Total Topics
633668
• Total Posts
3013254
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!