/*
pygame - Python Game Library
Copyright (C) 2000-2001 Pete Shinners
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Pete Shinners
pete@shinners.org
*/
/*
* pygame fastevent module
*/
#define PYGAMEAPI_FASTEVENT_INTERNAL
#include "pygame.h"
#include "fastevents.h"
static int FE_WasInit = 0;
#define FE_INIT_CHECK() \
do { \
if (!FE_WasInit) { \
return RAISE(PyExc_SDLError, "fastevent system not initialized"); \
} \
} while (0)
static void fastevent_cleanup(void)
{
if (FE_WasInit) {
FE_Quit();
FE_WasInit = 0;
}
}
/* fastevent module functions */
/*DOC*/ static char doc_init[] =
/*DOC*/ "pygame.fastevent.init() -> None\n"
/*DOC*/ "initialize pygame.fastevent.\n"
/*DOC*/ ;
static PyObject* fastevent_init(PyObject* self, PyObject* args)
{
if(!PyArg_ParseTuple(args, ""))
return NULL;
VIDEO_INIT_CHECK();
#ifndef WITH_THREAD
return RAISE(PyExc_SDLError, "pygame.fastevent requires a threaded Python");
#else
if (!FE_WasInit) {
if(FE_Init() == -1)
return RAISE(PyExc_SDLError, FE_GetError());
PyGame_RegisterQuit(fastevent_cleanup);
FE_WasInit = 1;
}
RETURN_NONE
#endif /* WITH_THREAD */
}
/*DOC*/ static char doc_pump[] =
/*DOC*/ "pygame.fastevent.pump() -> None\n"
/*DOC*/ "update the internal messages\n"
/*DOC*/ "\n"
/*DOC*/ "For each frame of your game, you will need to make some sort\n"
/*DOC*/ "of call to the event queue. This ensures your program can internally\n"
/*DOC*/ "interact with the rest of the operating system. If you are not using\n"
/*DOC*/ "other event functions in your game, you should call pump() to allow\n"
/*DOC*/ "pygame to handle internal actions.\n"
/*DOC*/ "\n"
/*DOC*/ "There are important things that must be dealt with internally in the\n"
/*DOC*/ "event queue. The main window may need to be repainted. Certain joysticks\n"
/*DOC*/ "must be polled for their values. If you fail to make a call to the event\n"
/*DOC*/ "queue for too long, the system may decide your program has locked up.\n"
/*DOC*/ ;
static PyObject* fastevent_pump(PyObject* self, PyObject* args)
{
if(!PyArg_ParseTuple(args, ""))
return NULL;
FE_INIT_CHECK();
FE_PumpEvents();
RETURN_NONE
}
/*DOC*/ static char doc_wait[] =
/*DOC*/ "pygame.fastevent.wait() -> Event\n"
/*DOC*/ "wait for an event\n"
/*DOC*/ "\n"
/*DOC*/ "Returns the current event on the queue. If there are no messages\n"
/*DOC*/ "waiting on the queue, this will not return until one is\n"
/*DOC*/ "available. Sometimes it is important to use this wait to get\n"
/*DOC*/ "events from the queue, it will allow your application to idle\n"
/*DOC*/ "when the user isn't doing anything with it.\n"
/*DOC*/ ;
static PyObject* fastevent_wait(PyObject* self, PyObject* args)
{
SDL_Event event;
int status;
if(!PyArg_ParseTuple(args, ""))
return NULL;
FE_INIT_CHECK();
Py_BEGIN_ALLOW_THREADS
status = FE_WaitEvent(&event);
Py_END_ALLOW_THREADS
/* FE_WaitEvent will block forever on error */
if(!status)
return RAISE(PyExc_SDLError, "unexpected error in FE_WaitEvent!");
return PyEvent_New(&event);
}
/*DOC*/ static char doc_poll[] =
/*DOC*/ "pygame.fastevent.poll() -> Event\n"
/*DOC*/ "get an available event\n"
/*DOC*/ "\n"
/*DOC*/ "Returns next event on queue. If there is no event waiting on the\n"
/*DOC*/ "queue, this will return an event with type NOEVENT.\n"
/*DOC*/ ;
static PyObject* fastevent_poll(PyObject* self, PyObject* args)
{
SDL_Event event;
int status;
if(!PyArg_ParseTuple(args, ""))
return NULL;
FE_INIT_CHECK();
status = FE_PollEvent(&event);
if (status == 1) {
return PyEvent_New(&event);
} else {
/* Check for -1 */
return PyEvent_New(NULL);
}
}
/*DOC*/ static char doc_get[] =
/*DOC*/ "pygame.fastevent.get() -> list of Events\n"
/*DOC*/ "get all events from the queue\n"
/*DOC*/ ;
static PyObject* fastevent_get(PyObject* self, PyObject* args)
{
SDL_Event event;
PyObject *list, *e;
int status;
if(!PyArg_ParseTuple(args, ""))
return NULL;
FE_INIT_CHECK();
list = PyList_New(0);
if(!list)
return NULL;
FE_PumpEvents();
while (1)
{
status = FE_PollEvent(&event);
if (status != 1) {
break;
}
e = PyEvent_New(&event);
if(!e)
{
Py_DECREF(list);
return NULL;
}
PyList_Append(list, e);
Py_DECREF(e);
}
return list;
}
/*DOC*/ static char doc_post[] =
/*DOC*/ "pygame.fastevent.post(Event) -> None\n"
/*DOC*/ "place an event on the queue\n"
/*DOC*/ "\n"
/*DOC*/ "This will post your own event objects onto the event queue.\n"
/*DOC*/ "You can past any event type you want, but some care must be\n"
/*DOC*/ "taken. For example, if you post a MOUSEBUTTONDOWN event to the\n"
/*DOC*/ "queue, it is likely any code receiving the event will expect\n"
/*DOC*/ "the standard MOUSEBUTTONDOWN attributes to be available, like\n"
/*DOC*/ "'pos' and 'button'.\n"
/*DOC*/ "\n"
/*DOC*/ "Because pygame.fastevent.post() may have to wait for the queue\n"
/*DOC*/ "to empty, you can get into a dead lock if you try to append an\n"
/*DOC*/ "event on to a full queue from the thread that processes events.\n"
/*DOC*/ "For that reason I do not recommend using this function in the\n"
/*DOC*/ "main thread of an SDL program.\n"
/*DOC*/ ;
static PyObject* fastevent_post(PyObject* self, PyObject* args)
{
PyEventObject* e;
SDL_Event event;
int status;
if(!PyArg_ParseTuple(args, "O!", &PyEvent_Type, &e))
return NULL;
FE_INIT_CHECK();
if (PyEvent_FillUserEvent(e, &event))
return NULL;
Py_BEGIN_ALLOW_THREADS
status = FE_PushEvent(&event);
Py_END_ALLOW_THREADS
if (status != 1)
return RAISE(PyExc_SDLError, "Unexpected error in FE_PushEvent");
RETURN_NONE
}
static PyMethodDef fastevent_builtins[] =
{
{ "init", fastevent_init, 1, doc_init },
{ "get", fastevent_get, 1, doc_get },
{ "pump", fastevent_pump, 1, doc_pump },
{ "wait", fastevent_wait, 1, doc_wait },
{ "poll", fastevent_poll, 1, doc_poll },
{ "post", fastevent_post, 1, doc_post },
{ NULL, NULL }
};
/*DOC*/ static char doc_fastevent_MODULE[] =
/*DOC*/ "pygame.fastevent is a wrapper for Bob Pendleton's fastevent\n"
/*DOC*/ "library. It provides fast events for use in multithreaded\n"
/*DOC*/ "environments. When using pygame.fastevent, you can not use\n"
/*DOC*/ "any of the pump, wait, poll, post, get, peek, etc. functions\n"
/*DOC*/ "from pygame.event, but you should use the Event objects.\n"
/*DOC*/ ;
PYGAME_EXPORT
void initfastevent(void)
{
PyObject *module, *eventmodule, *dict;
/* create the module */
module = Py_InitModule3("fastevent", fastevent_builtins, doc_fastevent_MODULE);
dict = PyModule_GetDict(module);
/*imported needed apis*/
import_pygame_base();
import_pygame_event();
eventmodule = PyImport_ImportModule("pygame.event");
if (eventmodule) {
char *NAMES[] = {"Event", "event_name", NULL};
int i;
for (i = 0; NAMES[i]; i++) {
PyObject *ref = PyObject_GetAttrString(eventmodule, NAMES[i]);
if (ref) {
PyDict_SetItemString(dict, NAMES[i], ref);
} else {
PyErr_Clear();
}
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1