123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- 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()
|