Skip to content

Commit e88edd1

Browse files
authored
Merge pull request #2048 from yunline/joystick-fix
Remove `event._joy_instance_map`
2 parents be7ab7c + 41da177 commit e88edd1

File tree

7 files changed

+64
-115
lines changed

7 files changed

+64
-115
lines changed

docs/reST/c_api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pygame C API
1212
c_api/display.rst
1313
c_api/event.rst
1414
c_api/freetype.rst
15+
c_api/joystick.rst
1516
c_api/mixer.rst
1617
c_api/rect.rst
1718
c_api/rwobject.rst

docs/reST/c_api/joystick.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
.. include:: ../common.txt
2+
3+
.. highlight:: c
4+
5+
******************************************
6+
API exported by pygame.joystick
7+
******************************************
8+
9+
src_c/joystick.c
10+
================
11+
12+
The extension module :py:mod:`pygame.joystick`.
13+
14+
Header file: src_c/include/pygame.h
15+
16+
.. c:var:: PyTypeObject *pgJoystick_Type
17+
18+
The Pygame joystick object type :py:class:`pygame.Joystick`.
19+
20+
.. c:function:: PyObject* pgJoystick_New(int id)
21+
22+
Return a new :py:class:`pygame.Joystick` instance.
23+
On failure, raise a Python exception and return ``NULL``.
24+
25+
.. c:function:: int pgJoystick_GetDeviceIndexByInstanceID(int instance_id)
26+
27+
Get the device index of a joystick by a instance id.
28+
Return a device index.
29+
On failure, it returns -1.

src_c/_pygame.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ struct pgColorObject {
331331
*/
332332

333333
#define PYGAMEAPI_RECT_NUMSLOTS 10
334-
#define PYGAMEAPI_JOYSTICK_NUMSLOTS 2
334+
#define PYGAMEAPI_JOYSTICK_NUMSLOTS 3
335335
#define PYGAMEAPI_DISPLAY_NUMSLOTS 2
336336
#define PYGAMEAPI_SURFACE_NUMSLOTS 4
337337
#define PYGAMEAPI_SURFLOCK_NUMSLOTS 8

src_c/event.c

Lines changed: 13 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,6 @@
5353

5454
#define PG_GET_LIST_LEN 128
5555

56-
// Map joystick instance IDs to device ids for partial backwards compatibility
57-
static PyObject *joy_instance_map = NULL;
58-
5956
/* _custom_event stores the next custom user event type that will be
6057
* returned by pygame.event.custom_type() */
6158
#define _PGE_CUSTOM_EVENT_INIT PGE_USEREVENT + 1
@@ -851,51 +848,11 @@ get_joy_guid(int device_index)
851848
return PyUnicode_FromString(strguid);
852849
}
853850

854-
/** Try to insert the instance ID for a new device into the joystick mapping.
855-
*/
856-
void
857-
_joy_map_add(int device_index)
858-
{
859-
int instance_id = (int)SDL_JoystickGetDeviceInstanceID(device_index);
860-
PyObject *k, *v;
861-
if (instance_id != -1) {
862-
k = PyLong_FromLong(instance_id);
863-
v = PyLong_FromLong(device_index);
864-
if (k != NULL && v != NULL) {
865-
PyDict_SetItem(joy_instance_map, k, v);
866-
}
867-
Py_XDECREF(k);
868-
Py_XDECREF(v);
869-
}
870-
}
871-
872-
/** Look up a device ID for an instance ID. */
873-
PyObject *
874-
_joy_map_instance(int instance_id)
875-
{
876-
PyObject *v, *k = PyLong_FromLong(instance_id);
877-
if (!k) {
878-
Py_RETURN_NONE;
879-
}
880-
v = PyDict_GetItem(joy_instance_map, k);
881-
if (v) {
882-
Py_DECREF(k);
883-
Py_INCREF(v);
884-
return v;
885-
}
886-
return k;
887-
}
888-
889-
/** Discard a joystick from the joystick instance -> device mapping. */
890-
void
891-
_joy_map_discard(int instance_id)
851+
static PyObject *
852+
get_joy_device_index(int instance_id)
892853
{
893-
PyObject *k = PyLong_FromLong(instance_id);
894-
895-
if (k) {
896-
PyDict_DelItem(joy_instance_map, k);
897-
Py_DECREF(k);
898-
}
854+
int device_index = pgJoystick_GetDeviceIndexByInstanceID(instance_id);
855+
return PyLong_FromLong(device_index);
899856
}
900857

901858
static PyObject *
@@ -995,23 +952,23 @@ dict_from_event(SDL_Event *event)
995952
PyBool_FromLong((event->button.which == SDL_TOUCH_MOUSEID)));
996953
break;
997954
case SDL_JOYAXISMOTION:
998-
_pg_insobj(dict, "joy", _joy_map_instance(event->jaxis.which));
955+
_pg_insobj(dict, "joy", get_joy_device_index(event->jaxis.which));
999956
_pg_insobj(dict, "instance_id",
1000957
PyLong_FromLong(event->jaxis.which));
1001958
_pg_insobj(dict, "axis", PyLong_FromLong(event->jaxis.axis));
1002959
_pg_insobj(dict, "value",
1003960
PyFloat_FromDouble(event->jaxis.value / 32767.0));
1004961
break;
1005962
case SDL_JOYBALLMOTION:
1006-
_pg_insobj(dict, "joy", _joy_map_instance(event->jaxis.which));
963+
_pg_insobj(dict, "joy", get_joy_device_index(event->jaxis.which));
1007964
_pg_insobj(dict, "instance_id",
1008965
PyLong_FromLong(event->jball.which));
1009966
_pg_insobj(dict, "ball", PyLong_FromLong(event->jball.ball));
1010967
obj = Py_BuildValue("(ii)", event->jball.xrel, event->jball.yrel);
1011968
_pg_insobj(dict, "rel", obj);
1012969
break;
1013970
case SDL_JOYHATMOTION:
1014-
_pg_insobj(dict, "joy", _joy_map_instance(event->jaxis.which));
971+
_pg_insobj(dict, "joy", get_joy_device_index(event->jaxis.which));
1015972
_pg_insobj(dict, "instance_id",
1016973
PyLong_FromLong(event->jhat.which));
1017974
_pg_insobj(dict, "hat", PyLong_FromLong(event->jhat.hat));
@@ -1028,7 +985,7 @@ dict_from_event(SDL_Event *event)
1028985
break;
1029986
case SDL_JOYBUTTONUP:
1030987
case SDL_JOYBUTTONDOWN:
1031-
_pg_insobj(dict, "joy", _joy_map_instance(event->jaxis.which));
988+
_pg_insobj(dict, "joy", get_joy_device_index(event->jaxis.which));
1032989
_pg_insobj(dict, "instance_id",
1033990
PyLong_FromLong(event->jbutton.which));
1034991
_pg_insobj(dict, "button", PyLong_FromLong(event->jbutton.button));
@@ -1158,7 +1115,6 @@ dict_from_event(SDL_Event *event)
11581115
_pg_insobj(dict, "guid", get_joy_guid(event->jdevice.which));
11591116
break;
11601117
case SDL_JOYDEVICEADDED:
1161-
_joy_map_add(event->jdevice.which);
11621118
_pg_insobj(dict, "device_index",
11631119
PyLong_FromLong(event->jdevice.which));
11641120
_pg_insobj(dict, "guid", get_joy_guid(event->jdevice.which));
@@ -1170,7 +1126,6 @@ dict_from_event(SDL_Event *event)
11701126
PyLong_FromLong(event->cdevice.which));
11711127
break;
11721128
case SDL_JOYDEVICEREMOVED:
1173-
_joy_map_discard(event->jdevice.which);
11741129
_pg_insobj(dict, "instance_id",
11751130
PyLong_FromLong(event->jdevice.which));
11761131
break;
@@ -2263,6 +2218,11 @@ MODINIT_DEFINE(event)
22632218
return NULL;
22642219
}
22652220

2221+
import_pygame_joystick();
2222+
if (PyErr_Occurred()) {
2223+
return NULL;
2224+
}
2225+
22662226
/* type preparation */
22672227
if (PyType_Ready(&pgEvent_Type) < 0) {
22682228
return NULL;
@@ -2274,15 +2234,6 @@ MODINIT_DEFINE(event)
22742234
return NULL;
22752235
}
22762236

2277-
joy_instance_map = PyDict_New();
2278-
/* need to keep a reference for use in the module */
2279-
Py_XINCREF(joy_instance_map);
2280-
if (PyModule_AddObject(module, "_joy_instance_map", joy_instance_map)) {
2281-
Py_XDECREF(joy_instance_map);
2282-
Py_DECREF(module);
2283-
return NULL;
2284-
}
2285-
22862237
Py_INCREF(&pgEvent_Type);
22872238
if (PyModule_AddObject(module, "EventType", (PyObject *)&pgEvent_Type)) {
22882239
Py_DECREF(&pgEvent_Type);

src_c/include/_pygame.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ typedef struct pgJoystickObject {
229229

230230
#define pgJoystick_Check(x) ((x)->ob_type == &pgJoystick_Type)
231231
#define pgJoystick_New (*(PyObject * (*)(int)) PYGAMEAPI_GET_SLOT(joystick, 1))
232+
#define pgJoystick_GetDeviceIndexByInstanceID \
233+
(*(int (*)(int))PYGAMEAPI_GET_SLOT(joystick, 2))
232234

233235
#define import_pygame_joystick() IMPORT_PYGAME_MODULE(joystick)
234236
#endif

src_c/joystick.c

Lines changed: 16 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,11 @@
2828
#include "doc/joystick_doc.h"
2929

3030
static pgJoystickObject *joylist_head = NULL;
31-
#ifndef BUILD_STATIC
32-
static PyObject *joy_instance_map = NULL;
33-
#endif // BUILD_STATIC joy_instance_map already defined in src_c/event.c:57
3431
static PyTypeObject pgJoystick_Type;
3532
static PyObject *
3633
pgJoystick_New(int);
3734
static int
38-
_joy_map_insert(pgJoystickObject *jstick);
35+
pgJoystick_GetDeviceIndexByInstanceID(int);
3936
#define pgJoystick_Check(x) ((x)->ob_type == &pgJoystick_Type)
4037

4138
static PyObject *
@@ -130,39 +127,9 @@ joy_init(PyObject *self, PyObject *_null)
130127
}
131128
}
132129

133-
if (-1 == _joy_map_insert(jstick)) {
134-
return NULL;
135-
}
136-
137130
Py_RETURN_NONE;
138131
}
139132

140-
static int
141-
_joy_map_insert(pgJoystickObject *jstick)
142-
{
143-
SDL_JoystickID instance_id;
144-
PyObject *k, *v;
145-
146-
if (!joy_instance_map) {
147-
return -1;
148-
}
149-
150-
instance_id = SDL_JoystickInstanceID(jstick->joy);
151-
if (instance_id < 0) {
152-
PyErr_SetString(pgExc_SDLError, SDL_GetError());
153-
return -1;
154-
}
155-
k = PyLong_FromLong(instance_id);
156-
v = PyLong_FromLong(jstick->id);
157-
if (k && v) {
158-
PyDict_SetItem(joy_instance_map, k, v);
159-
}
160-
Py_XDECREF(k);
161-
Py_XDECREF(v);
162-
163-
return 0;
164-
}
165-
166133
static PyObject *
167134
joy_quit(PyObject *self, PyObject *_null)
168135
{
@@ -546,6 +513,20 @@ static PyTypeObject pgJoystick_Type = {
546513
.tp_methods = joy_methods,
547514
};
548515

516+
static int
517+
pgJoystick_GetDeviceIndexByInstanceID(int instance_id)
518+
{
519+
pgJoystickObject *cur;
520+
cur = joylist_head;
521+
while (cur) {
522+
if (SDL_JoystickInstanceID(cur->joy) == instance_id) {
523+
return cur->id;
524+
}
525+
cur = cur->next;
526+
}
527+
return -1;
528+
}
529+
549530
static PyObject *
550531
pgJoystick_New(int id)
551532
{
@@ -588,11 +569,6 @@ pgJoystick_New(int id)
588569
}
589570
joylist_head = jstick;
590571

591-
if (-1 == _joy_map_insert(jstick)) {
592-
Py_DECREF(jstick);
593-
return NULL;
594-
}
595-
596572
return (PyObject *)jstick;
597573
}
598574

@@ -632,17 +608,6 @@ MODINIT_DEFINE(joystick)
632608
return NULL;
633609
}
634610

635-
/* Grab the instance -> device id mapping */
636-
module = PyImport_ImportModule("pygame.event");
637-
if (!module) {
638-
return NULL;
639-
}
640-
joy_instance_map = PyObject_GetAttrString(module, "_joy_instance_map");
641-
Py_DECREF(module);
642-
if (!joy_instance_map) {
643-
return NULL;
644-
}
645-
646611
/* create the module */
647612
module = PyModule_Create(&_module);
648613
if (module == NULL) {
@@ -660,6 +625,7 @@ MODINIT_DEFINE(joystick)
660625
/* export the c api */
661626
c_api[0] = &pgJoystick_Type;
662627
c_api[1] = pgJoystick_New;
628+
c_api[2] = pgJoystick_GetDeviceIndexByInstanceID;
663629
apiobj = encapsulate_api(c_api, "joystick");
664630
if (PyModule_AddObject(module, PYGAMEAPI_LOCAL_ENTRY, apiobj)) {
665631
Py_XDECREF(apiobj);

src_c/static.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,14 +355,14 @@ PyInit_pygame_static()
355355
#undef pgEvent_Type
356356
#undef pgEvent_New
357357

358+
#include "joystick.c"
359+
358360
#include "event.c"
359361

360362
#include "mouse.c"
361363

362364
#include "key.c"
363365

364-
#include "joystick.c"
365-
366366
#include "time.c"
367367

368368
#include "system.c"

0 commit comments

Comments
 (0)