[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[pygame] Pygame exception on applicaiton exit



I have a simple script that generates an image and then rotates the palette in a thread.
The user can press any key to quit the application. Everything runs fine
except when the applications quits it raises an exception:
python.exe has encountered a problem and needs to close.
(Debug) (Close)
I chose debug and MS Visual Studio shows me this exception:
Unhandled exception in python.exe (SURFACE.PYD): 0xC0000005: Access Violation.
The problem seems to happen in the thread because I call screen.set_palette().
Again, it's weird because the program works fine with the palette rotation in the thread, but only
gives me this exception when I quit. If I pull the palette rotation out of the thread then I don't get
the exception.


I have included two test scripts which demonstrate the problem with palette rotation in a thread.
The first test script rotates the palette in a thread and will raise an exception when the program exits.
The second version has the palette rotation commented out of the thread. The thread still runs, but
it does nothing. Palette rotation is instead done in a loop in the main process.


I'm using Python 2.3.4 and Pygame 1.6.

I can't think of any way to narrow down the problem and further. Does anyone have
any suggestions? They will be appreciated.


Yours,
Noah

----- 8< ----- 8< ----- This version raises an exception on exit ----- 8< ----- 8< -----
#!/usr/bin/env python
import time, threading
import pygame, pygame.image
from pygame.locals import *


class roller (threading.Thread):
"""This runs a function in a loop in a thread."""
def __init__(self, interval, function, args=[], kwargs={}):
"""The interval parameter defines time between each call to the function."""
threading.Thread.__init__(self)
self.interval = interval
self.function = function
self.args = args
self.kwargs = kwargs
self.finished = threading.Event()
def cancel(self):
"""Stop the roller."""
self.finished.set()
def run(self):
while not self.finished.isSet():
self.finished.wait(self.interval)
self.function(*self.args, **self.kwargs)
def build_palette(step):
loop = range(256)
ramp = [abs((x+step*3)%511-255) for x in loop]
return [(ramp[x], ramp[(x+32)%256], (x+step)%256) for x in loop]


def make_image (surf, size):
   for y in range(size[1]):
       for x in range (size[0]):
           color = int ((x * y) % 255)
           surf.set_at ((x,y), surf.get_palette_at(color))
   return surf

def rotate_screen_palette (screen):
   screen.set_palette (build_palette((time.time()*100)%511))

def main():
   pygame.init()
   pygame.mouse.set_visible(False)
   screen = pygame.display.set_mode((320, 240), 0, 8)
   screen.set_palette(build_palette(1))
   image = screen.convert()
   make_image (image, (320,240))
   screen.blit(image, (0,0))

   # This starts the palette rotation thread.
   r = roller (0.01, rotate_screen_palette, (screen,))
   r.start()

   while pygame.event.poll().type not in (QUIT, KEYDOWN, MOUSEBUTTONDOWN):
       time.sleep (1)
   r.cancel()
   pygame.quit()

if __name__ == '__main__':
   main()

----- 8< ----- 8< ----- This version exits without any exceptions ----- 8< ----- 8< -----

#!/usr/bin/env python
import time, threading
import pygame, pygame.image
from pygame.locals import *

class roller (threading.Thread):
"""This runs a function in a loop in a thread."""
def __init__(self, interval, function, args=[], kwargs={}):
"""The interval parameter defines time between each call to the function."""
threading.Thread.__init__(self)
self.interval = interval
self.function = function
self.args = args
self.kwargs = kwargs
self.finished = threading.Event()
def cancel(self):
"""Stop the roller."""
self.finished.set()
def run(self):
while not self.finished.isSet():
self.finished.wait(self.interval)
self.function(*self.args, **self.kwargs)
def build_palette(step):
loop = range(256)
ramp = [abs((x+step*3)%511-255) for x in loop]
return [(ramp[x], ramp[(x+32)%256], (x+step)%256) for x in loop]


def make_image (surf, size):
   for y in range(size[1]):
       for x in range (size[0]):
           color = int ((x * y) % 255)
           surf.set_at ((x,y), surf.get_palette_at(color))
   return surf

def rotate_screen_palette (screen):
   # screen.set_palette (build_palette((time.time()*100)%511))
   pass

def main():
   pygame.init()
   pygame.mouse.set_visible(False)
   screen = pygame.display.set_mode((320, 240), 0, 8)
   screen.set_palette(build_palette(1))
   image = screen.convert()
   make_image (image, (320,240))
   screen.blit(image, (0,0))

   # This starts the palette rotation thread.
   r = roller (0.01, rotate_screen_palette, (screen,))
   r.start()

   while pygame.event.poll().type not in (QUIT, KEYDOWN, MOUSEBUTTONDOWN):
       time.sleep (0.01)
       screen.set_palette (build_palette((time.time()*100)%511))
   r.cancel()
   pygame.quit()

if __name__ == '__main__':
   main()