SDL_WaitEvent in 1.3

How about a timeout parameter for SDL_WaitEvent() in 1.3 that makes it
possible to wait for an event a limited amount of ms ?

A timeout paramater to SDL_WaitEvent() would allow me to limit the fps/cpu
usage of my application while still responding to events as soon as they
arrive. Something that a sleep() in my main loop does not allow.

To acheive this today I would have to start a timer every time before calling
SDL_WaitEvent().

The implementation could be solved by using WaitForMultipleEvents() on win32
and select() on X11.

What do you think?

/ Christoffer Gurell

How about a timeout parameter for SDL_WaitEvent() in 1.3 that makes it
possible to wait for an event a limited amount of ms ?

Sure. I think I didn’t implement it in SDL 1.2 because of the number of
event types that required polling.

See ya,
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

I’m sure we’d all like to say goodbye to the SDL_Delay(10) loop in there ;)On Fri, Jan 2, 2009 at 5:37 AM, Sam Lantinga wrote:

How about a timeout parameter for SDL_WaitEvent() in 1.3 that makes it
possible to wait for an event a limited amount of ms ?

Sure. I think I didn’t implement it in SDL 1.2 because of the number of
event types that required polling.


http://codebad.com/

A timeout paramater to SDL_WaitEvent() would allow me to limit the fps/cpu
usage of my application while still responding to events as soon as they
arrive. Something that a sleep() in my main loop does not allow.

On that subject:

http://lists.libsdl.org/pipermail/sdl-libsdl.org/2008-May/thread.html#65067On Thu, Jan 1, 2009 at 6:43 PM, <orbit at 0x63.nu> wrote:


http://pphaneuf.livejournal.com/

A timeout paramater to SDL_WaitEvent() would allow me to limit the fps/cpu
usage of my application while still responding to events as soon as they
arrive. Something that a sleep() in my main loop does not allow.

On that subject:

http://lists.libsdl.org/pipermail/sdl-libsdl.org/2008-May/thread.html#65067

Thanks, I’ve added the thread to the TODO list.

See ya!
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC> On Thu, Jan 1, 2009 at 6:43 PM, <orbit at 0x63.nu> wrote:

The implementation could be solved by using WaitForMultipleEvents() on win32
and select() on X11.

Also, we really need an internal mechanism that maps to a
platform-specific, selectable object…right now the joysticks don’t
know anything about the GUI events, etc…it would be nice if we could
give an array of stuff to wait on to SDL and then wait on it…the Unix
layer would understand these objects to be select()able file handles,
Windows would expect HANDLEs, etc…

There were 1.2 hacks to make SDL more friendly to power-conscious
embedded systems, but there are scenarios we couldn’t solve correctly in
1.2, because the higher levels of SDL didn’t know what the actual
joystick and video subsystem drivers were doing…there was no way to
even try to get a waitable object from everything.

–ryan.

The implementation could be solved by using WaitForMultipleEvents() on
win32
and select() on X11.

Also, we really need an internal mechanism that maps to a platform-specific,
selectable object…right now the joysticks don’t know anything about the
GUI events, etc…it would be nice if we could give an array of stuff to
wait on to SDL and then wait on it…the Unix layer would understand these
objects to be select()able file handles, Windows would expect HANDLEs,
etc…

There were 1.2 hacks to make SDL more friendly to power-conscious embedded
systems, but there are scenarios we couldn’t solve correctly in 1.2, because
the higher levels of SDL didn’t know what the actual joystick and video
subsystem drivers were doing…there was no way to even try to get a
waitable object from everything.

–ryan.

Ya’know… I looked at all of these problems way back when I wrote the
fastevent library. Because my net2 library needed to generate events
from a select() and work with the normal SDL 1.2 input code that uses
a mixture of waitable and pollable input devices I had to deal with
this problem. I used a combination of a timer and a condition
variable. The timer triggers the condition every 10 milliseconds so
that the polling code gets called regularly, and the waitable events
trigger the condition variable whenever they push something on the
queue. And, that was all done on top of the regular 1.2 event handling
code. BTW, it wasn’t called fastevents for nothing.

It would take very little effort to modify my version of waitevent()
to include a user specified polling time and the existing code for
handling waitable devices could just be used to handle waitable
objects. The code is all their in fasteevents and net2 because, of
course, net2 handles network input events using SDLs equivalent of
select().

What I am saying is that most of the code already exists. And, you or
Sam are free to put it into 1.3.

Bob PendletonOn Mon, Jan 5, 2009 at 2:49 AM, Ryan C. Gordon wrote:


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

±-------------------------------------+

my net2 library needed to generate events
from a select() and work with the normal SDL 1.2 input code that uses
a mixture of waitable and pollable input devices I had to deal with
this problem.

Sure. I think I didn’t implement it in SDL 1.2 because of the number of
event types that required polling.

Is there a definitive list in any one place of what input devices
require polling? It seems absolutely archaic.On Mon, Jan 5, 2009 at 2:12 PM, Bob Pendleton wrote:
On Fri, Jan 2, 2009 at 5:37 AM, Sam Lantinga wrote:


http://codebad.com/

my net2 library needed to generate events
from a select() and work with the normal SDL 1.2 input code that uses
a mixture of waitable and pollable input devices I had to deal with
this problem.

Sure. I think I didn’t implement it in SDL 1.2 because of the number of
event types that required polling.

Is there a definitive list in any one place of what input devices
require polling? It seems absolutely archaic.

I’ve never seen such a list, and you are right it does seem archaic.
OTOH, consider that the event systems in X, Windows, and Mac OS, are
all built around a polling model very much like SDL_WaitEvent() which
means that the easiest way to interact with existing OSes is to poll
through the native polling APIs.

Bob PendletonOn Mon, Jan 5, 2009 at 3:33 PM, Donny Viszneki <donny.viszneki at gmail.com> wrote:

On Mon, Jan 5, 2009 at 2:12 PM, Bob Pendleton <@Bob_Pendleton> wrote:
On Fri, Jan 2, 2009 at 5:37 AM, Sam Lantinga wrote:


http://codebad.com/


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

±-------------------------------------+

I’ve never seen such a list, and you are right it does seem archaic.
OTOH, consider that the event systems in X, Windows, and Mac OS, are
all built around a polling model very much like SDL_WaitEvent() which
means that the easiest way to interact with existing OSes is to poll
through the native polling APIs.

You can use the X11 connection with select(), Win32 has
WaitForMultipleObjects, and Mac OS X has CFRunLoop (it’s arguably the
most event-driven of them, in fact, but SDL uses it in a rather hacky
way that artificially makes it polling, mostly because most game
developers follow grand old traditions dating from DOS).

The bad part about SDL_WaitEvent() isn’t really that you have to call
it. What’s bad about it is these two things:

  • internally, it’s not event-driven, but really poll-driven, with a
    small sleep to make it not a full-on busy-wait, compromising between
    eating the CPU alive and increasing the latency of event delivery

  • you can only wait on the SDL events, and nothing else, forcing you
    to use a separate thread to gather other events (like fastevents does)
    and piping them in across, while they could in reality all fetched in
    the same system

My preferred way of dealing with this is to have events delivered by
callbacks, instead of fetching them explicitly. This way, you can have
all sorts of optional event registration functions that can be defined
per platforms (say, for Mach ports, if you’re so inclined, but more
realistically, for the slight differences in handling Winsock handles
and POSIX file descriptors), without changing the polling API, which
can just be a simple function with a timeout, say “void
SDL_DispatchEvents(int timeout)”, for example (you might just want to
know whether there was an event or the timeout was reached, rather
than just void, but you don’t want to get the event itself).

Unfortunately, that’s rather hard to fit in the way that SDL 1.2
works. I haven’t looked at 1.3, though, and this might just be the
right time to do this kind of thing.On Mon, Jan 5, 2009 at 8:38 PM, Bob Pendleton wrote:


http://pphaneuf.livejournal.com/

I’ve never seen such a list, and you are right it does seem archaic.
OTOH, consider that the event systems in X, Windows, and Mac OS, are
all built around a polling model very much like SDL_WaitEvent() which
means that the easiest way to interact with existing OSes is to poll
through the native polling APIs.

I didn’t believe what Bob said here for a minute. The only real
exception to the idea that most existing platforms (thoguh Bob said
"OSes") AFAIK are platforms like NES/SNES/Atari/etc… In fact I
recently interfaced a microcontroller with a SNES controller bus, and
polling is all there is at that level. But that doesn’t mean that at
the application level you must also poll, and it in no way implies
that a kernel polling a data source means that polling is the “easiest
way to interact” with the data at the application level.

You can use the X11 connection with select(), Win32 has
WaitForMultipleObjects, and Mac OS X has CFRunLoop (it’s arguably the
most event-driven of them, in fact, but SDL uses it in a rather hacky
way that artificially makes it polling, mostly because most game
developers follow grand old traditions dating from DOS).

I think it’s awfully arrogant to assume SDL uses CFRunLoop incorrectly
"because most game developers follow grand old traditions." But I
greatly appreciate your vote of confidence for event-driven
programming.

The bad part about SDL_WaitEvent() isn’t really that you have to call
it. What’s bad about it is these two things:

I’d like to add another reason, and for many games it’s the big one
(even if I’ve thought differently in the past):

Latency: In fact I think it was Bob who wrote fastevents to combat
exactly that issue.

My preferred way of dealing with this is to have events delivered by
callbacks, instead of fetching them explicitly. This way, you can have
all sorts of optional event registration functions that can be defined
per platforms (say, for Mach ports, if you’re so inclined, but more
realistically, for the slight differences in handling Winsock handles
and POSIX file descriptors), without changing the polling API, which
can just be a simple function with a timeout, say “void
SDL_DispatchEvents(int timeout)”, for example (you might just want to
know whether there was an event or the timeout was reached, rather
than just void, but you don’t want to get the event itself).

I completely agree. I vote for SDL API layer callbacks (registered by
the SDL API user/programmer) being invoked by internal SDL callbacks
(to act as an intervening layer for normalizing the API the programmer
has to deal with, and for internally queueing events to prevent the
case that they might interrupt one another) which in turn are invoked
EITHER by platform-specific callbacks (registered by the SDL
internally) OR by SDL’s polling loop (which would only be used on
platforms with event source that absolutely require polling.)
Maintaining the internal event queue can help retain both poll-driven
SDL event API, as well as ensuring that concurrency at the event
processing level is not a challenge the programmer has to face unless
they really want to (perhaps the SDL API can provide a means of
describing which types of events may preempt others, although I have
my doubts that that would have much practical value, except perhaps
for breaking out of a program that is being overrun with some other
event…)

Unfortunately, that’s rather hard to fit in the way that SDL 1.2
works. I haven’t looked at 1.3, though, and this might just be the
right time to do this kind of thing.

I agree. I think we need Sam’s opinion! I’d be thrilled to work toward
a new interrupt/signal/select() driven processing subsystem for SDL.On Mon, Jan 5, 2009 at 9:25 PM, Pierre Phaneuf wrote:

On Mon, Jan 5, 2009 at 8:38 PM, Bob Pendleton wrote:


http://codebad.com/

I didn’t believe what Bob said here for a minute. The only real
exception to the idea that most existing platforms (thoguh Bob said
"OSes") AFAIK are platforms like NES/SNES/Atari/etc… In fact I
recently interfaced a microcontroller with a SNES controller bus, and
polling is all there is at that level. But that doesn’t mean that at
the application level you must also poll, and it in no way implies
that a kernel polling a data source means that polling is the “easiest
way to interact” with the data at the application level.

I think most (interesting) low-level hardware is interrupt-driven,
nowadays, no? In any case, it’s much easier to make a non-blocking API
that requires polling look like a blocking API than the reverse…

You can use the X11 connection with select(), Win32 has
WaitForMultipleObjects, and Mac OS X has CFRunLoop (it’s arguably the
most event-driven of them, in fact, but SDL uses it in a rather hacky
way that artificially makes it polling, mostly because most game
developers follow grand old traditions dating from DOS).

I think it’s awfully arrogant to assume SDL uses CFRunLoop incorrectly
"because most game developers follow grand old traditions." But I
greatly appreciate your vote of confidence for event-driven
programming.

I didn’t say “incorrectly”, I said “in a rather hacky way”. The
SDLmain.m that I used (provided with SDL) set an NSApplication up for
itself, and hooked its “run loop has just started” event, which is
fired exactly once, and calls the SDL_main() from there, followed by a
harsh exit() (rather than a more normal posting of a “quit” event to
the run loop), while using some rarely used lower level (or maybe
they’re just weird Carbon APIs on the brink of extinction) functions
to peek at the event queue and remove events from it. From the point
of view of NSApplication, an SDL game does a “rough exit” as soon as
it’s started, with an extremely convoluted exit process (that is,
running the game!).

At the very least, it’s kind of colourful and original, you have to admit. :slight_smile:

That’s in fact a good example of how it can be difficult to make a
blocking API behave in a non-blocking way.

I’m saying the “grand old tradition” in such a bad way. SDL was
originally developed to help port software (I’m thinking Doom era)
that came from those kinds of platforms such as DOS where there was
not really an OS or other processes to be nice to, you were the only
process, and SDL_WaitEvent would be coded without the SDL_Delay! At
best, you had the equivalent of sched_yield() to help Windows 3.11 or
DESQview (whoa!), but that was it. I remember myself, a very long
time ago, hearing about DirectX, and thinking that was non-sense,
running a game without having the whole CPU to yourself would never be
as good… :wink:

Converting a game like ioquake3 (which isn’t that old! if I
remember, it more or less uses SDL_PollEvent? it’s been a while I
looked) for an inverted flow of control like what we are both
suggesting (I agree with your suggested API, sounds good to me)
wouldn’t be trivial, and you’ve got people like Ryan making a living
of porting games that like a certain way of working (although,
hopefully, things must be changing, I’d be curious to see an even more
recent vintage of source code)… The API you’re suggesting involves
giving up some control, and game developers are not been so keen on
that, in my experience.

The bad part about SDL_WaitEvent() isn’t really that you have to call
it. What’s bad about it is these two things:

I’d like to add another reason, and for many games it’s the big one
(even if I’ve thought differently in the past):

Latency: In fact I think it was Bob who wrote fastevents to combat
exactly that issue.

The very first point after the bit I wrote that you quoted was
latency. So, yes, very important! ;-)On Tue, Jan 6, 2009 at 2:13 AM, Donny Viszneki <donny.viszneki at gmail.com> wrote:


http://pphaneuf.livejournal.com/

I didn’t believe what Bob said here for a minute. The only real
exception to the idea that most existing platforms (thoguh Bob said
"OSes") AFAIK are platforms like NES/SNES/Atari/etc… In fact I
recently interfaced a microcontroller with a SNES controller bus, and
polling is all there is at that level. But that doesn’t mean that at
the application level you must also poll, and it in no way implies
that a kernel polling a data source means that polling is the “easiest
way to interact” with the data at the application level.

I think most (interesting) low-level hardware is interrupt-driven,
nowadays, no?

Well the AVR series does support an interrupt driven programming model
for mastering a simple serial connection (SPI) which would be
compatible with a single SNES controller. However each SNES controller
has its own data line, so without a parallel-to-serial shift register
to merge those data lines, my microcontroller requires one data line
per controller. The notable disadvantage to this is that I cannot use
the interrupt-driven SPI provisions of the chip, I have to master the
bus all in software. But I poll the controllers about 100 times a
second without eating up too much CPU anyway.

In any case, it’s much easier to make a non-blocking API
that requires polling look like a blocking API than the reverse…

Well, you need a high performance asynchronous queue structure, which
amounts to adding a sub-queue for each thread which has insertion
access (we don’t have to worry as much about reading since SDL really
only needs one event queue extraction thread.) That’s not ludicrously
complex or anything. What it comes down to is that you would need one
extra kernel thread for each blocking read needed to listen on all of
your event sources, plus as many threads as you feel that you need for
polling (probably only one, but maybe polling itself is something that
introduces inevitable sleep time.) As it has already suggested, on
many platforms you only have one such blocking read: select(), or
WaitForMultipleEvents(). If you knew you only had one, you wouldn’t
need a complex queue. As for entry-points registered with the system
to handle events, how you regard those in terms of what I’ve just
described depends entirely on the semantics of those system callbacks.
If you have a system which will queue all of the signals coming into
your process until each signal handler returns, then you have no
concurrency concerns between such signals, and you can consider
system-initiated entry points into your application a single thread.
Anyone with any expertise on that subject for any platform SDL is on
or might be on is hereby encouraged to chime in.

I think it’s awfully arrogant to assume SDL uses CFRunLoop incorrectly
"because most game developers follow grand old traditions." But I
greatly appreciate your vote of confidence for event-driven
programming.

I didn’t say “incorrectly”, I said “in a rather hacky way”.The
SDLmain.m that I used (provided with SDL) set an NSApplication up for
itself, and hooked its “run loop has just started” event, which is
fired exactly once, and calls the SDL_main() from there, followed by a
harsh exit() (rather than a more normal posting of a “quit” event to
the run loop), while using some rarely used lower level (or maybe
they’re just weird Carbon APIs on the brink of extinction) functions
to peek at the event queue and remove events from it. From the point
of view of NSApplication, an SDL game does a “rough exit” as soon as
it’s started, with an extremely convoluted exit process (that is,
running the game!).

I don’t see the incorrect/hacky distinction. And I’m not convinced of
your argument for why SDL doesn’t have a stronger abstraction at the
event processing layer. But I can see how it might have been that way.
Only Sam knows for sure why he did it the way he did :slight_smile:

At the very least, it’s kind of colourful and original, you have to admit. :slight_smile:

I’ve never seen it myself, but it sounds like something that might
break in a future version of Cocoa :frowning:

The very first point after the bit I wrote that you quoted was
latency. So, yes, very important! :wink:

Ah, it seemed to me to focus on the fact that it wasted CPU time. shrug

Is there a Bugzilla entry for this issue?

(Does anyone else get asked to login to Bugzilla all the time? My
cookies are definitely enabled.)On Tue, Jan 6, 2009 at 3:33 AM, Pierre Phaneuf wrote:

On Tue, Jan 6, 2009 at 2:13 AM, Donny Viszneki <@Donny_Viszneki> wrote:


http://codebad.com/

I agree. I think we need Sam’s opinion! I’d be thrilled to work toward
a new interrupt/signal/select() driven processing subsystem for SDL.

I’d love to see something like this for SDL 1.3.

Here are the requirements that I can think of off the top of my head:

  • Support existing 1.2 API
  • Support posting custom SDL events from separate threads and waking as soon as possible to deliver them.
  • Support existing event sources (window events, multiple mice, joystick events, etc.)
  • Must work on UNIX, Windows, and Mac OS X.

See ya!
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

I agree. I think we need Sam’s opinion! I’d be thrilled to work toward
a new interrupt/signal/select() driven processing subsystem for SDL.

I’d love to see something like this for SDL 1.3.

Here are the requirements that I can think of off the top of my head:

  • Support existing 1.2 API
  • Support posting custom SDL events from separate threads and waking as soon as possible to deliver them.
  • Support existing event sources (window events, multiple mice, joystick events, etc.)
  • Must work on UNIX, Windows, and Mac OS X.

I believe that the code in net2 and fastevents could be used as a
basis for all you are asking for. The code already exists and has been
used with no bug reports for several years now.

Bob PendletonOn Tue, Jan 6, 2009 at 10:22 PM, Sam Lantinga wrote:

See ya!
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

±-------------------------------------+

A gracious offer. Might I also add that glib’s event handling provides
quite an excellent API model and is probably also worth looking into.
glib supports multithreaded applications, multiple “event loops,” and
APIs for adding new “event sources” (which for all I know may boil
down to adding your own file descriptors to a collection that glib
select()s, but perhaps it’s more interesting and sophisticated than
that!)On Thu, Jan 8, 2009 at 1:00 PM, Bob Pendleton wrote:

I believe that the code in net2 and fastevents could be used as a
basis for all you are asking for. The code already exists and has been
used with no bug reports for several years now.


http://codebad.com/

+1 for fastevents :slight_smile:

I’ve been using it with pygame a lot… and we are thinking of using
it as the default event module for the next release.

cheers,On Fri, Jan 9, 2009 at 5:00 AM, Bob Pendleton wrote:

On Tue, Jan 6, 2009 at 10:22 PM, Sam Lantinga wrote:

I agree. I think we need Sam’s opinion! I’d be thrilled to work toward
a new interrupt/signal/select() driven processing subsystem for SDL.

I’d love to see something like this for SDL 1.3.

Here are the requirements that I can think of off the top of my head:

  • Support existing 1.2 API
  • Support posting custom SDL events from separate threads and waking as soon as possible to deliver them.
  • Support existing event sources (window events, multiple mice, joystick events, etc.)
  • Must work on UNIX, Windows, and Mac OS X.

I believe that the code in net2 and fastevents could be used as a
basis for all you are asking for. The code already exists and has been
used with no bug reports for several years now.

Bob Pendleton

I believe that the code in net2 and fastevents could be used as a
basis for all you are asking for. The code already exists and has been
used with no bug reports for several years now.

A gracious offer. Might I also add that glib’s event handling provides
quite an excellent API model and is probably also worth looking into.
glib supports multithreaded applications, multiple “event loops,” and
APIs for adding new “event sources” (which for all I know may boil
down to adding your own file descriptors to a collection that glib
select()s, but perhaps it’s more interesting and sophisticated than
that!)

You won’t know how interesting glib is until you look…

OTOH, how will glib fit in Sam’s dual licensing scheme? While I am all
for dual licensing it does make it hard to mix and match code from
other bits of FOSS.

Bob PendletonOn Thu, Jan 8, 2009 at 4:23 PM, Donny Viszneki <donny.viszneki at gmail.com> wrote:

On Thu, Jan 8, 2009 at 1:00 PM, Bob Pendleton <@Bob_Pendleton> wrote:


http://codebad.com/


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

±-------------------------------------+

glib is huge

I was not suggesting to copy any of its code directly, only to use it
as a research tool to see how others have done things.

At any rate, I’m not going to restrict my plans for SDL development to
what Sam can license unless he wants to give me a job! (Sam, is your
new company hiring?)

If I really put my weight into forking SDL for any reason, I’ll put a
good deal of effort into making sure it is nominally API compatible
with Sam’s, so even if I did copy glib code, it is not my intention to
make it difficult for Sam by fragmenting the API. He can catch up on
implementation at his own pace if it comes down to it!On Thu, Jan 8, 2009 at 9:52 PM, Bob Pendleton wrote:

OTOH, how will glib fit in Sam’s dual licensing scheme? While I am all
for dual licensing it does make it hard to mix and match code from
other bits of FOSS.


http://codebad.com/

OTOH, how will glib fit in Sam’s dual licensing scheme? While I am all
for dual licensing it does make it hard to mix and match code from
other bits of FOSS.

glib is huge

I was not suggesting to copy any of its code directly, only to use it
as a research tool to see how others have done things.

That makes sense.

At any rate, I’m not going to restrict my plans for SDL development to
what Sam can license unless he wants to give me a job! (Sam, is your
new company hiring?)

IMHO that makes some sense.

If I really put my weight into forking SDL for any reason, I’ll put a
good deal of effort into making sure it is nominally API compatible
with Sam’s, so even if I did copy glib code, it is not my intention to
make it difficult for Sam by fragmenting the API. He can catch up on
implementation at his own pace if it comes down to it!

That also makes sense. I think…

Bob PendletonOn Thu, Jan 8, 2009 at 9:09 PM, Donny Viszneki <donny.viszneki at gmail.com> wrote:

On Thu, Jan 8, 2009 at 9:52 PM, Bob Pendleton <@Bob_Pendleton> wrote:


http://codebad.com/


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

±-------------------------------------+