Completed
Push — master ( 2d128b...9ed847 )
by Kyle
01:42
created

KeyEvent.__repr__()   A

Complexity

Conditions 3

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
c 0
b 0
f 0
dl 0
loc 10
rs 9.4285
1
"""
2
    This module handles user input.
3
4
    To handle user input you will likely want to use the L{event.get} function
5
    or create a subclass of L{event.App}.
6
     - L{event.get} iterates over recent events.
7
     - L{event.App} passes events to the overridable methods: ev_* and key_*.
8
9
    But there are other options such as L{event.keyWait} and L{event.isWindowClosed}.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (85/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
10
11
    A few event attributes are actually string constants.
12
    Here's a reference for those:
13
     - L{Event.type}
14
15
       'QUIT', 'KEYDOWN', 'KEYUP', 'MOUSEDOWN', 'MOUSEUP', or 'MOUSEMOTION.'
16
17
     - L{MouseButtonEvent.button} (found in L{MouseDown} and L{MouseUp} events)
18
19
       'LEFT', 'MIDDLE', 'RIGHT', 'SCROLLUP', 'SCROLLDOWN'
20
21
     - L{KeyEvent.key} (found in L{KeyDown} and L{KeyUp} events)
22
23
       'NONE', 'ESCAPE', 'BACKSPACE', 'TAB', 'ENTER', 'SHIFT', 'CONTROL',
24
       'ALT', 'PAUSE', 'CAPSLOCK', 'PAGEUP', 'PAGEDOWN', 'END', 'HOME', 'UP',
25
       'LEFT', 'RIGHT', 'DOWN', 'PRINTSCREEN', 'INSERT', 'DELETE', 'LWIN',
26
       'RWIN', 'APPS', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
27
       'KP0', 'KP1', 'KP2', 'KP3', 'KP4', 'KP5', 'KP6', 'KP7', 'KP8', 'KP9',
28
       'KPADD', 'KPSUB', 'KPDIV', 'KPMUL', 'KPDEC', 'KPENTER', 'F1', 'F2',
29
       'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12',
30
       'NUMLOCK', 'SCROLLLOCK', 'SPACE', 'CHAR'
31
32
"""
33
34
import time as _time
35
36
from tcod import ffi as _ffi
0 ignored issues
show
Configuration introduced by
The import tcod could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
37
from tcod import lib as _lib
0 ignored issues
show
Configuration introduced by
The import tcod could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
38
39
import tdl as _tdl
40
from . import style as _style
41
42
_eventQueue = []
0 ignored issues
show
Coding Style Naming introduced by
The name _eventQueue does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
43
_pushedEvents = []
0 ignored issues
show
Coding Style Naming introduced by
The name _pushedEvents does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
44
45
_mousel = 0
0 ignored issues
show
Coding Style Naming introduced by
The name _mousel does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
46
_mousem = 0
0 ignored issues
show
Coding Style Naming introduced by
The name _mousem does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
47
_mouser = 0
0 ignored issues
show
Coding Style Naming introduced by
The name _mouser does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
48
49
# this interprets the constants from libtcod and makes a key -> keyname dictionary
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (82/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
50
def _parseKeyNames(lib):
0 ignored issues
show
Coding Style Naming introduced by
The name _parseKeyNames does not conform to the function naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
51
    """
52
    returns a dictionary mapping of human readable key names to their keycodes
53
    this parses constants with the names of K_* and makes code=name pairs
54
    this is for KeyEvent.key variable and that enables things like:
55
    if (event.key == 'PAGEUP'):
56
    """
57
    _keyNames = {}
0 ignored issues
show
Comprehensibility Bug introduced by
_keyNames is re-defining a name which is already available in the outer-scope (previously defined on line 63).

It is generally a bad practice to shadow variables from the outer-scope. In most cases, this is done unintentionally and might lead to unexpected behavior:

param = 5

class Foo:
    def __init__(self, param):   # "param" would be flagged here
        self.param = param
Loading history...
Coding Style Naming introduced by
The name _keyNames does not conform to the variable naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
58
    for attr in dir(lib): # from the modules variables
59
        if attr[:6] == 'TCODK_': # get the K_* constants
60
            _keyNames[getattr(lib, attr)] = attr[6:] # and make CODE=NAME pairs
61
    return _keyNames
62
63
_keyNames = _parseKeyNames(_lib)
0 ignored issues
show
Coding Style Naming introduced by
The name _keyNames does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
64
65
class Event(object):
66
    """Base Event class.
67
68
    You can easily subclass this to make your own events.  Be sure to set
69
    the class attribute L{Event.type} for it to be passed to a custom L{App}
70
    ev_* method."""
71
    type = None
72
    """String constant representing the type of event.
73
74
    The L{App} ev_* methods depend on this attribute.
75
76
    Can be: 'QUIT', 'KEYDOWN', 'KEYUP', 'MOUSEDOWN', 'MOUSEUP', or 'MOUSEMOTION.'
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (81/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
77
    """
78
79
    def __repr__(self):
80
        """List an events public attributes when printed.
81
        """
82
        attrdict = {}
83
        for varname in dir(self):
84
            if '_' == varname[0]:
85
                continue
86
            attrdict[varname] = self.__getattribute__(varname)
87
        return '%s Event %s' % (self.__class__.__name__, repr(attrdict))
88
89
class Quit(Event):
90
    """Fired when the window is closed by the user.
91
    """
92
    __slots__ = ()
93
    type = 'QUIT'
94
95
class KeyEvent(Event):
0 ignored issues
show
Coding Style introduced by
This class should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
96
97
    def __init__(self, key='', char='', text='', shift=False,
98
                 left_alt=False, right_alt=False,
99
                 left_control=False, right_control=False,
100
                 left_meta=False, right_meta=False):
101
        # Convert keycodes into string, but use string if passed
102
        self.key = key if isinstance(key, str) else _keyNames[key]
103
        """Human readable names of the key pressed.
104
        Non special characters will show up as 'CHAR'.
105
106
        Can be one of
107
        'NONE', 'ESCAPE', 'BACKSPACE', 'TAB', 'ENTER', 'SHIFT', 'CONTROL',
108
        'ALT', 'PAUSE', 'CAPSLOCK', 'PAGEUP', 'PAGEDOWN', 'END', 'HOME', 'UP',
109
        'LEFT', 'RIGHT', 'DOWN', 'PRINTSCREEN', 'INSERT', 'DELETE', 'LWIN',
110
        'RWIN', 'APPS', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
111
        'KP0', 'KP1', 'KP2', 'KP3', 'KP4', 'KP5', 'KP6', 'KP7', 'KP8', 'KP9',
112
        'KPADD', 'KPSUB', 'KPDIV', 'KPMUL', 'KPDEC', 'KPENTER', 'F1', 'F2',
113
        'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12',
114
        'NUMLOCK', 'SCROLLLOCK', 'SPACE', 'CHAR'
115
116
        For the actual character instead of 'CHAR' use L{keychar}.
117
        @type: string"""
118
        self.char = char.replace('\x00', '') # change null to empty string
119
        """A single character string of the letter or symbol pressed.
120
121
        Special characters like delete and return are not cross-platform.
122
        L{key} or L{keychar} should be used instead for special keys.
123
        Characters are also case sensitive.
124
        @type: string"""
125
        # get the best out of self.key and self.char
126
        self.keychar = self.char if self.key == 'CHAR' else self.key
127
        """Similar to L{key} but returns a case sensitive letter or symbol
128
        instead of 'CHAR'.
129
130
        This variable makes available the widest variety of symbols and should
131
        be used for key-mappings or anywhere where a narrower sample of keys
132
        isn't needed.
133
        """
134
        self.text = text
135
136
        self.left_alt = self.leftAlt = bool(left_alt)
0 ignored issues
show
Coding Style Naming introduced by
The name leftAlt does not conform to the attribute naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
137
        """@type: boolean"""
138
        self.right_alt = self.rightAlt = bool(right_alt)
0 ignored issues
show
Coding Style Naming introduced by
The name rightAlt does not conform to the attribute naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
139
        """@type: boolean"""
140
        self.left_control = self.leftCtrl = bool(left_control)
0 ignored issues
show
Coding Style Naming introduced by
The name leftCtrl does not conform to the attribute naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
141
        """@type: boolean"""
142
        self.right_control = self.rightCtrl = bool(right_control)
0 ignored issues
show
Coding Style Naming introduced by
The name rightCtrl does not conform to the attribute naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
143
        """@type: boolean"""
144
        self.shift = bool(shift)
145
        """True if shift was held down during this event.
146
        @type: boolean"""
147
        self.alt = self.left_alt or self.right_alt
148
        """True if alt was held down during this event.
149
        @type: boolean"""
150
        self.control = self.left_control or self.right_control
151
        """True if control was held down during this event.
152
        @type: boolean"""
153
        self.left_meta = bool(left_meta)
154
        self.right_meta = bool(right_meta)
155
        self.meta = self.left_meta or self.right_meta
156
157
    def __repr__(self):
158
        parameters = []
159
        for attr in ('key', 'char', 'text', 'shift',
160
                     'left_alt', 'right_alt',
161
                     'left_control', 'right_control',
162
                     'left_meta', 'right_meta'):
163
            value = getattr(self, attr)
164
            if value:
165
                parameters.append('%s=%r' % (attr, value))
166
        return '%s(%s)' % (self.__class__.__name__, ', '.join(parameters))
167
168
class KeyDown(KeyEvent):
169
    """Fired when the user presses a key on the keyboard or a key repeats.
170
    """
171
    type = 'KEYDOWN'
172
173
class KeyUp(KeyEvent):
174
    """Fired when the user releases a key on the keyboard.
175
    """
176
    type = 'KEYUP'
177
178
_mouseNames = {1: 'LEFT', 2: 'MIDDLE', 3: 'RIGHT', 4: 'SCROLLUP', 5: 'SCROLLDOWN'}
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (82/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style Naming introduced by
The name _mouseNames does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
179
class MouseButtonEvent(Event):
0 ignored issues
show
Coding Style introduced by
This class should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
180
181
    def __init__(self, button, pos, cell):
182
        self.button = _mouseNames[button]
183
        """Can be one of
184
        'LEFT', 'MIDDLE', 'RIGHT', 'SCROLLUP', 'SCROLLDOWN'
185
        @type: string"""
186
        self.pos = pos
187
        """(x, y) position of the mouse on the screen
188
        @type: (int, int)"""
189
        self.cell = cell
190
        """(x, y) position of the mouse snapped to a cell on the root console
191
        @type: (int, int)"""
192
193
class MouseDown(MouseButtonEvent):
194
    """Fired when a mouse button is pressed."""
195
    __slots__ = ()
196
    type = 'MOUSEDOWN'
197
198
class MouseUp(MouseButtonEvent):
199
    """Fired when a mouse button is released."""
200
    __slots__ = ()
201
    type = 'MOUSEUP'
202
203
class MouseMotion(Event):
204
    """Fired when the mouse is moved."""
205
    type = 'MOUSEMOTION'
206
207
    def __init__(self, pos, cell, motion, cellmotion):
208
        self.pos = pos
209
        """(x, y) position of the mouse on the screen.
210
        type: (int, int)"""
211
        self.cell = cell
212
        """(x, y) position of the mouse snapped to a cell on the root console.
213
        type: (int, int)"""
214
        self.motion = motion
215
        """(x, y) motion of the mouse on the screen.
216
        type: (int, int)"""
217
        self.cellmotion = cellmotion
218
        """(x, y) mostion of the mouse moving over cells on the root console.
219
        type: (int, int)"""
220
221
class App(object):
222
    """
223
    Application framework.
224
225
     - ev_*: Events are passed to methods based on their L{Event.type} attribute.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (81/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
226
       If an event type is 'KEYDOWN' the ev_KEYDOWN method will be called
227
       with the event instance as a parameter.
228
229
     - key_*: When a key is pressed another method will be called based on the
230
       L{KeyEvent.key} attribute.  For example the 'ENTER' key will call key_ENTER
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (82/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
231
       with the associated L{KeyDown} event as its parameter.
232
233
     - L{update}: This method is called every loop.  It is passed a single
234
       parameter detailing the time in seconds since the last update
235
       (often known as deltaTime.)
236
237
       You may want to call drawing routines in this method followed by
238
       L{tdl.flush}.
239
240
    """
241
    __slots__ = ('__running', '__prevTime')
242
243
    def ev_QUIT(self, event):
0 ignored issues
show
Coding Style Naming introduced by
The name ev_QUIT does not conform to the method naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Unused Code introduced by
The argument event seems to be unused.
Loading history...
Coding Style introduced by
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
244
        """Unless overridden this method raises a SystemExit exception closing
245
        the program."""
246
        raise SystemExit()
247
248
    def ev_KEYDOWN(self, event):
0 ignored issues
show
Coding Style Naming introduced by
The name ev_KEYDOWN does not conform to the method naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
249
        """Override this method to handle a L{KeyDown} event."""
250
251
    def ev_KEYUP(self, event):
0 ignored issues
show
Coding Style Naming introduced by
The name ev_KEYUP does not conform to the method naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
252
        """Override this method to handle a L{KeyUp} event."""
253
254
    def ev_MOUSEDOWN(self, event):
0 ignored issues
show
Coding Style Naming introduced by
The name ev_MOUSEDOWN does not conform to the method naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
255
        """Override this method to handle a L{MouseDown} event."""
256
257
    def ev_MOUSEUP(self, event):
0 ignored issues
show
Coding Style Naming introduced by
The name ev_MOUSEUP does not conform to the method naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
258
        """Override this method to handle a L{MouseUp} event."""
259
260
    def ev_MOUSEMOTION(self, event):
0 ignored issues
show
Coding Style Naming introduced by
The name ev_MOUSEMOTION does not conform to the method naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
261
        """Override this method to handle a L{MouseMotion} event."""
262
263
    def update(self, deltaTime):
0 ignored issues
show
Coding Style Naming introduced by
The name deltaTime does not conform to the argument naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
264
        """Override this method to handle per frame logic and drawing.
265
266
        @type deltaTime: float
267
        @param deltaTime: This parameter tells the amount of time passed since
268
                          the last call measured in seconds as a floating point
269
                          number.
270
271
                          You can use this variable to make your program
272
                          frame rate independent.
273
                          Use this parameter to adjust the speed of motion,
274
                          timers, and other game logic.
275
        """
276
        pass
277
278
    def suspend(self):
279
        """When called the App will begin to return control to where
280
        L{App.run} was called.
281
282
        Some further events are processed and the L{App.update} method will be
283
        called one last time before exiting
284
        (unless suspended during a call to L{App.update}.)
285
        """
286
        self.__running = False
0 ignored issues
show
Coding Style introduced by
The attribute __running was defined outside __init__.

It is generally a good practice to initialize all attributes to default values in the __init__ method:

class Foo:
    def __init__(self, x=None):
        self.x = x
Loading history...
287
288
    def run(self):
289
        """Delegate control over to this App instance.  This function will
290
        process all events and send them to the special methods ev_* and key_*.
291
292
        A call to L{App.suspend} will return the control flow back to where
293
        this function is called.  And then the App can be run again.
294
        But a single App instance can not be run multiple times simultaneously.
295
        """
296
        if getattr(self, '_App__running', False):
297
            raise _tdl.TDLError('An App can not be run multiple times simultaneously')
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (86/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
298
        self.__running = True
0 ignored issues
show
Coding Style introduced by
The attribute __running was defined outside __init__.

It is generally a good practice to initialize all attributes to default values in the __init__ method:

class Foo:
    def __init__(self, x=None):
        self.x = x
Loading history...
299
        while self.__running:
300
            self.runOnce()
301
302
    def run_once(self):
303
        """Pump events to this App instance and then return.
304
305
        This works in the way described in L{App.run} except it immediately
306
        returns after the first L{update} call.
307
308
        Having multiple L{App} instances and selectively calling runOnce on
309
        them is a decent way to create a state machine.
310
        """
311
        if not hasattr(self, '_App__prevTime'):
312
            self.__prevTime = _time.clock() # initiate __prevTime
0 ignored issues
show
Coding Style Naming introduced by
The name __prevTime does not conform to the attribute naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style introduced by
The attribute __prevTime was defined outside __init__.

It is generally a good practice to initialize all attributes to default values in the __init__ method:

class Foo:
    def __init__(self, x=None):
        self.x = x
Loading history...
313
        for event in get():
314
            if event.type: # exclude custom events with a blank type variable
315
                # call the ev_* methods
316
                method = 'ev_%s' % event.type # ev_TYPE
317
                getattr(self, method)(event)
318
            if event.type == 'KEYDOWN':
319
                # call the key_* methods
320
                method = 'key_%s' % event.key # key_KEYNAME
321
                if hasattr(self, method): # silently exclude undefined methods
322
                    getattr(self, method)(event)
323
        newTime = _time.clock()
0 ignored issues
show
Coding Style Naming introduced by
The name newTime does not conform to the variable naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
324
        self.update(newTime - self.__prevTime)
325
        self.__prevTime = newTime
0 ignored issues
show
Coding Style introduced by
The attribute __prevTime was defined outside __init__.

It is generally a good practice to initialize all attributes to default values in the __init__ method:

class Foo:
    def __init__(self, x=None):
        self.x = x
Loading history...
326
        #_tdl.flush()
327
328
def _processEvents():
0 ignored issues
show
Coding Style Naming introduced by
The name _processEvents does not conform to the function naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
329
    """Flushes the event queue from libtcod into the global list _eventQueue"""
330
    global _mousel, _mousem, _mouser, _eventsflushed, _pushedEvents
0 ignored issues
show
Coding Style Naming introduced by
The name _mousel does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
The name _mousem does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
The name _mouser does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
The name _eventsflushed does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
The name _pushedEvents does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Bug introduced by
Global variable '_eventsflushed' undefined at the module level
Loading history...
331
    _eventsflushed = True
332
    events = _pushedEvents # get events from event.push
333
    _pushedEvents = [] # then clear the pushed events queue
334
335
    mouse = _ffi.new('TCOD_mouse_t *')
336
    libkey = _ffi.new('TCOD_key_t *')
337
    while 1:
338
        libevent = _lib.TCOD_sys_check_for_event(_lib.TCOD_EVENT_ANY, libkey, mouse)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (84/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
339
        if not libevent: # no more events from libtcod
340
            break
341
342
        #if mouse.dx or mouse.dy:
343
        if libevent & _lib.TCOD_EVENT_MOUSE_MOVE:
344
            events.append(MouseMotion((mouse.x, mouse.y),
345
                                      (mouse.cx, mouse.cy),
346
                                      (mouse.dx, mouse.dy),
347
                                      (mouse.dcx, mouse.dcy)))
348
349
        mousepos = ((mouse.x, mouse.y), (mouse.cx, mouse.cy))
350
351
        for oldstate, newstate, released, button in \
352
            zip((_mousel, _mousem, _mouser),
353
                (mouse.lbutton, mouse.mbutton, mouse.rbutton),
354
                (mouse.lbutton_pressed, mouse.mbutton_pressed,
355
                 mouse.rbutton_pressed),
356
                (1, 2, 3)):
357
            if released:
358
                if not oldstate:
359
                    events.append(MouseDown(button, *mousepos))
360
                events.append(MouseUp(button, *mousepos))
361
                if newstate:
362
                    events.append(MouseDown(button, *mousepos))
363
            elif newstate and not oldstate:
364
                events.append(MouseDown(button, *mousepos))
365
366
        if mouse.wheel_up:
367
            events.append(MouseDown(4, *mousepos))
368
        if mouse.wheel_down:
369
            events.append(MouseDown(5, *mousepos))
370
371
        _mousel = mouse.lbutton
372
        _mousem = mouse.mbutton
373
        _mouser = mouse.rbutton
374
375
        if libkey.vk == _lib.TCODK_NONE:
376
            break
377
        if libkey.pressed:
378
            keyevent = KeyDown
379
        else:
380
            keyevent = KeyUp
381
        events.append(
382
            keyevent(
383
                libkey.vk,
384
                libkey.c.decode('ascii', errors='ignore'),
385
                _ffi.string(libkey.text).decode('utf-8'),
386
                libkey.shift,
387
                libkey.lalt,
388
                libkey.ralt,
389
                libkey.lctrl,
390
                libkey.rctrl,
391
                libkey.lmeta,
392
                libkey.rmeta,
393
                )
394
            )
395
396
    if _lib.TCOD_console_is_window_closed():
397
        events.append(Quit())
398
399
    _eventQueue.extend(events)
400
401
def get():
402
    """Flushes the event queue and returns the list of events.
403
404
    This function returns L{Event} objects that can be identified by their
405
    type attribute or their class.
406
407
    @rtype: iterator
408
    @return: Returns an iterable of objects derived from L{Event} or anything
409
             put in a L{push} call.  If the iterator is deleted or otherwise
410
             interrupted before finishing the excess items are preserved for the
411
             next call.
412
    """
413
    _processEvents()
414
    return _event_generator()
415
416
def _event_generator():
0 ignored issues
show
Coding Style introduced by
This function should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
417
    while _eventQueue:
418
        # if there is an interruption the rest of the events stay untouched
419
        # this means you can break out of a event.get loop without losing
420
        # the leftover events
421
        yield(_eventQueue.pop(0))
0 ignored issues
show
Unused Code Coding Style introduced by
There is an unnecessary parenthesis after yield.
Loading history...
422
    raise StopIteration()
423
424
425
def wait(timeout=None, flush=True):
426
    """Wait for an event.
427
428
    @type timeout: int or None
429
    @param timeout: The time in seconds that this function will wait before
430
                    giving up and returning None.
431
432
                    With the default value of None, this will block forever.
433
    @type flush: boolean
434
    @param flush: If True a call to L{tdl.flush} will be made before listening
435
                  for events.
436
    @rtype: L{Event} or None
437
    @return: Returns an instance derived from L{Event}, or None if the function
438
             has timed out.
439
             Anything added via L{push} will also be returned.
440
441
    @since: 1.4.0
442
    """
443
    if timeout is not None:
444
        timeout = timeout + _time.clock() # timeout at this time
445
    while True:
446
        if _eventQueue:
447
            return _eventQueue.pop(0)
448
        if flush:
449
            # a full 'round' of events need to be processed before flushing
450
            _tdl.flush()
451
        if timeout and _time.clock() >= timeout:
452
            return None # return None on timeout
453
        _time.sleep(0.001) # sleep 1ms
454
        _processEvents()
455
456
457
def push(event):
458
    """Push an event into the event buffer.
459
460
    @type event: L{Event}-like object
461
    @param event: The event will be available on the next call to L{event.get}.
462
                  An event pushed in the middle of a L{get} will not show until
463
                  the next time L{get} called preventing push related
464
                  infinite loops.
465
466
                  This object should at least have a 'type' attribute.
467
    """
468
    _pushedEvents.append(event)
469
470
def key_wait():
471
    """Waits until the user presses a key.
472
    Then returns a L{KeyDown} event.
473
474
    Key events will repeat if held down.
475
476
    A click to close the window will be converted into an Alt+F4 KeyDown event.
477
478
    @rtype: L{KeyDown}
479
    """
480
    while 1:
481
        for event in get():
482
            if event.type == 'KEYDOWN':
483
                return event
484
            if event.type == 'QUIT':
485
                # convert QUIT into alt+F4
486
                return KeyDown('F4', '', True, False, True, False, False)
487
        _time.sleep(.001)
488
489
def set_key_repeat(delay=500, interval=0):
0 ignored issues
show
Unused Code introduced by
The argument interval seems to be unused.
Loading history...
Unused Code introduced by
The argument delay seems to be unused.
Loading history...
490
    """Does nothing.
491
    """
492
    pass
493
494
def is_window_closed():
495
    """Returns True if the exit button on the window has been clicked and
496
    stays True afterwards.
497
498
    @rtype: boolean
499
    """
500
    return _lib.TCOD_console_is_window_closed()
501
502
__all__ = [_var for _var in locals().keys() if _var[0] != '_']
503
504
App.runOnce = _style.backport(App.run_once)
505
keyWait = _style.backport(key_wait)
0 ignored issues
show
Coding Style Naming introduced by
The name keyWait does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
506
setKeyRepeat = _style.backport(set_key_repeat)
0 ignored issues
show
Coding Style Naming introduced by
The name setKeyRepeat does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
507
isWindowClosed = _style.backport(is_window_closed)
0 ignored issues
show
Coding Style Naming introduced by
The name isWindowClosed does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
508
509