Proposed changes to the event system

Here’s the plan that I have in mind. Some of those steps are
refactorings of the “remove this function, then fix what broke”. The
API to SDL itself should be backward compatible after this, but the
API of video drivers would change.

The first step is one of the hardest. We’d start by replacing the
PumpEvents method of SDL_VideoDevice with one along the lines of this:

/* A negative timeout means to wait indefinitely, returns 1 if an
event was returned, 0 otherwise (or maybe -1 for an error?). /
int GetEvent(_THIS, SDL_Event
event, int timeout);

Yes, yes, a timeout, the crowds will go wild, I’m sure… :wink:

An SDL_WaitEventTimeout with a similar signature would be added, which
would check the SDL event queue and return an event from there if
there is one, or otherwise call GetEvent. SDL_PollEvent and
SDL_WaitEvent would be simply wrappers for this single call, with the
appropriate timeout.

At this point, there is no systematic superfluous queueing or
SDL_Delay in SDL_WaitEvent. Unless the video driver is silly, as we’ll
see next… :slight_smile:

There is a quick video driver migration path, which would be to
implement their GetEvent in a way similar to how SDL_WaitEvent is
currently implemented, only needing to add the timeout feature. This
could even be provided in a general way by the core SDL, but you
should have the goal of eliminating any need for it, of course,
because it’s silly. :slight_smile:

That leaves just my third point from my previous email (not being
possible to wait for events at the same time as something else).

Adding timer events would be trivial, done in SDL_WaitEventTimeout,
checking whether a timer has expired before calling GetEvent, skipping
it if there was, if there wasn’t, tweaking the timeout so that it
returns before the next one, and finally return the next timer event
if GetEvent timed out (or wasn’t called). These timers would not have
the low latency of the existing timers, but would remove the threading
requirement, would never tell you that a platform doesn’t support
multiple timers, and most importantly, you would not have the “you
can’t call any functions except SDL_PushEvent” restriction. For a
caller that just calls SDL_PushEvent, this would probably be more
efficient, actually (no context switching or mutex/queue
manipulation). The existing timer feature can remain as is, anyway.

Support for other, more interesting things, like file descriptors,
though, would be a bit more work, and every type would require
modifying all the video drivers that support it, since they would be
responsible for dealing with it. Realistically, we should probably
pull a fast one and just add support for “sockets”, which would really
support all matters of stuff based on file descriptors on Unix
platforms, but would portably just be sockets (Win32 is funky that
way, for example).

There’s a few questions, still…

Should SDL_PeepEvents still just “check the event queue”, or should it
actually wrap GetEvent as well? If the latter, then peeking be a
little bit icky, if the queue is empty, it would GetEvent, push it on
the queue, then do the peek as it is now (for those who are paying
attention, yes, this is a bit of a race, although it shouldn’t change
outcomes significantly).

SDL_HasEvent could behave a bit strangely. If you checked whether it
has an event and then do SDL_PollEvent right away, you could very well
be told that a certain type of event is not available, and get exactly
that right away. Does anyone really use that? Not very popular, it
seems: http://google.com/codesearch?q=SDL_HasEvent&hl=en&btnG=Search+Code

Oh, it’s new to 1.3 and only used internally… To work around the
event queue. :wink:

Is the event thread actually used much? It’s not supported on a major
top-tier platform (Windows), that makes it’s general usefulness rather
questionable, IMHO, and it’s the kind of thing that would tend to muck
up things (I think it would work with my changes, it would just be
rather wacky, and I wouldn’t really like to be you if you hit a bug!).

I’m sure there will be a zillion other niggly details, but that’s
basically the plan I have. What do you think?–
http://pphaneuf.livejournal.com/

Is the event thread actually used much?

Not really, it was originally added to support a responsive color mouse
cursor. We still need to support that somehow, but many systems have them
directly now.

I’m sure there will be a zillion other niggly details, but that’s
basically the plan I have. What do you think?

One of the biggest questions I have is how you’ll integrate SDL_PushEvent()
on the various platforms.

Also, I noticed this plan ties the timers to the event loop, which is a bad
idea for some uses of the timer functionality. (e.g. real-time processing)

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

Is the event thread actually used much?

Not really, it was originally added to support a responsive color mouse
cursor. We still need to support that somehow, but many systems have them
directly now.

A “responsive color mouse”? What the heck is that?!?

In Quadra, I used an 8192 bytes fragment size, with 16-bit stereo
samples, making for a single fragment to contain about 46 milliseconds
of sound, and that pretty much never skipped (only fades while the
very gross PseudoColor emulation I had hacked). Granted, that’s only
20 Hz or so, but doing some measurement by moving the mouse around
with a test program, you can get past 100 Hz resolution on that.

The mouse cursor in Quadra used to be done by our application when
fullscreen, too, and it didn’t seem awful. Is that what you mean?

I’m sure there will be a zillion other niggly details, but that’s
basically the plan I have. What do you think?

One of the biggest questions I have is how you’ll integrate SDL_PushEvent()
on the various platforms.

Well, the icky transition workaround that I described basically works
just the same as the current SDL_WaitEvent, so if that works, it’ll
work. :slight_smile:

But you are correct, I forgot one part: SDL_VideoDevice will also need
a new WakeGetEvent, which would tell it to look at the event queue.
While using the transition workaround, it should be a no-op, but an
X11 version of that could be a non-blocking write of a single byte to
a pipe, to wake up a select(). On Cocoa, it might be to send ourselves
a dummy Cocoa event, etc…

Also, I noticed this plan ties the timers to the event loop, which is a bad
idea for some uses of the timer functionality. (e.g. real-time processing)

As I mentioned, the existing timer feature can remain as it is, this
is just in addition to it. If all your timer callbacks do is
SDL_PushEvent, use the new stuff, it’ll be at least as good,
otherwise, keep using the existing stuff.On Mon, Jan 12, 2009 at 3:30 PM, Sam Lantinga wrote:


http://pphaneuf.livejournal.com/

Is the event thread actually used much?

Not really, it was originally added to support a responsive color mouse
cursor. We still need to support that somehow, but many systems have them
directly now.

A “responsive color mouse”? What the heck is that?!?

Oh, and how was this responsive color mouse done on Win32?On Mon, Jan 12, 2009 at 4:03 PM, Pierre Phaneuf <@Pierre_Phaneuf> wrote:


http://pphaneuf.livejournal.com/

But you are correct, I forgot one part: SDL_VideoDevice will also need
a new WakeGetEvent, which would tell it to look at the event queue.

Please forgive the intrusion of a simple, lightweight game programmer such as myself in this deep, technical discussion, but this is touching on one of my biggest gripes in SDL. Why in the WORLD is event processing coupled so tightly with the video subsystem? What does the one have to do with the other? From the application developer’s viewpoint, they’re two completely different things. If you’re trying to fix problems in SDL_Events, why don’t you start out by decoupling it from the video?>----- Original Message ----

From: Pierre Phaneuf
Subject: Re: [SDL] proposed changes to the event system

In modern GUIs (Windows, X-Window, etc.), it’s typical for a user’s
keyboard input and mouse events to be attached to a window (otherwise,
how does the user know where their typing will go?)

I think that’s the reason,On Mon, Jan 12, 2009 at 01:31:05PM -0800, Mason Wheeler wrote:

Please forgive the intrusion of a simple, lightweight game programmer such as myself in this deep, technical discussion, but this is touching on one of my biggest gripes in SDL. Why in the WORLD is event processing coupled so tightly with the video subsystem? What does the one have to do with the other? From the application developer’s viewpoint, they’re two completely different things. If you’re trying to fix problems in SDL_Events, why don’t you start out by decoupling it from the video?


-bill!
“Tux Paint” - free children’s drawing software for Windows / Mac OS X / Linux!
Download it today! http://www.tuxpaint.org/

In modern GUIs (Windows, X-Window, etc.), it’s typical for a user’s
keyboard input and mouse events to be attached to a window (otherwise,
how does the user know where their typing will go?)

I think that’s the reason,

Is that how it works by default? That sounds very strange to me. Maybe it’s just that I’m used to Delphi, where the application, not the window, receives the events, then resolves the proper control and passes it on to its message-handling methods. (Of course, that only works under a strong object-oriented framework with an Application object to control program execution.)

So is that the reason why we’re stuck with event processing tied to the video subsystem?>----- Original Message ----

From: Bill Kendrick
Subject: Re: [SDL] proposed changes to the event system

Hello !

So is that the reason why we’re stuck with event processing tied to
the video subsystem?

I may be wrong, but i think especially in Win32 you need to
have a window, to get events, even if that window is not visible.

CU

Hello !

So is that the reason why we’re stuck with event processing tied to the video subsystem?

I may be wrong, but i think especially in Win32 you need to
have a window, to get events, even if that window is not visible.

Aha! That would explain why Delphi’s Application object generates an invisible window that doesn’t seem to do anything. It’s catching all the events because Windows’s C-centric viewpoint for event dispatching is an ugly hack, so it needs an ugly counter-hack to convert them to elegant event processing. :p>----- Original Message ----

From: Torsten Giebl
Subject: Re: [SDL] proposed changes to the event system

Based on my experience with GUIs at the OS level, I would say that this way
of dealing
with events is actually quite common. Microsoft didn’t invent anything new
there.On Tue, Jan 13, 2009 at 12:13 AM, Mason Wheeler wrote:

----- Original Message ----

From: Torsten Giebl
Subject: Re: [SDL] proposed changes to the event system

Hello !

So is that the reason why we’re stuck with event processing tied to the
video subsystem?

I may be wrong, but i think especially in Win32 you need to
have a window, to get events, even if that window is not visible.

Aha! That would explain why Delphi’s Application object generates an
invisible window that doesn’t seem to do anything. It’s catching all the
events because Windows’s C-centric viewpoint for event dispatching is an
ugly hack, so it needs an ugly counter-hack to convert them to elegant event
processing. :stuck_out_tongue:


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

Is that how it works by default? That sounds very strange to me. Maybe it’s just that I’m used to Delphi, where the application, not the window, receives the events, then resolves the proper control and passes it on to its message-handling methods. (Of course, that only works under a strong object-oriented framework with an Application object to control program execution.)

So is that the reason why we’re stuck with event processing tied to the video subsystem?

That’s pretty much it, yeah. Even in Delphi, windows actually receive
events eventually, when the application doesn’t handle them.

Fundamentally, it’s not really that events are tied to windows,
strictly speaking, but rather to the windowing/display system in use.
With X11, you use XNextEvent, with Win32, you use GetMessage, and so
on. There are some where this is not true, like Svgalib and fbcon, but
they are the exception more than the rule. You can see that the OS
itself is not a sufficient level of abstraction, because on Windows,
you could potentially make an X11 application that does not call
GetMessage (assuming that Xlib doesn’t use it itself, which is totally
possible if it used Winsock’s select()).

So it’s just more convenient to tie the two together, even though
there’s some stuff that’s unrelated (like socket events). Since in an
SDL game the vast majority of events originate from the windowing
system or the game itself, it’s easier that way.

Note that if you wanted to have the two separate so that you could
share more code with, say, a dedicated server, it would be possible to
make the GetEvent implementation of the dummy video driver do
something appropriate (select() on Unix, for example), so it would be
usable and quite efficient (compared to now, slightly less CPU usage,
no 10ms+epsilon rounding of event delivery timing and no need for a
separate thread to collect network events and push them across a
context switch)…On Mon, Jan 12, 2009 at 5:46 PM, Mason Wheeler wrote:


http://pphaneuf.livejournal.com/

Aha! That would explain why Delphi’s Application object generates an invisible window that doesn’t seem to do anything. It’s catching all the events because Windows’s C-centric viewpoint for event dispatching is an ugly hack, so it needs an ugly counter-hack to convert them to elegant event processing. :stuck_out_tongue:

The thing is, Win32 “windows” are poorly named. They’re more “objects
that can receive events” (in Cocoa parlance, something like an
NSResponder), with invisible windows being sort of the parent class
(NSResponder itself), and normal windows are derived class that
actually do things. See the following:

http://msdn.microsoft.com/en-us/library/ms632599(VS.85).aspx#message_only

In a similar family, X11 has InputOnly windows, but those have more
"flesh" to them, they actually have a size, location and z-order,
they’re used when you want to track the mouse in a region without
actually displaying anything there. They are incredibly rarely used.
:-)On Mon, Jan 12, 2009 at 6:13 PM, Mason Wheeler wrote:


http://pphaneuf.livejournal.com/

The thing is, Win32 “windows” are poorly named. They’re more “objects
that can receive events” (in Cocoa parlance, something like an
NSResponder), with invisible windows being sort of the parent class
(NSResponder itself), and normal windows are derived class that
actually do things. See the following:

Yeah. I don’t know Cocoa, but I do know that in Delphi, almost all of the common controls have a “Window Handle” that allows them to both receive input focus and contain other controls. A “window” is more properly called a Form.>----- Original Message ----

From: Pierre Phaneuf
Subject: Re: [SDL] proposed changes to the event system
On Mon, Jan 12, 2009 at 6:13 PM, Mason Wheeler <@Mason_Wheeler> wrote:

Is the event thread actually used much?

Not really, it was originally added to support a responsive color mouse
cursor. We still need to support that somehow, but many systems have them
directly now.

A “responsive color mouse”? What the heck is that?!?

The key word you left out of your quotation is “cursor”. A color
cursor is one that has more than 2 colors. You want a nice multicolor
cursor you have to implement it yourself. You do it by 1) disabling
the default cursor. 2) drawing your own cursor at the current mouse
location. When the cursor moves you redraw what was behind it and then
draw the cursor its new location.

BTW, this is exactly how all cursors are drawn on systems that do not
have hardware cursor support. In the really really old days of 1 bit
displays you could use the xor trick, but then it turned out that AT&T
had a patent on that so everyone stopped using xor on displays and
then video DACs with hardware cursor support came along and everyone,
except game programmers, forgot about software cursors.

Wow, I was at the X consortium meeting when AT&T announced they had
that patent and were going to go after people for cash to use it…
Talk about a test for how civilized folks are :slight_smile: Yeah, I am that
old.

Oh, and how was this responsive color mouse done on Win32?

Same way as on any other system. The same way I just described.

Bob PendletonOn Mon, Jan 12, 2009 at 3:04 PM, Pierre Phaneuf wrote:

On Mon, Jan 12, 2009 at 4:03 PM, Pierre Phaneuf wrote:


http://pphaneuf.livejournal.com/


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

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

A “responsive color mouse”? What the heck is that?!?

The key word you left out of your quotation is “cursor”. A color
cursor is one that has more than 2 colors. You want a nice multicolor
cursor you have to implement it yourself. You do it by 1) disabling
the default cursor. 2) drawing your own cursor at the current mouse
location. When the cursor moves you redraw what was behind it and then
draw the cursor its new location.

Oh, and how was this responsive color mouse done on Win32?

Same way as on any other system. The same way I just described.

Under Windows, it is possible to get the OS to draw a color cursor.
The APIs are not very portable, and I am not sure if the functionality
is supported in anything earlier than WinXP. It is doable, and has
the advantage that the OS can, if need be, draw the cursor at a higher
framerate than that of the application.

I’m a bit hazy on the exact Windows calls required, as I’ve only
started to investigate this myself for an app I am working on. If I
end up getting this working, I could send you more info on the
details.On Tue, Jan 13, 2009 at 2:05 PM, Bob Pendleton wrote:

On Mon, Jan 12, 2009 at 3:04 PM, Pierre Phaneuf wrote:


David Ludwig
@David_Ludwig

Under Windows, it is possible to get the OS to draw a color cursor.
The APIs are not very portable, and I am not sure if the functionality
is supported in anything earlier than WinXP. It is doable, and has
the advantage that the OS can, if need be, draw the cursor at a higher
framerate than that of the application.

I’m a bit hazy on the exact Windows calls required, as I’ve only
started to investigate this myself for an app I am working on. If I
end up getting this working, I could send you more info on the
details.

Yep, I’m planning to add that for SDL 1.3, possibly with animated cursor
support, so I’d love to hear your experiences.

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

Yep, I’m planning to add that for SDL 1.3, possibly with animated cursor
support, so I’d love to hear your experiences.

So, what do you think of the plan I laid out?On Tue, Jan 13, 2009 at 10:40 PM, Sam Lantinga wrote:


http://pphaneuf.livejournal.com/

Hi,

working on multiple events at once would be good (aka, a batching
API). So you can add multiple events at once to the queue, and get
back multiple events. For lots of events, this is a much better idea
I think.

Is it worth looking at high performance event systems like libevent,
libev, kqueue, epoll?
http://monkey.org/~provos/libevent/
http://software.schmorp.de/pkg/libev.html

Making sure the event system could be used with those high performance
event libraries would be swell :slight_smile:

Being able to process events quickly could open up new types of games.
It’s not to hard to see that some games could get a lot more events
than currently – with multiple mice, cameras, networking, wiimotes
etc.

cu,

Yep, I’m planning to add that for SDL 1.3, possibly with animated cursor
support, so I’d love to hear your experiences.

So, what do you think of the plan I laid out?

I think I’d like to see pseudo code implementation for the various platforms
so I can see how your ideas translate into platform specific logic. Go ahead
and keep it high level, maybe comparing it to the existing implementation.

I’m looking forward to seeing it. :slight_smile:

See ya!
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC> On Tue, Jan 13, 2009 at 10:40 PM, Sam Lantinga wrote:

working on multiple events at once would be good (aka, a batching
API). So you can add multiple events at once to the queue, and get
back multiple events. For lots of events, this is a much better idea
I think.

I agree in principles, but we have to work with what the platforms
provide. For example, X11’s XNextEvent returns just one, so that’s
what you get. Internally, it does get more than one, so as far as
issuing too many system calls, it’s doing okay.

Is it worth looking at high performance event systems like libevent,
libev, kqueue, epoll?
http://monkey.org/~provos/libevent/

Heh, that’s my manager at work, nice guy, and a fiercely good
programmer. Also, have a look at the acknowledgements in the README
(https://levent.svn.sourceforge.net/svnroot/levent/trunk/libevent/README).
:wink:

Making sure the event system could be used with those high performance
event libraries would be swell :slight_smile:

I’m afraid that would be, as they say, beyond the scope of this
project, unfortunately. In some cases, like on Windows, we have to use
the GetMessage API, which (if I remember correctly), libevent and
friends don’t wrap (they usually wrap the select() provided by
Winsock).

That said, it would depend on the drivers. The X11 driver, after my
modifications, could optionally use epoll (or one of those libraries)
if it’s available, since it only needs watching on file descriptors.
I’ll start with just a plain old select(), though, first. :wink:

You’re also free to use libevent on another thread, by the way, but if
you end up throwing back work at the main thread (through
SDL_PushEvent, say), or competing with it on some mutex in your game
logic, say, then you won’t really have an advantage over using these
new APIs I’m proposing. But sometimes you can do a chunk of processing
independently, and only interact with the main thread briefly (say,
implement a complicated handshake protocol in the thread, then when
it’s done just send a “new connection” message to the main thread, for
example). You’ll have to experiment yourself with that, I’m afraid…
My experience is either with servers that only do the libevent-style
thing (I used to be one of the main WvStreams developer, we did
awesome with that stuff!) or with games, but not both at same time.
:slight_smile:

Being able to process events quickly could open up new types of games.
It’s not to hard to see that some games could get a lot more events
than currently – with multiple mice, cameras, networking, wiimotes
etc.

My planned approach for the X11 driver, anyway, would certainly make
it fairly capable at handling networking for up to about a thousand
sockets, easy, at which point it then becomes more a problem of
select() than our code (either we hit the maximum size of FD_SET, or
the its O(N) complexity bites us). If we detect and optionally use the
better APIs like epoll, then it would probably go even further. After
that, well, show me some profiler output, and we’ll talk. :wink:

Cameras is the only other one I’d worry about, since it’s the only one
that has the potential to have high throughput, but it could probably
be handled by moving that processing in a separate thread.On Wed, Jan 14, 2009 at 1:04 AM, Ren? Dudfield wrote:


http://pphaneuf.livejournal.com/