~manuq/+junk/manuqs_interactives

« back to all changes in this revision

Viewing changes to casa_tomada_2/pyglet/app/__init__.py

  • Committer: Manuel Quiñones
  • Date: 2008-07-07 06:48:54 UTC
  • Revision ID: manuel.por.aca@gmail.com-20080707064854-0dpwpz7at6atdne3
Import of casa_tomada_2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# ----------------------------------------------------------------------------
 
2
# pyglet
 
3
# Copyright (c) 2006-2008 Alex Holkner
 
4
# All rights reserved.
 
5
 
6
# Redistribution and use in source and binary forms, with or without
 
7
# modification, are permitted provided that the following conditions 
 
8
# are met:
 
9
#
 
10
#  * Redistributions of source code must retain the above copyright
 
11
#    notice, this list of conditions and the following disclaimer.
 
12
#  * Redistributions in binary form must reproduce the above copyright 
 
13
#    notice, this list of conditions and the following disclaimer in
 
14
#    the documentation and/or other materials provided with the
 
15
#    distribution.
 
16
#  * Neither the name of pyglet nor the names of its
 
17
#    contributors may be used to endorse or promote products
 
18
#    derived from this software without specific prior written
 
19
#    permission.
 
20
#
 
21
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
22
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
23
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 
24
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 
25
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 
26
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 
27
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
28
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 
29
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
30
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 
31
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
32
# POSSIBILITY OF SUCH DAMAGE.
 
33
# ----------------------------------------------------------------------------
 
34
 
 
35
'''Application-wide functionality.
 
36
 
 
37
Most applications need only call `run` after creating one or more windows
 
38
to begin processing events.  For example, a simple application consisting of
 
39
one window is::
 
40
 
 
41
    from pyglet import app
 
42
    from pyglet import window
 
43
 
 
44
    win = window.Window()
 
45
    app.run()
 
46
 
 
47
To handle events on the main event loop, instantiate it manually.  The
 
48
following example exists the application as soon as any window is closed (the
 
49
default policy is to wait until all windows are closed)::
 
50
 
 
51
    event_loop = app.EventLoop()
 
52
 
 
53
    @event_loop.event
 
54
    def on_window_close(window):
 
55
        event_loop.exit()
 
56
 
 
57
:since: pyglet 1.1
 
58
'''
 
59
 
 
60
__docformat__ = 'restructuredtext'
 
61
__version__ = '$Id: __init__.py 2049 2008-05-02 01:50:36Z Alex.Holkner $'
 
62
 
 
63
import sys
 
64
import weakref
 
65
 
 
66
from pyglet import clock
 
67
from pyglet import event
 
68
 
 
69
_is_epydoc = hasattr(sys, 'is_epydoc') and sys.is_epydoc
 
70
 
 
71
class WeakSet(object):
 
72
    '''Set of objects, referenced weakly.
 
73
 
 
74
    Adding an object to this set does not prevent it from being garbage
 
75
    collected.  Upon being garbage collected, the object is automatically
 
76
    removed from the set.
 
77
    '''
 
78
    def __init__(self):
 
79
        self._dict = weakref.WeakKeyDictionary()
 
80
 
 
81
    def add(self, value):
 
82
        self._dict[value] = True
 
83
 
 
84
    def remove(self, value):
 
85
        del self._dict[value]
 
86
 
 
87
    def __iter__(self):
 
88
        for key in self._dict.keys():
 
89
            yield key
 
90
 
 
91
    def __contains__(self, other):
 
92
        return other in self._dict
 
93
 
 
94
    def __len__(self):
 
95
        return len(self._dict)
 
96
 
 
97
#: Set of all open displays.  Instances of `Display` are automatically added
 
98
#: to this set upon construction.  The set uses weak references, so displays
 
99
#: are removed from the set when they are no longer referenced.
 
100
#:
 
101
#: :type: `WeakSet`
 
102
displays = WeakSet()
 
103
 
 
104
#: Set of all open windows (including invisible windows).  Instances of
 
105
#: `Window` are automatically added to this set upon construction.  The set
 
106
#: uses weak references, so windows are removed from the set when they are no
 
107
#: longer referenced or are closed explicitly.
 
108
#:
 
109
#: :type: `WeakSet`
 
110
windows = WeakSet()
 
111
 
 
112
 
 
113
class BaseEventLoop(event.EventDispatcher):
 
114
    '''The main run loop of the application.
 
115
 
 
116
    Calling `run` begins the application event loop, which processes
 
117
    operating system events, calls `pyglet.clock.tick` to call scheduled
 
118
    functions and calls `pyglet.window.Window.on_draw` and
 
119
    `pyglet.window.Window.flip` to update window contents.
 
120
 
 
121
    Applications can subclass `EventLoop` and override certain methods
 
122
    to integrate another framework's run loop, or to customise processing
 
123
    in some other way.  You should not in general override `run`, as
 
124
    this method contains platform-specific code that ensures the application
 
125
    remains responsive to the user while keeping CPU usage to a minimum.
 
126
    '''
 
127
 
 
128
    #: Flag indicating if the event loop will exit in the next iteration.
 
129
    #: This is
 
130
    has_exit = False
 
131
 
 
132
    def run(self):
 
133
        '''Begin processing events, scheduled functions and window updates.
 
134
 
 
135
        This method returns when `has_exit` is set to True.
 
136
 
 
137
        Developers are discouraged from overriding this method, as the
 
138
        implementation is platform-specific.
 
139
        '''
 
140
        raise NotImplementedError('abstract')
 
141
 
 
142
    def _setup(self):
 
143
        global event_loop
 
144
        event_loop = self
 
145
 
 
146
        # Disable event queuing for dispatch_events
 
147
        from pyglet.window import Window
 
148
        Window._enable_event_queue = False
 
149
        
 
150
        # Dispatch pending events
 
151
        for window in windows:
 
152
            window.switch_to()
 
153
            window.dispatch_pending_events()
 
154
 
 
155
    def _idle_chance(self):
 
156
        '''If timeout has expired, manually force an idle loop.
 
157
 
 
158
        Called by window that have blocked the event loop (e.g. during
 
159
        resizing).
 
160
        '''
 
161
 
 
162
    def idle(self):
 
163
        '''Called during each iteration of the event loop.
 
164
 
 
165
        The method is called immediately after any window events (i.e., after
 
166
        any user input).  The method can return a duration after which
 
167
        the idle method will be called again.  The method may be called
 
168
        earlier if the user creates more input events.  The method
 
169
        can return `None` to only wait for user events.
 
170
 
 
171
        For example, return ``1.0`` to have the idle method called every
 
172
        second, or immediately after any user events.
 
173
 
 
174
        The default implementation dispatches the
 
175
        `pyglet.window.Window.on_draw` event for all windows and uses
 
176
        `pyglet.clock.tick` and `pyglet.clock.get_sleep_time` on the default
 
177
        clock to determine the return value.
 
178
 
 
179
        This method should be overridden by advanced users only.  To have
 
180
        code execute at regular intervals, use the
 
181
        `pyglet.clock.schedule` methods.
 
182
 
 
183
        :rtype: float
 
184
        :return: The number of seconds before the idle method should
 
185
            be called again, or `None` to block for user input.
 
186
        '''
 
187
        dt = clock.tick(True)
 
188
 
 
189
        # Redraw all windows
 
190
        for window in windows:
 
191
            if window.invalid:
 
192
                window.switch_to()
 
193
                window.dispatch_event('on_draw')
 
194
                window.flip()
 
195
 
 
196
        # Update timout
 
197
        return clock.get_sleep_time(True)
 
198
 
 
199
    def exit(self):
 
200
        '''Safely exit the event loop at the end of the current iteration.
 
201
 
 
202
        This method is convenience for setting `has_exit` to ``True``.
 
203
        '''
 
204
        self.has_exit = True
 
205
 
 
206
    def on_window_close(self, window):
 
207
        '''Default window close handler.'''
 
208
        if not windows:
 
209
            self.exit()
 
210
 
 
211
    if _is_epydoc:
 
212
        def on_window_close(window):
 
213
            '''A window was closed.
 
214
 
 
215
            This event is dispatched when a window is closed.  It is not
 
216
            dispatched if the window's close button was pressed but the
 
217
            window did not close.
 
218
 
 
219
            The default handler calls `exit` if no more windows are open.  You
 
220
            can override this handler to base your application exit on some
 
221
            other policy.
 
222
 
 
223
            :event:
 
224
            '''
 
225
 
 
226
        def on_enter():
 
227
            '''The event loop is about to begin.
 
228
 
 
229
            This is dispatched when the event loop is prepared to enter
 
230
            the main run loop, and represents the last chance for an 
 
231
            application to initialise itself.
 
232
 
 
233
            :event:
 
234
            '''
 
235
 
 
236
        def on_exit():
 
237
            '''The event loop is about to exit.
 
238
 
 
239
            After dispatching this event, the `run` method returns (the
 
240
            application may not actually exit if you have more code
 
241
            following the `run` invocation).
 
242
 
 
243
            :event:
 
244
            '''
 
245
 
 
246
BaseEventLoop.register_event_type('on_window_close')
 
247
BaseEventLoop.register_event_type('on_enter')
 
248
BaseEventLoop.register_event_type('on_exit')
 
249
 
 
250
#: The global event loop.  Set to the correct instance when an `EventLoop` is
 
251
#: started.
 
252
#:
 
253
#: :type: `EventLoop`
 
254
event_loop = None
 
255
 
 
256
def run():
 
257
    '''Begin processing events, scheduled functions and window updates.
 
258
 
 
259
    This is a convenience function, equivalent to::
 
260
 
 
261
        EventLoop().run()
 
262
 
 
263
    '''
 
264
    EventLoop().run()
 
265
 
 
266
def exit():
 
267
    '''Exit the application event loop.
 
268
 
 
269
    Causes the application event loop to finish, if an event loop is currently
 
270
    running.  The application may not necessarily exit (for example, there may
 
271
    be additional code following the `run` invocation).
 
272
 
 
273
    This is a convenience function, equivalent to::
 
274
 
 
275
        event_loop.exit()
 
276
 
 
277
    '''
 
278
    if event_loop:
 
279
        event_loop.exit()
 
280
 
 
281
if _is_epydoc:
 
282
    EventLoop = BaseEventLoop
 
283
    EventLoop.__name__ = 'EventLoop'
 
284
    del BaseEventLoop
 
285
else:
 
286
    # Permit cyclic import.
 
287
    import pyglet
 
288
    pyglet.app = sys.modules[__name__]
 
289
 
 
290
    if sys.platform == 'darwin':
 
291
        from pyglet.app.carbon import CarbonEventLoop as EventLoop
 
292
    elif sys.platform in ('win32', 'cygwin'):
 
293
        from pyglet.app.win32 import Win32EventLoop as EventLoop
 
294
    else:
 
295
        from pyglet.app.xlib import XlibEventLoop as EventLoop
 
296
 
 
297