I noticed another pattern I seem to consistently apply to all event code I write. Namely that I want to process all events during one iteration of the main loop, but wait . Up until recently I had used pygame.event.get() without noticing that that essentially is a busy wait and hence migrated to the less nicely looking
while running: for ev in [pygame.event.wait(), *pygame.event.get()]: if ev.type == ... The patch is attached from my local git(-hub) clone and would allow to rephrase the above to the now equivalent while running: for ev in pygame.event.wait_get(): if ev.type == ... cheers! mar77i
From ec5173d91442ddf00518b2b4b8685452ae6518d2 Mon Sep 17 00:00:00 2001 From: mar77i <mar...@mar77i.ch> Date: Wed, 17 Aug 2016 12:39:25 +0200 Subject: [PATCH] add pygame.{fast,}event.wait_get() -> Eventlist combines pygame.wait() with pygame.get() as a pre-3.5 shortcut for [pygame.event.wait(), *pygame.event.get()] as basis for limiting one iteration over the main loop per frame and one frame per iteration over the main loop. --- docs/reST/ref/event.rst | 12 ++++++++++++ src/doc/event_doc.h | 6 ++++++ src/event.c | 23 +++++++++++++++++++++++ src/fastevent.c | 29 +++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+) diff --git a/docs/reST/ref/event.rst b/docs/reST/ref/event.rst index 2633ec9..a5f7c61 100644 --- a/docs/reST/ref/event.rst +++ b/docs/reST/ref/event.rst @@ -151,6 +151,18 @@ type and have identical attribute values. Inequality checks also work. .. ## pygame.event.wait ## +.. function:: wait_get + + | :sl:`wait for at least one event and get events from the queue` + | :sg:`wait_get() -> Eventlist` + + This will get all the messages and remove them from the queue. If the queue + is empty this function will wait until one is created. While the program is + waiting it will sleep in an idle state. This is important for programs that + want to share the system with other applications. + + .. ## pygame.event.wait_get ## + .. function:: peek | :sl:`test if event types are waiting on the queue` diff --git a/src/doc/event_doc.h b/src/doc/event_doc.h index c936f49..705dca1 100644 --- a/src/doc/event_doc.h +++ b/src/doc/event_doc.h @@ -9,6 +9,8 @@ #define DOC_PYGAMEEVENTWAIT "wait() -> EventType instance\nwait for a single event from the queue" +#define DOC_PYGAMEEVENTWAITGET "wait_get() -> Eventlist\nwait for at least one event and get all events from the queue" + #define DOC_PYGAMEEVENTPEEK "peek(type) -> bool\npeek(typelist) -> bool\ntest if event types are waiting on the queue" #define DOC_PYGAMEEVENTCLEAR "clear() -> None\nclear(type) -> None\nclear(typelist) -> None\nremove all events from the queue" @@ -62,6 +64,10 @@ pygame.event.wait wait() -> EventType instance wait for a single event from the queue +pygame.event.wait_get + wait_get() -> Eventlist +wait for at least one event and get all events from the queue + pygame.event.peek peek(type) -> bool peek(typelist) -> bool diff --git a/src/event.c b/src/event.c index 74dd7ab..eb3d8e7 100644 --- a/src/event.c +++ b/src/event.c @@ -683,6 +683,23 @@ pygame_wait (PyObject* self, PyObject* args) } static PyObject* +pygame_wait_get (PyObject* self, PyObject* args) +{ + int status; + + VIDEO_INIT_CHECK (); + + Py_BEGIN_ALLOW_THREADS; + status = SDL_WaitEvent (NULL); + Py_END_ALLOW_THREADS; + + if (!status) + return RAISE (PyExc_SDLError, SDL_GetError ()); + + return event_get (self, args); +} + +static PyObject* pygame_poll (PyObject* self, PyObject* args) { SDL_Event event; @@ -1014,6 +1031,12 @@ static PyMethodDef _event_methods[] = { "pump", (PyCFunction) pygame_pump, METH_NOARGS, DOC_PYGAMEEVENTPUMP }, { "wait", (PyCFunction) pygame_wait, METH_NOARGS, DOC_PYGAMEEVENTWAIT }, + { + "wait_get", + (PyCFunction) pygame_wait_get, + METH_NOARGS, + DOC_PYGAMEEVENTWAITGET + }, { "poll", (PyCFunction) pygame_poll, METH_NOARGS, DOC_PYGAMEEVENTPOLL }, { "clear", event_clear, METH_VARARGS, DOC_PYGAMEEVENTCLEAR }, { "get", event_get, METH_VARARGS, DOC_PYGAMEEVENTGET }, diff --git a/src/fastevent.c b/src/fastevent.c index e54393a..9db4198 100644 --- a/src/fastevent.c +++ b/src/fastevent.c @@ -130,6 +130,34 @@ fastevent_wait (PyObject * self) return PyEvent_New (&event); } +/* DOC */ static char doc_wait_get[] = +/* DOC */ "pygame.fastevent.wait_get() -> list of Events\n" +/* DOC */ "wait for at least one event and get all events from the queue\n" +/* DOC */ "\n" +/* DOC */ "Returns all events from the queue. If there are no messages\n" +/* DOC */ "waiting on the queue, this will not return until at least 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_get (PyObject * self) +{ + int status; + + FE_INIT_CHECK (); + + Py_BEGIN_ALLOW_THREADS; + status = FE_WaitEvent (NULL); + Py_END_ALLOW_THREADS; + + /* FE_WaitEvent will block forever on error */ + if (!status) + return RAISE (PyExc_SDLError, "unexpected error in FE_WaitEvent!"); + + return fastevent_get (self); +} + /* DOC */ static char doc_poll[] = /* DOC */ "pygame.fastevent.poll() -> Event\n" /* DOC */ "get an available event\n" @@ -244,6 +272,7 @@ static PyMethodDef _fastevent_methods[] = {"get", (PyCFunction) fastevent_get, METH_NOARGS, doc_get}, {"pump", (PyCFunction) fastevent_pump, METH_NOARGS, doc_pump}, {"wait", (PyCFunction) fastevent_wait, METH_NOARGS, doc_wait}, + {"wait_get", (PyCFunction) fastevent_wait_get, METH_NOARGS, doc_wait_get}, {"poll", (PyCFunction) fastevent_poll, METH_NOARGS, doc_poll}, {"post", fastevent_post, METH_O, doc_post}, -- 2.9.3