inputhookpyglet.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. # encoding: utf-8
  2. """
  3. Enable pyglet to be used interacive by setting PyOS_InputHook.
  4. Authors
  5. -------
  6. * Nicolas P. Rougier
  7. * Fernando Perez
  8. """
  9. #-----------------------------------------------------------------------------
  10. # Copyright (C) 2008-2011 The IPython Development Team
  11. #
  12. # Distributed under the terms of the BSD License. The full license is in
  13. # the file COPYING, distributed as part of this software.
  14. #-----------------------------------------------------------------------------
  15. #-----------------------------------------------------------------------------
  16. # Imports
  17. #-----------------------------------------------------------------------------
  18. import os
  19. import sys
  20. import time
  21. from timeit import default_timer as clock
  22. import pyglet
  23. #-----------------------------------------------------------------------------
  24. # Platform-dependent imports and functions
  25. #-----------------------------------------------------------------------------
  26. if os.name == 'posix':
  27. import select
  28. def stdin_ready():
  29. infds, outfds, erfds = select.select([sys.stdin],[],[],0)
  30. if infds:
  31. return True
  32. else:
  33. return False
  34. elif sys.platform == 'win32':
  35. import msvcrt
  36. def stdin_ready():
  37. return msvcrt.kbhit()
  38. # On linux only, window.flip() has a bug that causes an AttributeError on
  39. # window close. For details, see:
  40. # http://groups.google.com/group/pyglet-users/browse_thread/thread/47c1aab9aa4a3d23/c22f9e819826799e?#c22f9e819826799e
  41. if sys.platform.startswith('linux'):
  42. def flip(window):
  43. try:
  44. window.flip()
  45. except AttributeError:
  46. pass
  47. else:
  48. def flip(window):
  49. window.flip()
  50. #-----------------------------------------------------------------------------
  51. # Code
  52. #-----------------------------------------------------------------------------
  53. def inputhook_pyglet():
  54. """Run the pyglet event loop by processing pending events only.
  55. This keeps processing pending events until stdin is ready. After
  56. processing all pending events, a call to time.sleep is inserted. This is
  57. needed, otherwise, CPU usage is at 100%. This sleep time should be tuned
  58. though for best performance.
  59. """
  60. # We need to protect against a user pressing Control-C when IPython is
  61. # idle and this is running. We trap KeyboardInterrupt and pass.
  62. try:
  63. t = clock()
  64. while not stdin_ready():
  65. pyglet.clock.tick()
  66. for window in pyglet.app.windows:
  67. window.switch_to()
  68. window.dispatch_events()
  69. window.dispatch_event('on_draw')
  70. flip(window)
  71. # We need to sleep at this point to keep the idle CPU load
  72. # low. However, if sleep to long, GUI response is poor. As
  73. # a compromise, we watch how often GUI events are being processed
  74. # and switch between a short and long sleep time. Here are some
  75. # stats useful in helping to tune this.
  76. # time CPU load
  77. # 0.001 13%
  78. # 0.005 3%
  79. # 0.01 1.5%
  80. # 0.05 0.5%
  81. used_time = clock() - t
  82. if used_time > 10.0:
  83. # print 'Sleep for 1 s' # dbg
  84. time.sleep(1.0)
  85. elif used_time > 0.1:
  86. # Few GUI events coming in, so we can sleep longer
  87. # print 'Sleep for 0.05 s' # dbg
  88. time.sleep(0.05)
  89. else:
  90. # Many GUI events coming in, so sleep only very little
  91. time.sleep(0.001)
  92. except KeyboardInterrupt:
  93. pass
  94. return 0