~pygame/pygame/trunk

« back to all changes in this revision

Viewing changes to src/fastevent.c

  • Committer: pygame
  • Date: 2017-01-10 00:31:42 UTC
  • Revision ID: git-v1:2eea4f299a2e791f884608d7ed601558634af73c
commit 1639c41a8cb3433046882ede92c80ce69d59016b
Author: Thomas Kluyver <takowl@gmail.com>
Date:   Sun Jan 8 18:46:46 2017 +0000

    Build newer versions of libogg and libvorbis into Linux base images

    Closes #317
    Closes #323

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  pygame - Python Game Library
 
3
  Copyright (C) 2000-2001  Pete Shinners
 
4
 
 
5
  This library is free software; you can redistribute it and/or
 
6
  modify it under the terms of the GNU Library General Public
 
7
  License as published by the Free Software Foundation; either
 
8
  version 2 of the License, or (at your option) any later version.
 
9
 
 
10
  This library is distributed in the hope that it will be useful,
 
11
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
  Library General Public License for more details.
 
14
 
 
15
  You should have received a copy of the GNU Library General Public
 
16
  License along with this library; if not, write to the Free
 
17
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 
 
19
  Pete Shinners
 
20
  pete@shinners.org
 
21
*/
 
22
 
 
23
/*
 
24
 *  pygame fastevent module
 
25
 */
 
26
#define PYGAMEAPI_FASTEVENT_INTERNAL
 
27
#include "pygame.h"
 
28
#include "pgcompat.h"
 
29
#include "fastevents.h"
 
30
 
 
31
static int FE_WasInit = 0;
 
32
 
 
33
#define FE_INIT_CHECK()                                                 \
 
34
    do                                                                  \
 
35
    {                                                                   \
 
36
        if (!FE_WasInit)                                                \
 
37
            return RAISE(PyExc_SDLError,                                \
 
38
                         "fastevent system not initialized");           \
 
39
    }                                                                   \
 
40
    while (0)
 
41
 
 
42
static void
 
43
fastevent_cleanup (void)
 
44
{
 
45
    if (FE_WasInit)
 
46
    {
 
47
        FE_Quit ();
 
48
        FE_WasInit = 0;
 
49
    }
 
50
}
 
51
 
 
52
/* fastevent module functions */
 
53
 
 
54
/* DOC */ static char doc_init[] =
 
55
/* DOC */ "pygame.fastevent.init() -> None\n"
 
56
/* DOC */ "initialize pygame.fastevent.\n"
 
57
/* DOC */ ;
 
58
static PyObject *
 
59
fastevent_init (PyObject * self)
 
60
{
 
61
    VIDEO_INIT_CHECK ();
 
62
 
 
63
#ifndef WITH_THREAD
 
64
    return RAISE (PyExc_SDLError,
 
65
                  "pygame.fastevent requires a threaded Python");
 
66
#else
 
67
    if (!FE_WasInit)
 
68
    {
 
69
        if (FE_Init () == -1)
 
70
            return RAISE (PyExc_SDLError, FE_GetError ());
 
71
 
 
72
        PyGame_RegisterQuit (fastevent_cleanup);
 
73
        FE_WasInit = 1;
 
74
    }
 
75
 
 
76
    Py_RETURN_NONE;
 
77
#endif /* WITH_THREAD */
 
78
}
 
79
 
 
80
 
 
81
/* DOC */ static char doc_pump[] =
 
82
/* DOC */ "pygame.fastevent.pump() -> None\n"
 
83
/* DOC */ "update the internal messages\n"
 
84
/* DOC */ "\n"
 
85
/* DOC */ "For each frame of your game, you will need to make some sort\n"
 
86
/* DOC */ "of call to the event queue. This ensures your program can internally\n"
 
87
/* DOC */ "interact with the rest of the operating system. If you are not using\n"
 
88
/* DOC */ "other event functions in your game, you should call pump() to allow\n"
 
89
/* DOC */ "pygame to handle internal actions.\n"
 
90
/* DOC */ "\n"
 
91
/* DOC */ "There are important things that must be dealt with internally in the\n"
 
92
/* DOC */ "event queue. The main window may need to be repainted. Certain joysticks\n"
 
93
/* DOC */ "must be polled for their values. If you fail to make a call to the event\n"
 
94
/* DOC */ "queue for too long, the system may decide your program has locked up.\n"
 
95
/* DOC */ ;
 
96
static PyObject *
 
97
fastevent_pump (PyObject * self)
 
98
{
 
99
    FE_INIT_CHECK ();
 
100
    FE_PumpEvents ();
 
101
    Py_RETURN_NONE;
 
102
}
 
103
 
 
104
/* DOC */ static char doc_wait[] =
 
105
/* DOC */ "pygame.fastevent.wait() -> Event\n"
 
106
/* DOC */ "wait for an event\n"
 
107
/* DOC */ "\n"
 
108
/* DOC */ "Returns the current event on the queue. If there are no messages\n"
 
109
/* DOC */ "waiting on the queue, this will not return until one is\n"
 
110
/* DOC */ "available. Sometimes it is important to use this wait to get\n"
 
111
/* DOC */ "events from the queue, it will allow your application to idle\n"
 
112
/* DOC */ "when the user isn't doing anything with it.\n"
 
113
/* DOC */ ;
 
114
static PyObject *
 
115
fastevent_wait (PyObject * self)
 
116
{
 
117
    SDL_Event event;
 
118
    int       status;
 
119
 
 
120
    FE_INIT_CHECK ();
 
121
 
 
122
    Py_BEGIN_ALLOW_THREADS;
 
123
    status = FE_WaitEvent (&event);
 
124
    Py_END_ALLOW_THREADS;
 
125
 
 
126
    /* FE_WaitEvent will block forever on error */
 
127
    if (!status)
 
128
        return RAISE (PyExc_SDLError, "unexpected error in FE_WaitEvent!");
 
129
 
 
130
    return PyEvent_New (&event);
 
131
}
 
132
 
 
133
/* DOC */ static char doc_poll[] =
 
134
/* DOC */ "pygame.fastevent.poll() -> Event\n"
 
135
/* DOC */ "get an available event\n"
 
136
/* DOC */ "\n"
 
137
/* DOC */ "Returns next event on queue. If there is no event waiting on the\n"
 
138
/* DOC */ "queue, this will return an event with type NOEVENT.\n"
 
139
/* DOC */ ;
 
140
static PyObject *
 
141
fastevent_poll (PyObject * self)
 
142
{
 
143
    SDL_Event event;
 
144
    int       status;
 
145
 
 
146
    FE_INIT_CHECK ();
 
147
 
 
148
    status = FE_PollEvent (&event);
 
149
    if (status == 1)
 
150
        return PyEvent_New (&event);
 
151
    else
 
152
    {
 
153
        /* Check for -1 */
 
154
        return PyEvent_New (NULL);
 
155
    }
 
156
}
 
157
 
 
158
 
 
159
/* DOC */ static char doc_get[] =
 
160
/* DOC */ "pygame.fastevent.get() -> list of Events\n"
 
161
/* DOC */ "get all events from the queue\n"
 
162
/* DOC */ ;
 
163
static PyObject *
 
164
fastevent_get (PyObject * self)
 
165
{
 
166
    SDL_Event event;
 
167
    PyObject  *list, *e;
 
168
    int       status;
 
169
 
 
170
    FE_INIT_CHECK ();
 
171
 
 
172
    list = PyList_New (0);
 
173
    if (!list)
 
174
        return NULL;
 
175
 
 
176
    FE_PumpEvents ();
 
177
 
 
178
    while (1)
 
179
    {
 
180
        status = FE_PollEvent (&event);
 
181
        if (status != 1)
 
182
            break;
 
183
        e = PyEvent_New (&event);
 
184
        if (!e)
 
185
        {
 
186
            Py_DECREF (list);
 
187
            return NULL;
 
188
        }
 
189
 
 
190
        PyList_Append (list, e);
 
191
        Py_DECREF (e);
 
192
    }
 
193
 
 
194
    return list;
 
195
}
 
196
 
 
197
/*DOC*/ static char doc_post[] =
 
198
/*DOC*/ "pygame.fastevent.post(Event) -> None\n"
 
199
/*DOC*/ "place an event on the queue\n"
 
200
/*DOC*/ "\n"
 
201
/*DOC*/ "This will post your own event objects onto the event queue.\n"
 
202
/*DOC*/ "You can past any event type you want, but some care must be\n"
 
203
/*DOC*/ "taken. For example, if you post a MOUSEBUTTONDOWN event to the\n"
 
204
/*DOC*/ "queue, it is likely any code receiving the event will expect\n"
 
205
/*DOC*/ "the standard MOUSEBUTTONDOWN attributes to be available, like\n"
 
206
/*DOC*/ "'pos' and 'button'.\n"
 
207
/*DOC*/ "\n"
 
208
/*DOC*/ "Because pygame.fastevent.post() may have to wait for the queue\n"
 
209
/*DOC*/ "to empty, you can get into a dead lock if you try to append an\n"
 
210
/*DOC*/ "event on to a full queue from the thread that processes events.\n"
 
211
/*DOC*/ "For that reason I do not recommend using this function in the\n"
 
212
/*DOC*/ "main thread of an SDL program.\n"
 
213
/*DOC*/ ;
 
214
static PyObject *
 
215
fastevent_post (PyObject * self, PyObject * arg)
 
216
{
 
217
    SDL_Event     event;
 
218
    int           status;
 
219
 
 
220
    if (!PyObject_IsInstance (arg, (PyObject *) &PyEvent_Type)) {
 
221
        PyErr_Format (PyExc_TypeError, "argument 1 must be %s, not %s",
 
222
                      PyEvent_Type.tp_name, Py_TYPE(arg)->tp_name);
 
223
        return NULL;
 
224
    }
 
225
 
 
226
    FE_INIT_CHECK ();
 
227
 
 
228
    if (PyEvent_FillUserEvent ((PyEventObject *) arg, &event))
 
229
        return NULL;
 
230
 
 
231
    Py_BEGIN_ALLOW_THREADS;
 
232
    status = FE_PushEvent (&event);
 
233
    Py_END_ALLOW_THREADS;
 
234
 
 
235
    if (status != 1)
 
236
        return RAISE (PyExc_SDLError, "Unexpected error in FE_PushEvent");
 
237
 
 
238
    Py_RETURN_NONE;
 
239
}
 
240
 
 
241
static PyMethodDef _fastevent_methods[] =
 
242
{
 
243
    {"init", (PyCFunction) fastevent_init, METH_NOARGS, doc_init},
 
244
    {"get", (PyCFunction) fastevent_get, METH_NOARGS, doc_get},
 
245
    {"pump", (PyCFunction) fastevent_pump, METH_NOARGS, doc_pump},
 
246
    {"wait", (PyCFunction) fastevent_wait, METH_NOARGS, doc_wait},
 
247
    {"poll", (PyCFunction) fastevent_poll, METH_NOARGS, doc_poll},
 
248
    {"post", fastevent_post, METH_O, doc_post},
 
249
 
 
250
    {NULL, NULL, 0, NULL}
 
251
};
 
252
 
 
253
/*DOC*/ static char doc_fastevent_MODULE[] =
 
254
/*DOC*/ "pygame.fastevent is a wrapper for Bob Pendleton's fastevent\n"
 
255
/*DOC*/ "library.  It provides fast events for use in multithreaded\n"
 
256
/*DOC*/ "environments.  When using pygame.fastevent, you can not use\n"
 
257
/*DOC*/ "any of the pump, wait, poll, post, get, peek, etc. functions\n"
 
258
/*DOC*/ "from pygame.event, but you should use the Event objects.\n"
 
259
/*DOC*/ ;
 
260
MODINIT_DEFINE (fastevent)
 
261
{
 
262
    PyObject *module, *eventmodule, *dict;
 
263
    int ecode;
 
264
 
 
265
#if PY3
 
266
    static struct PyModuleDef _module = {
 
267
        PyModuleDef_HEAD_INIT,
 
268
        "fastevent",
 
269
        doc_fastevent_MODULE,
 
270
        -1,
 
271
        _fastevent_methods,
 
272
        NULL, NULL, NULL, NULL
 
273
    };
 
274
#endif
 
275
 
 
276
    /* imported needed apis; Do this first so if there is an error
 
277
       the module is not loaded.
 
278
    */
 
279
    import_pygame_base ();
 
280
    if (PyErr_Occurred ()) {
 
281
        MODINIT_ERROR;
 
282
    }
 
283
    import_pygame_event ();
 
284
    if (PyErr_Occurred ()) {
 
285
        MODINIT_ERROR;
 
286
    }
 
287
 
 
288
    /* create the module */
 
289
#if PY3
 
290
    module = PyModule_Create (&_module);
 
291
#else
 
292
    module = Py_InitModule3 (MODPREFIX "fastevent",
 
293
                             _fastevent_methods,
 
294
                             doc_fastevent_MODULE);
 
295
#endif
 
296
    if (module == NULL) {
 
297
        MODINIT_ERROR;
 
298
    }
 
299
    dict = PyModule_GetDict (module);
 
300
 
 
301
    /* add the event module functions if available */
 
302
    eventmodule = PyImport_ImportModule (IMPPREFIX "event");
 
303
    if (eventmodule)
 
304
    {
 
305
        char *NAMES[] = {"Event", "event_name", NULL};
 
306
        int  i;
 
307
 
 
308
        for (i = 0; NAMES[i]; i++)
 
309
        {
 
310
            PyObject *ref = PyObject_GetAttrString (eventmodule, NAMES[i]);
 
311
            if (ref)
 
312
            {
 
313
                ecode = PyDict_SetItemString (dict, NAMES[i], ref);
 
314
                Py_DECREF (ref);
 
315
                if (ecode == -1) {
 
316
                    DECREF_MOD(module);
 
317
                    MODINIT_ERROR;
 
318
                }
 
319
            }
 
320
            else
 
321
                PyErr_Clear ();
 
322
        }
 
323
    }
 
324
    else
 
325
    {
 
326
        PyErr_Clear ();
 
327
    }
 
328
    MODINIT_RETURN (module);
 
329
}