Spaces:
Sleeping
Sleeping
| from pyglet.window import Window | |
| from pyglet.clock import Clock | |
| from threading import Thread, Lock | |
| gl_lock = Lock() | |
| class ManagedWindow(Window): | |
| """ | |
| A pyglet window with an event loop which executes automatically | |
| in a separate thread. Behavior is added by creating a subclass | |
| which overrides setup, update, and/or draw. | |
| """ | |
| fps_limit = 30 | |
| default_win_args = {"width": 600, | |
| "height": 500, | |
| "vsync": False, | |
| "resizable": True} | |
| def __init__(self, **win_args): | |
| """ | |
| It is best not to override this function in the child | |
| class, unless you need to take additional arguments. | |
| Do any OpenGL initialization calls in setup(). | |
| """ | |
| # check if this is run from the doctester | |
| if win_args.get('runfromdoctester', False): | |
| return | |
| self.win_args = dict(self.default_win_args, **win_args) | |
| self.Thread = Thread(target=self.__event_loop__) | |
| self.Thread.start() | |
| def __event_loop__(self, **win_args): | |
| """ | |
| The event loop thread function. Do not override or call | |
| directly (it is called by __init__). | |
| """ | |
| gl_lock.acquire() | |
| try: | |
| try: | |
| super().__init__(**self.win_args) | |
| self.switch_to() | |
| self.setup() | |
| except Exception as e: | |
| print("Window initialization failed: %s" % (str(e))) | |
| self.has_exit = True | |
| finally: | |
| gl_lock.release() | |
| clock = Clock() | |
| clock.fps_limit = self.fps_limit | |
| while not self.has_exit: | |
| dt = clock.tick() | |
| gl_lock.acquire() | |
| try: | |
| try: | |
| self.switch_to() | |
| self.dispatch_events() | |
| self.clear() | |
| self.update(dt) | |
| self.draw() | |
| self.flip() | |
| except Exception as e: | |
| print("Uncaught exception in event loop: %s" % str(e)) | |
| self.has_exit = True | |
| finally: | |
| gl_lock.release() | |
| super().close() | |
| def close(self): | |
| """ | |
| Closes the window. | |
| """ | |
| self.has_exit = True | |
| def setup(self): | |
| """ | |
| Called once before the event loop begins. | |
| Override this method in a child class. This | |
| is the best place to put things like OpenGL | |
| initialization calls. | |
| """ | |
| pass | |
| def update(self, dt): | |
| """ | |
| Called before draw during each iteration of | |
| the event loop. dt is the elapsed time in | |
| seconds since the last update. OpenGL rendering | |
| calls are best put in draw() rather than here. | |
| """ | |
| pass | |
| def draw(self): | |
| """ | |
| Called after update during each iteration of | |
| the event loop. Put OpenGL rendering calls | |
| here. | |
| """ | |
| pass | |
| if __name__ == '__main__': | |
| ManagedWindow() | |