SDL_WaitEvent in 1.3

Sorry, to be more clear, I’m really interested in seeing some details
on the architecture and implementation that Pierre Phaneuf has in mind.
He clearly has thought alot about it, and I’m curious how he plans to
go about it.

I have a pretty clear idea of how I’d do it from scratch, but I’m
trying to think how to make it fit well with the SDL 1.2 API at the
moment.

As Donny said, simply having the default callbacks post to the SDL
queue would suffice for 1.2 compatibility. The trick is making sure
that other sources posting to the queue will wake up any low level
event waiting.

By the way, this might be entirely overkill, as almost without exception
multimedia applications are continually changing their visual content and
therefore are polling their events instead of waiting on them.

See ya!
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC> On Sun, Jan 11, 2009 at 2:33 AM, Sam Lantinga wrote:

I have a pretty clear idea of how I’d do it from scratch, but I’m
trying to think how to make it fit well with the SDL 1.2 API at the
moment.

Also, not to be a downer here, but after all this talk about event
management, it’s probably worth noting that it’s not really broken, so
I’m not entirely clear on why we’re fixing it.

Having everything go through select() or whatever internally has a
benefit for power management and latency, but the callback thing is
getting a little silly. Can anyone tell me of a case where they ever
legitimately lost events that wasn’t either a bug in SDL (which we
should fix) or a bug in their application (which we should not conceal)?

–ryan.

I dislike callbacks for events, and very much love the SDL event
queue… especially with the fastevents code.

With current SDL, it’s not very good with threads(slow, and unsafe).
With fastevents I have had no issues. Posting events into the queue
can fail, which requires possibly many retries with current SDL. Also
the event peek function is kind of silly with SDL… fastevents
removes this function since, by design it is not thread safe – it can
easily cause a race condition.

cu.On Mon, Jan 12, 2009 at 11:43 AM, Ryan C. Gordon wrote:

I have a pretty clear idea of how I’d do it from scratch, but I’m
trying to think how to make it fit well with the SDL 1.2 API at the
moment.

Also, not to be a downer here, but after all this talk about event
management, it’s probably worth noting that it’s not really broken, so I’m
not entirely clear on why we’re fixing it.

Having everything go through select() or whatever internally has a benefit
for power management and latency, but the callback thing is getting a little
silly. Can anyone tell me of a case where they ever legitimately lost
events that wasn’t either a bug in SDL (which we should fix) or a bug in
their application (which we should not conceal)?

–ryan.

Having everything go through select() or whatever internally has a benefit
for power management and latency, but the callback thing is getting a little
silly. Can anyone tell me of a case where they ever legitimately lost
events that wasn’t either a bug in SDL (which we should fix) or a bug in
their application (which we should not conceal)?

I dislike callbacks for events, and very much love the SDL event
queue… especially with the fastevents code.

If you’re writing a time-critical networked game, you need to do
everything possible to cut down latency. Every millisecond counts.
Just having callbacks isn’t enough, as it seems some of us think we’ll
register our callbacks with SDL, then tell SDL “we’re ready to handle
some events” at which point it will fire our callbacks synchronously.
I think we can do a lot better.

With current SDL, it’s not very good with threads(slow, and unsafe).
With fastevents I have had no issues. Posting events into the queue
can fail, which requires possibly many retries with current SDL. Also
the event peek function is kind of silly with SDL… fastevents
removes this function since, by design it is not thread safe – it can
easily cause a race condition.

Providing multiple queues and allowing the program to designate what
each queue is for would solve the need for a “peek” function.On Sun, Jan 11, 2009 at 7:43 PM, Ryan C. Gordon wrote:
On Sun, Jan 11, 2009 at 7:54 PM, Ren? Dudfield wrote:


http://codebad.com/

Also, not to be a downer here, but after all this talk about event
management, it’s probably worth noting that it’s not really broken, so I’m
not entirely clear on why we’re fixing it.

The parts that I feel are broken are:

  • the SDL_Delay in SDL_WaitEvent
  • the superfluous queueing (but keeping the necessary queueing, of course!)
  • not being possible to wait for events at the same time as something
    else (without threads (which is even more queueing), that is)

Note that none of this requires using callbacks, could all be done
with (I think) 100% compatibility with the 1.2 API, only adding new
functions (say, an SDL_WatchFD function similar to XtAppAddInput or
WSAAsyncSelect) which would be pretty much optional (one might expect
some to depend on the platform, say one to watch a Mach port, for
example), and could be added over time.

Having everything go through select() or whatever internally has a benefit
for power management and latency, but the callback thing is getting a little
silly. Can anyone tell me of a case where they ever legitimately lost
events that wasn’t either a bug in SDL (which we should fix) or a bug in
their application (which we should not conceal)?

Note again that whichever event lossage that could be helped does
not need the callbacks to be helped.

Why do I want them, then?

As I said before, it’s easier to make a callback oriented API (such as
Cocoa or BeOS) from an event pump oriented API (such as X11 and
Win32), as it’s pretty obvious. On BeOS, we start the main loop in a
separate thread, then posting back across to the main thread, on Cocoa
we use the hack where we run the whole SDL program from a callback,
since Cocoa also provides separate methods to get events in the style
of XNextEvent/GetMessage. In the worst case where an API wouldn’t
support these tricks, there are still more (increasingly crazier!)
tricks, like queueing down events and asking to exit the main loop
(could be done this way on Mac OS X, might have better integration
with a mixed application), or (brace for it!) using an alternate stack
to call the main loop and swapping the context.

(The “better integration” would allow us to just call
SDL_CreateWindowFrom, have it hook the listeners (on Cocoa), and just
let the main application loop do its normal work, being a “better
citizen”)

When you do the reverse, there’s no trickery, and you’re free to do
things very efficiently, as you’re just calling the callback right
away. If you’ve got an API that is callback oriented, then you don’t
have the potentially expensive trickery (like the queueing events,
then returning from the run loop). Again, it’s my argument that if
there’s something that you layer on, you can’t take it off if you
don’t want it, you have no choice. If you wanted to get an
SDL_PollEvent/SDL_WaitEvent (and I think we pretty much have to, even
though I think it’s generally inferior), you could get it if you
wanted, and accept that there might be an extra overhead.

A callback oriented API also has the efficiency/correctness advantage
that you can keep a minimal XSelectInput (or local equivalent) for
efficiency, without any doubt of having a mismatch or forgetting to
update it (setting the callback means you want it, unsetting it means
you don’t, that’s the end of it). The Xlib API does not work like
that, and check it out, SDL has this very bug in it (the safe “we just
get spurious unknown events”, thankfully):
http://lists.libsdl.org/pipermail/sdl-libsdl.org/2008-May/065066.html
:wink:

But why I’m not running off with this is that all those trickeries to
make the callback oriented APIs work as an event pump API are kind of
platform-specific, so you wouldn’t necessarily be able to convert the
SDL version of the API back. And if the native SDL 1.3 API becomes
callback driven, paying the overhead to convert back to an event
pump API when the native API might already be an event pump API isn’t
exactly attractive…

What I’m thinking about is whether it could be made so that you can
choose at SDL_Init time which style you want, and SDL would provide
whatever you choosed as efficiently as it can (as I explained, the
callback style would basically be guaranteed to be as efficient as
possible, but the SDL_PollEvent style should be very efficient on X11
and Win32, say). But this is icky, as you might get two code paths in
the driver API for the platforms with the callback style API, and even
then, think of a platform like Mac OS X with a strange set-up (with
the SDLMain.m), etc…

I’m a bit disappointed, but I’m currently leaning toward doing this
with the current style of API, just fixing the three issues I pointed
out at the top.

If you’re not convinced that the latency in SDL_WaitEvent could be
better, try out the small test program attached to the following email
(X11-specific, of course, but does work on Mac OS X):

http://lists.libsdl.org/pipermail/sdl-libsdl.org/2008-May/065067.html

On my Mac, I had to put “#undef main” in front of the main function,
set the SDL_VIDEODRIVER environment variable to “x11”, and I used the
following command line to compile it:

gcc -O2 -F/Users/pphaneuf/Library/Frameworks
-I/Users/pphaneuf/Library/Frameworks/SDL.framework/Headers -framework
SDL -Wall -o sdlwait sdlwait.c

Try uncommenting the three METHOD_xxx (one at a time!), notice the
number at the beginning of the line (number of milliseconds since the
previous event was received) and the CPU usage results at the end (I
forgot the wall time! use “time ./sdlwait” to get the full story).
You’ll see that METHOD_WAIT has low CPU usage, but chunky latency
(multiple of 10 msec, plus a hair), METHOD_POLL has good latency, but
higher CPU usage, and METHOD_SELECT has both good latency and low
CPU usage (a tiny bit lower than METHOD_WAIT, actually!). I think that
if we cut out the event queue (and mutex operations!), it could be
even nicer and smoother, latency-wise (but should be equivalent on the
CPU).

So there is a way to do this better, even if we keep the exact same
external API (it changes), I really think we should at least do that!
:slight_smile:

But as a bonus, I think it’d be dead easy to get cheaper timers (not
using a thread or pushing events), and shouldn’t be too bad to add
something like WSAAsyncSelect.On Sun, Jan 11, 2009 at 7:43 PM, Ryan C. Gordon wrote:


http://pphaneuf.livejournal.com/

I dislike callbacks for events, and very much love the SDL event
queue… especially with the fastevents code.

I understand the dislike for callbacks. I like them myself, but I
understand this is mostly a question of taste. Loving the event queue,
I find it kind of strange, I mostly something tend to work despite
of it. :slight_smile:

With current SDL, it’s not very good with threads(slow, and unsafe).
With fastevents I have had no issues. Posting events into the queue
can fail, which requires possibly many retries with current SDL. Also
the event peek function is kind of silly with SDL… fastevents
removes this function since, by design it is not thread safe – it can
easily cause a race condition.

I think you’re still supposed to get events from a single thread,
especially as some platforms are “angry” if you end up doing stuff on
threads other than some mystical “UI thread” (to be assumed is the
main thread, I guess).

If you get events from a single thread, then peek is safe. It is only
unsafe if there are more than one thread getting events from the
queue.

For the queue, I’d use a pipe as a semaphore (see
http://pphaneuf.livejournal.com/158971.html), and if I’m clever
enough, that would be the only locking primitive needed, also
providing built-in notification (SDL_WaitEvent would wake up the very
moment an event is posted, no delay at all).On Sun, Jan 11, 2009 at 7:54 PM, Ren? Dudfield wrote:


http://pphaneuf.livejournal.com/

If you’re writing a time-critical networked game, you need to do
everything possible to cut down latency. Every millisecond counts.
Just having callbacks isn’t enough, as it seems some of us think we’ll
register our callbacks with SDL, then tell SDL “we’re ready to handle
some events” at which point it will fire our callbacks synchronously.
I think we can do a lot better.

What I’m proposing is the equivalent of a game loop consisting of
SDL_PollEvent in a loop until a certain event is obtained or some time
is elapsed, then render a frame, but which would use the lowest amount
of CPU without compromising latency (like SDL_WaitEvent does at the
moment) instead of using 100% CPU. Nothing more, nothing less.

If you need, say, to be able to handle events and somehow integrate it
in your game state during the rendering of a frame, then you need to
use a thread, or insert checks on SDL_PollEvent in the middle of your
rendering frame.

Providing multiple queues and allowing the program to designate what
each queue is for would solve the need for a “peek” function.

I think it would be a “nice to have” feature, for each thread to have
their own queue, and maybe ask for some events to be redirected to
specific threads, that kind of stuff… But not in my top priority.
You can implement a blocking event queue for a thread very easily
using a semaphore, anyway.On Sun, Jan 11, 2009 at 8:12 PM, Donny Viszneki <donny.viszneki at gmail.com> wrote:


http://pphaneuf.livejournal.com/

Right now that is true. I’m only proposing that it shouldn’t be.
Perhaps my programming experience has been a spoiled one with access
to things like hardware interrupts on embedded platforms, and unix
signals when data arrives on a socket. On platforms that support it, I
thought SDL could provide access to near-zero-latency
interrupt/signal-driven I/O, which means both good scheduling and low
latency.

Perhaps you’re right in saying I should just use another thread for
this sort of thing. Especially since that will probably mean a
performance boost for any platform with more than one CPU core. When I
want this kind of bleeding-edge latency, I am usually only looking to
fire off a packet to a game server in response to user input anyway,
so I don’t really need to worry about locking a whole lot, the event
thread would be almost entirely self-sufficient.

Would it be difficult to accommodate this sort of application design in SDL?On Mon, Jan 12, 2009 at 2:08 AM, Pierre Phaneuf wrote:

On Sun, Jan 11, 2009 at 8:12 PM, Donny Viszneki <@Donny_Viszneki> wrote:

If you’re writing a time-critical networked game, you need to do
everything possible to cut down latency. Every millisecond counts.
Just having callbacks isn’t enough, as it seems some of us think we’ll
register our callbacks with SDL, then tell SDL “we’re ready to handle
some events” at which point it will fire our callbacks synchronously.
I think we can do a lot better.

What I’m proposing is the equivalent of a game loop consisting of
SDL_PollEvent in a loop until a certain event is obtained or some time
is elapsed, then render a frame, but which would use the lowest amount
of CPU without compromising latency (like SDL_WaitEvent does at the
moment) instead of using 100% CPU. Nothing more, nothing less.

If you need, say, to be able to handle events and somehow integrate it
in your game state during the rendering of a frame, then you need to
use a thread, or insert checks on SDL_PollEvent in the middle of your
rendering frame.


http://codebad.com/

Oh, I’ve been meaning to inject another bit of advice into this thread
for a while now but I keep forgetting about it: we should keep in mind
other libs whose APIs like to be part of the event processing chain.
Many of these libs provide a function for processing an SDL_Event, and
in return they provide feedback as to whether or not their library has
"grabbed" that input, or whether or not it should “bubble up” to other
libraries in the chain. On *nix platforms, the signal(2) signal
handler registration callback simply returns the previous callback
function pointer when you set a new one, giving your software
component the opportunity to store that pointer and attempt to
cooperate with other software components by passing the signal along
the chain when appropriate. Maybe this would be a good enough system?–
http://codebad.com/

Right now that is true. I’m only proposing that it shouldn’t be.
Perhaps my programming experience has been a spoiled one with access
to things like hardware interrupts on embedded platforms, and unix
signals when data arrives on a socket. On platforms that support it, I
thought SDL could provide access to near-zero-latency
interrupt/signal-driven I/O, which means both good scheduling and low
latency.

I don’t want to push the discussion over to high-performance network
programming, since that thread is already heavy enough! :slight_smile:

When you have interrupts or POSIX-style asynchronous signals, you
rarely want to actual work in them, and on top of it they’re often
running with very harsh constraints, interrupt disabled, can’t take
any lock (did you know it’s unsafe to take a mutex in a signal
handler? there’s a chance of deadlock! the only safe pthread primitive
there is sem_post)… So you end up using a bottom-half handler to
actually do the work for the interrupt, or using the “self-pipe trick”
(which I intend to use for posting events from other threads:
http://cr.yp.to/docs/selfpipe.html), and you’re back in the main
thread, “later”…

Even when using SIGIO, what’s usually done is block the signal and use
sigtimedwait(), it was really just a way to avoid the O(N) problem of
the select()/poll() system calls (but nowadays, you’re better off
using epoll or kqueue, if available).

Perhaps you’re right in saying I should just use another thread for
this sort of thing. Especially since that will probably mean a
performance boost for any platform with more than one CPU core. When I
want this kind of bleeding-edge latency, I am usually only looking to
fire off a packet to a game server in response to user input anyway,
so I don’t really need to worry about locking a whole lot, the event
thread would be almost entirely self-sufficient.

There are some very specific cases where you can actually do the work
in the interrupt or signal handler. For example, since XFree86 4.0,
they use SIGIO for the mouse file descriptor, and process the mouse
right there, somehow (I’m not aware of the details, I don’t know much
more now about this than back then:
http://lists.libsdl.org/pipermail/sdl-libsdl.org/2000-July/010414.html).
I think they just move the graphical cursor, and still queue up the
actual events, so the apps don’t see any improvement, but it looks
nicer for the user. :slight_smile:

If you’re going to do something involving the network, then surely, it
can wait. :wink:

I’d point out that in the pre-SDL version of Quadra (you can see the
code here: http://code.google.com/p/quadra/source/browse/branches/quadra-1.2),
I handled everything in a single thread, with no signal geekery,
including the OSS sound. If there was anything that screwed up the
latency, the sound would skip badly. Quake3 (as originally released,
not the ioquake3 version, it’s a bit the same situation as Quadra 1.2
versus trunk) did the exact same thing, so I figure you can do a whole
lot without having to worry about latency too much, as long as you’re
behaving nicely and never using blocking calls (that reminds me, after
this, I’ll have to hack SDL_net to use non-blocking writes!)… :wink:

Would it be difficult to accommodate this sort of application design in SDL?

I think it’d be nuts (because of the portability). :-POn Mon, Jan 12, 2009 at 2:30 AM, Donny Viszneki <donny.viszneki at gmail.com> wrote:


http://pphaneuf.livejournal.com/

Le 12 janv. 09 ? 07:57, Pierre Phaneuf a ?crit :

I understand the dislike for callbacks. I like them myself, but I
understand this is mostly a question of taste. Loving the event queue,
I find it kind of strange, I mostly something tend to work despite
of it. :slight_smile:

It’s not only a matter of taste. An event queue or a selectable file
descriptor makes it much more easier to make bindings to higher-level
languages. They also allow to play nicely with a language’s
interactive toplevel.

Leaving the control flow to the programmer (vs. to the library with
callback soups) is easier to understand and more compositional –
integrating two libraries that require inversion of control is not a
delighting task.

Best,

Daniel

It’s not only a matter of taste. An event queue or a selectable file
descriptor makes it much more easier to make bindings to higher-level
languages. They also allow to play nicely with a language’s interactive
toplevel.

Leaving the control flow to the programmer (vs. to the library with callback
soups) is easier to understand and more compositional – integrating two
libraries that require inversion of control is not a delighting task.

That’s true. I was intending for the function that would run the main
loop to have a timeout (possibly zero, making it non-blocking), which
should have made it possible to integrate with another main loop. The
best is when you indeed have a selectable file descriptor, but it’s
hard to provide that in a cross-platform way.

One of my strategies was to make the run loop something that can be
provided by the user (with a default one built in), and then have the
video drivers use it to do their thing using it (for example, the X11
driver would ask to watch the ConnectionNumber(dpy) for readability),
so that you could integrate with another library by simply wrapping it
(a little bit like the SDL_RWops make it possible to load files using
any number of underlying APIs).

With these two things, integration with other libraries and making
language bindings shouldn’t have been too difficult.

But still, I’m leaning toward keeping the current API and just add to
it (still taking out the SDL queue, but it’s an additional queue,
there are still underlying queues, in Xlib and Win32, for example,
we’ll just use those directly).On Mon, Jan 12, 2009 at 4:57 AM, Daniel B?nzli <daniel.buenzli at erratique.ch> wrote:


http://pphaneuf.livejournal.com/

If your “check for events” function is nonblocking, aren’t we back to
polling? Aren’t we back to pegging the CPU? What would we have
accomplished?On Mon, Jan 12, 2009 at 11:42 AM, Pierre Phaneuf wrote:

On Mon, Jan 12, 2009 at 4:57 AM, Daniel B?nzli <daniel.buenzli at erratique.ch> wrote:

It’s not only a matter of taste. An event queue or a selectable file
descriptor makes it much more easier to make bindings to higher-level
languages. They also allow to play nicely with a language’s interactive
toplevel.

Leaving the control flow to the programmer (vs. to the library with callback
soups) is easier to understand and more compositional – integrating two
libraries that require inversion of control is not a delighting task.

That’s true. I was intending for the function that would run the main
loop to have a timeout (possibly zero, making it non-blocking), which
should have made it possible to integrate with another main loop. The
best is when you indeed have a selectable file descriptor, but it’s
hard to provide that in a cross-platform way.


http://codebad.com/

If your “check for events” function is nonblocking, aren’t we back to
polling? Aren’t we back to pegging the CPU? What would we have
accomplished?

Not much, as you have no way of knowing whether you need to check for
events, so you have to check “every once in a while”. This is like
SDL_WaitEvent, there really only is SDL_PumpEvents and SDL_PeepEvents,
both of which are non-blocking, so you have to implement your stuff in
terms of that. So you stick in an SDL_Delay(10).

But sometimes, that’s all you can do.

But that’s how it is integrating multiple event loops, often… :-(On Mon, Jan 12, 2009 at 8:45 PM, Donny Viszneki <donny.viszneki at gmail.com> wrote:


http://pphaneuf.livejournal.com/

[…]

If your “check for events” function is nonblocking, aren’t we back to
polling? Aren’t we back to pegging the CPU? What would we have
accomplished?

Well, if you are CPU bound (say rendering a constantly changing 3D
background) you don’t want to be suspended. Rather, you are running all
the time and peek at the event queue whenever you are in a state where you
can suspend calculations to service events (and possibly abandon or
restart the rest of the calculations, due to an event). If, because of a
drop in the CPU load, you start to have spare time, you can set non-zero
timeouts so you fall back to event-driven mode. In fact, if the timeout
value == 0 is non-blocking and < 0 means no timeout at all, then you can
even satisfy those who prefer timer events over timeouts (like me).

Hogging the CPU in a loop doing nothing but waiting for something to
happen is indeed a shameful sin but when you are flat out doing actual
work it’s the opposite: it would be shameful if the library forced you
to suspend, the CPU idling while waiting for an interrupt and you not
being able to finish your calculations in time.

While the above scenario can be soved with separate threads, you’d need to
set up a pretty funky synchronisation between your calculator thread and
event thread. It is easier if you have it built in the library.

Furthermore, allowing a non-blocking GetEvent() does not limit any
functionality but adds to the possibilities, therefore it is a good
thing, I think.

Regards,

ZoltanOn Mon, 12 Jan 2009, Donny Viszneki wrote:

Sorry, to be more clear, I’m really interested in seeing some details
on the architecture and implementation that Pierre Phaneuf has in mind.
He clearly has thought alot about it, and I’m curious how he plans to
go about it.

I have a pretty clear idea of how I’d do it from scratch, but I’m
trying to think how to make it fit well with the SDL 1.2 API at the
moment. I spent the day yesterday removing various things from
SDL_events.h (and SDL_events_c.h) and seeing what breaks, what needs
what, and so on. I’ll get back with some pseudo-code soon.

It seems to me that everyone favors a callback-driven event
dispatching API for the majority of events. Why is it hard to have the
default callbacks fill the SDL event queue, thus being backward
compatible?

It isn’t hard. It is dead easy.

Bob PendletonOn Sun, Jan 11, 2009 at 12:01 PM, Donny Viszneki <donny.viszneki at gmail.com> wrote:

On Sun, Jan 11, 2009 at 11:59 AM, Pierre Phaneuf wrote:

On Sun, Jan 11, 2009 at 2:33 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 have a pretty clear idea of how I’d do it from scratch, but I’m
trying to think how to make it fit well with the SDL 1.2 API at the
moment.

Also, not to be a downer here, but after all this talk about event
management, it’s probably worth noting that it’s not really broken, so I’m
not entirely clear on why we’re fixing it.

Having everything go through select() or whatever internally has a benefit
for power management and latency, but the callback thing is getting a little
silly. Can anyone tell me of a case where they ever legitimately lost
events that wasn’t either a bug in SDL (which we should fix) or a bug in
their application (which we should not conceal)?

–ryan.

To answer the first question first, yes I have lost events due to what
I consider a bug in SDL and it is why I wrote my FastEvents library.
I wanted to use a single event queue for all input events and in the
case of a server with a lot of traffic I lost events. Of course, that
is a pathological case and was not what anyone was thinking about when
SDL was written.

I have seen a lot of ideas flowing back and forth during this
discussion. I think the problem is that many of the ideas have been
kind of mixed together so it is hard to talk about them and there is a
lot of muddling going on because some people like call backs and some
like a queue and so the real ideas are being confused with those two
nearly equivalent methods of delivering events. I also think there
has been a bit much focus on the details of specific implementations
and not enough focus on the differences between the different possible
implementations. SDL has to work across at least 3 main OSes and a
bunch of others and the differences are what cause many of the design
decisions.

Before I go on I want to make sure that people understand why there
are queues anywhere in any system. They are there to buffer the
difference in production and consumption rates between the things at
each end of the queue. Why do we stand in a queue to buy movie tickets
(Ok, the real answer is because we didn’t think to buy them online
:-)? Because the people selling tickets can process each transaction
in about the same amount of time but people show up at a random rate.

In a computer systems queues have another, less obvious, purpose. When
a queue is full the software thread trying to write to the queue
blocks. That means the hardware thread driving the writing thread gets
allocated to a ready software thread that has no hardware thread. That
means that queue length is an implicit and reliable way of allocating
hardware threads to software threads and of controlling how much time
is spent in the software threads on each end of a queue.

OK, so here is my interpretation of what has been said. There is no
reason to believe that this is what any od you meant… it is my
interpretation of what has been said.

  1. The current implementation of the event queue in SDL adds latency.
  2. The current implementation of the event queue in SDL is based on a
    10+ year old world view. The hardware and the related OS APIs have
    changed since it was originally written.
  3. Using the newer APIs it may be possible to get rid of the SDL queue
    completely and just use the platform APIs.
    I.e. it may be possible to make the current event oriented SDL API
    into a thin layer over existing OS/Platform APIs.

After that it starts getting real confusing to me… :slight_smile: It seems some
of the APIs would are best suited to be used in a callback based event
delivery system and some are best suited to delivering events into a
queue. And, of course it is easy to use callbacks to deliver events to
a queue and equally easy to use a queue to make call backs.

Bob PendletonOn Sun, Jan 11, 2009 at 6:43 PM, Ryan C. Gordon wrote:


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

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

Maybe I’m crazy, but from my perspective there exists a significant
duality between pollable event sources and signaled event sources.

That means this:

if a series of discrete events can be “coalesced” then they can be
polled (just think about using an implementation of
SDL_GetKeyboardState() driven by coalescing KEYDOWN and KEYUP events)
and if a data source can be polled regularly and key moments
discriminated from boring moments (meaning that you can tell the
difference between noteworthy changes and note-unworthy changes or a
complete absence of change) then you can receive discrete messages on
a pollable source.

Apparently MSWindows does just this: it coalesces pointer motion data
for each application which avoids queuing messages. It logically
follows then SDL is handing application developers pointer motion
"events" which don’t really exist on MSWindows, they are imagined
through a combination of SDL’s polling action and MSWindows’
coalescent pointer data.

If we recognize the duality of pollable data sources (sources which do
not deliver discrete events, but whose state must be queried) and
discrete or signaled event sources (sources which deliver new data in
specific quanta through some API or other) then we can offer SDL users
an opportunity to choose the update delivery model that suits both
their project and the platform best.

For example on MSWindows, the windowing environment will coalesce
pointer data for you. Maybe that suits your application, so on
MSWindows you tell SDL you want to poll pointer motion. On another
platform without a windowing environment that will coalesce pointer
data for you, if you’ve told SDL you want to poll the pointer
position, it can still happen, through the magic of an abstracting
layer called SDL! I really don’t see anything very hard about this,
and it seems necessary for embedded platforms that might not coalesce
anything for you.

Ya’know, the more I read of your writing the more I like you. :slight_smile:

I believe that what you just said is correct.

On a related subject.

In the bad old days artists used Macs over windows for one main
reason. On the Mac when you drew with the mouse or a tablet you got
the curve you drew. On Windows you sometimes got what you drew and you
sometimes got long straight segments because Windows coalesced mouse
motion events. In X there was a configuration flag so that it would
either coalesce mouse motion or not, so that X could behave more like
a Mac, or more like WIndows.

From a user point of view, coalesced mouse motion events can be a
serious problem.

Bob PendletonOn Sun, Jan 11, 2009 at 12:46 PM, Donny Viszneki <donny.viszneki at gmail.com> wrote:


http://codebad.com/


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

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

It seems to me that everyone favors a callback-driven event
dispatching API for the majority of events. Why is it hard to have the
default callbacks fill the SDL event queue, thus being backward
compatible?

It isn’t hard. It is dead easy.

It’s fairly easy, as long as the callback-driven API provides a
"please exit the run loop as soon as you can" function (that isn’t
also a “please quit the program entirely”, of course!). If it doesn’t,
then it becomes pretty horrible, and you still need a “get the next
event” function (possibly that works even if you’re in an event
handler, depending on the level of horribleness involved). If you
don’t have that last bit either, then you’re really in trouble, and to
manage it at all, you might have to create an alternate stack, and
setjmp()/longjmp() around, and whoa, is that ever exciting (and
non-portable)! :slight_smile:

That said, every platform currently supported by SDL do support that,
so it is generally easy (well, some like Mac OS X and BeOS do have
some hoops to jump through, but it could be worse).

It’s also somewhat inefficient (compared to dispatching a callback
right from the event handler), as you have to marshall the event
information into an SDL_Event (if you use callbacks, you might have
to do that, but not all the time, and possibly mostly not), then
return from a few functions (who knows how deep and complicated is the
platform’s event dispatch?). Not a huge deal, though.

What I find a little worrying is that with a low queue depth like 128,
if I’ve got 100 or so sockets, and they’re all ready, and I get a few
other events, then one iteration of the main loop could fill up the
queue and you’d lose events, where I wouldn’t have lost anything if I
had just called the callbacks as I was traversing the FD_SETs returned
from select()…On Tue, Jan 13, 2009 at 12:35 PM, Bob Pendleton wrote:


http://pphaneuf.livejournal.com/

It seems to me that everyone favors a callback-driven event
dispatching API for the majority of events. Why is it hard to have the
default callbacks fill the SDL event queue, thus being backward
compatible?

It isn’t hard. It is dead easy.

It’s fairly easy, as long as the callback-driven API provides a
"please exit the run loop as soon as you can" function (that isn’t
also a “please quit the program entirely”, of course!). If it doesn’t,
then it becomes pretty horrible, and you still need a “get the next
event” function (possibly that works even if you’re in an event
handler, depending on the level of horribleness involved). If you
don’t have that last bit either, then you’re really in trouble, and to
manage it at all, you might have to create an alternate stack, and
setjmp()/longjmp() around, and whoa, is that ever exciting (and
non-portable)! :slight_smile:

If you have a run loop function that is driving the call backs then
you don’t really have a call back based event handling system. You can
just take what is in the run loop function and expose it to the
programmer and my bet is you will find an event queue that you can
just use.

That said, every platform currently supported by SDL do support that,
so it is generally easy (well, some like Mac OS X and BeOS do have
some hoops to jump through, but it could be worse).

It’s also somewhat inefficient (compared to dispatching a callback
right from the event handler), as you have to marshall the event
information into an SDL_Event (if you use callbacks, you might have
to do that, but not all the time, and possibly mostly not), then
return from a few functions (who knows how deep and complicated is the
platform’s event dispatch?). Not a huge deal, though.

What I find a little worrying is that with a low queue depth like 128,
if I’ve got 100 or so sockets, and they’re all ready, and I get a few
other events, then one iteration of the main loop could fill up the
queue and you’d lose events, where I wouldn’t have lost anything if I
had just called the callbacks as I was traversing the FD_SETs returned
from select()…

Yeah, that is why I wrote fastevents… back in 2002.

Bob PendletonOn Tue, Jan 13, 2009 at 1:02 PM, Pierre Phaneuf wrote:

On Tue, Jan 13, 2009 at 12:35 PM, Bob Pendleton <@Bob_Pendleton> wrote:


http://pphaneuf.livejournal.com/


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

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