2828 'KPADD', 'KPSUB', 'KPDIV', 'KPMUL', 'KPDEC', 'KPENTER', 'F1', 'F2',
2929 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12',
3030 'NUMLOCK', 'SCROLLLOCK', 'SPACE', 'CHAR'
31+
3132"""
3233
34+ from __future__ import division
35+
3336import time as _time
3437
3538from tcod import ffi as _ffi
4548_mousem = 0
4649_mouser = 0
4750
48- # this interpets the constants from libtcod and makes a key -> keyname dictionary
51+ # this interprets the constants from libtcod and makes a key -> keyname dictionary
4952def _parseKeyNames (lib ):
5053 """
5154 returns a dictionary mapping of human readable key names to their keycodes
@@ -67,7 +70,6 @@ class Event(object):
6770 You can easily subclass this to make your own events. Be sure to set
6871 the class attribute L{Event.type} for it to be passed to a custom L{App}
6972 ev_* method."""
70- __slots__ = ('__weakref__' ,)
7173 type = None
7274 """String constant representing the type of event.
7375
@@ -93,9 +95,7 @@ class Quit(Event):
9395 type = 'QUIT'
9496
9597class KeyEvent (Event ):
96- __slots__ = ('key' , 'char' , 'keychar' , 'shift' , 'alt' , 'control' ,
97- 'leftAlt' , 'leftCtrl' , 'rightAlt' , 'rightCtrl' )
98-
98+
9999 def __init__ (self , key , char , lalt , lctrl , ralt , rctrl , shift ):
100100 # Convert keycodes into string, but use string if passed
101101 self .key = key if isinstance (key , str ) else _keyNames [key ]
@@ -152,19 +152,16 @@ def __init__(self, key, char, lalt, lctrl, ralt, rctrl, shift):
152152class KeyDown (KeyEvent ):
153153 """Fired when the user presses a key on the keyboard or a key repeats.
154154 """
155- __slots__ = ()
156155 type = 'KEYDOWN'
157156
158157class KeyUp (KeyEvent ):
159158 """Fired when the user releases a key on the keyboard.
160159 """
161- __slots__ = ()
162160 type = 'KEYUP'
163161
164162_mouseNames = {1 : 'LEFT' , 2 : 'MIDDLE' , 3 : 'RIGHT' , 4 : 'SCROLLUP' , 5 : 'SCROLLDOWN' }
165163class MouseButtonEvent (Event ):
166- __slots__ = ('button' , 'pos' , 'cell' )
167-
164+
168165 def __init__ (self , button , pos , cell ):
169166 self .button = _mouseNames [button ]
170167 """Can be one of
@@ -189,7 +186,6 @@ class MouseUp(MouseButtonEvent):
189186
190187class MouseMotion (Event ):
191188 """Fired when the mouse is moved."""
192- __slots__ = ('pos' , 'motion' , 'cell' , 'cellmotion' )
193189 type = 'MOUSEMOTION'
194190
195191 def __init__ (self , pos , cell , motion , cellmotion ):
@@ -224,6 +220,7 @@ class App(object):
224220
225221 You may want to call drawing routines in this method followed by
226222 L{tdl.flush}.
223+
227224 """
228225 __slots__ = ('__running' , '__prevTime' )
229226
@@ -311,7 +308,7 @@ def run_once(self):
311308 self .update (newTime - self .__prevTime )
312309 self .__prevTime = newTime
313310 #_tdl.flush()
314-
311+
315312def _processEvents ():
316313 """Flushes the event queue from libtcod into the global list _eventQueue"""
317314 global _mousel , _mousem , _mouser , _eventsflushed , _pushedEvents
@@ -377,7 +374,7 @@ def _processEvents():
377374def get ():
378375 """Flushes the event queue and returns the list of events.
379376
380- This function returns L{Event} objects that can be indentified by their
377+ This function returns L{Event} objects that can be identified by their
381378 type attribute or their class.
382379
383380 @rtype: iterator
@@ -386,15 +383,53 @@ def get():
386383 interrupted before finishing the excess items are preserved for the
387384 next call.
388385 """
389- def eventGenerator ():
390- while _eventQueue :
391- # if there is an interruption the rest of the events stay untouched
392- # this means you can break out of a event.get loop without losing
393- # the leftover events
394- yield (_eventQueue .pop (0 ))
395- raise StopIteration ()
396386 _processEvents ()
397- return eventGenerator ()
387+ return _event_generator ()
388+
389+ def _event_generator ():
390+ while _eventQueue :
391+ # if there is an interruption the rest of the events stay untouched
392+ # this means you can break out of a event.get loop without losing
393+ # the leftover events
394+ yield (_eventQueue .pop (0 ))
395+ raise StopIteration ()
396+
397+
398+ def wait (timeout = None , filter = None , flush = True ):
399+ """Wait for an event.
400+
401+ @type timeout: int or None
402+ @param timeout:
403+ @type filter: collection or None
404+ @param filter: A collection of types to return.
405+
406+ For example: filter={'KEYUP', 'KEYDOWN', 'QUIT'},
407+ will only return Key events and L{Quit}.
408+ All other events will be discarded.
409+ @type flush: boolean
410+ @param flush: If True a call to L{tdl.flush} will be made before listening
411+ for events.
412+ @rtype: L{Event} or None
413+ @return: Returns an instance derived from L{Event} or anything
414+ put in a L{push} call that matches the filter.
415+
416+ @since: 1.4.0
417+ """
418+ if timeout is not None :
419+ timeout = timeout / 1000 + _time .clock () # timeout at this time
420+ while True :
421+ for event in _event_generator ():
422+ if filter and event .type not in filter :
423+ continue
424+ return event
425+ if flush :
426+ # a full 'round' of events need to be processed before flushing
427+ _tdl .flush ()
428+ if timeout and _time .clock () >= timeout :
429+ return None # return None on timeout
430+ _time .sleep (0.001 ) # sleep 1ms
431+ _processEvents ()
432+
398433
399434def push (event ):
400435 """Push an event into the event buffer.
@@ -404,6 +439,8 @@ def push(event):
404439 An event pushed in the middle of a L{get} will not show until
405440 the next time L{get} called preventing push related
406441 infinite loops.
442+
443+ This object should at least have a 'type' attribute.
407444 """
408445 _pushedEvents .append (event )
409446
@@ -455,3 +492,4 @@ def is_window_closed():
455492keyWait = _style .backport (key_wait )
456493setKeyRepeat = _style .backport (set_key_repeat )
457494isWindowClosed = _style .backport (is_window_closed )
495+
0 commit comments