I guess the conclusion of all this is that the entire joystick support
is a horrible mess.
I wouldn’t call it that. The interface is actually pretty clean and
simple for the most part. It just didn’t get as profound a makeover
for 2.0 as some subsystems, aside from some under the hood support
for devices appearing and disappearing. That’s actually a rather big
change internally, but you don’t see much of it because the decision
was made not to change the API if it didn’t need changing.
The event interface returns an instance id mainly because that’s what
the event.which field can hold. That’s annoying in C because the
structure is private and you have to call a getter function to access
it. Call it good OO design or call it keeping some idiot from making
changes to a read-only structure. 
I guess the one advantage of the current API is that you can’t call
SDL_JoystickClose unless you have that pointer. And you don’t have
the pointer unless you opened it.
I guess the biggest problem is if you’re handling things like in my
game, where the input and the events are handled in completely
separate sections, then you have lots of glue code just to be able to
pass the relevant events to the input system, and the more thing one
has to care about, the more glue code is needed.
…or maybe I should be kicked and be demanded to do all the glue work 
You can now have multiple event processors. That’s one of the neat
things about SDL 2.0’s event API. You can watch for input events in
your input code now.
Plus, in C++, you’d be using a Vector most likely, so the issue of
managing a linked list is solved for you. If you’re using C, I
suppose you should already expect to be doing things a bit closer to
bare metal.
To be fair, linked lists are overkill… I mean, you’re never going to
have more than a handful of joysticks connected to the same machine
(heck, I bet you could hardcode the maximum count to 4 and nobody
would notice), and adding and removing are extremely uncommon events,
to the point they may not even happen, and with such a small array, it
isn’t worth the complexity of a full blown list… yeah
I don’t use a list for GameControllers. I use an array. More than 4
will not be in use, so ? why bother?
Joysticks are a little more arbitrary. Think about flight simulator
stuff for people who are serious about it. Separate stick or yoke,
throttle control, pedals? And often these things are sold as
separate USB devices that are all vaguely “joysticks”. Throw in a
wiimote and maybe a couple of gamepads and you’ve got a lot of random
sticks to handle.
So maybe I’m suggesting a brittle solution to the problem of
programmer laziness?
Or perhaps, it really would’ve been much
easier if SDL 2.0 had moved to using instance ids throughout?
Honestly IDs would have been better… except for the fact that an ID
can change its joystick at any moment, and a naively written program
(or worse, a cleverly written one with events being processed in a
separate thread) may end up not noticing that, and we’re back to
square one -_-’
If instance IDs weren’t reusable this may have been a non-problem I guess.
Ah, but instance IDs are NOT reusable.
That you didn’t realize
that explains why you’d think the API is such a mess. It really
isn’t. In SDL 2.0, there are three ways a joystick is identified,
based on what you’re doing with it. They’re all related:
SDL’s internal representation is the instance id. As new joysticks
are found (at startup or while SDL is running), it’s given the next
instance ID. On the Mac, my first joystick was given instance ID 4
until Sam committed a patch that didn’t allow anything but a joystick
to increment the instance ID counter on Darwin systems. Instance IDs
are never reused, and since they’re not guaranteed to start at 0,
they’re useless for loop iteration.
Once a joystick is opened, SDL wants more info about the joystick,
and that goes in the SDL_Joystick structure. Its contents should not
be modified, so as noted you have to call getters if you want the
info contained within.
That leaves opening the joystick. In 1.2, joysticks didn’t use
instance IDs like they do now. They used a device index guaranteed
to be in the range 0 to SDL_NumJoysticks(). Sound familiar? If you
could name anything in the joystick API as “legacy code”, it’s the
device index. It was clearly kept for two reasons:
-
You cannot iterate over instance IDs for all connected joysticks.
-
The alternative would be to have a loop, but then call a function
to get the instance ID for the current loop count so you could open
or query the joystick’s basic info. If you did that, code written
for 1.2’s device indices would compile and then break quietly,
leading to frustrating bugs (probably for users, not developers) and
create all kinds of headaches.
So SDL still uses device indices and they are guaranteed to be
something you can loop over. Because of that, SDL_JOYDEVICEADDED is
the one joystick event that does NOT contain an instance ID. It
comes with a device index. This is documented in SDL_joystick.h but
not yet on the wiki.
JosephOn Sat, Oct 12, 2013 at 10:47:50AM -0300, Sik the hedgehog wrote: