As far as I understand a union in C can hold only 1 value at a time and I don't really understand how this code in C makes sense since event.window cannot be populated at the same time as event.type ?
while(SDL_PollEvent(&event)) {
switch(event.type)
{
case SDL_WINDOWEVENT:
switch(event.window.event)
The event is defined as:
typedef union SDL_Event
{
Uint32 type; /**< Event type, shared with all events */
SDL_CommonEvent common; /**< Common event data */
SDL_WindowEvent window; /**< Window event data */
SDL_KeyboardEvent key; /**< Keyboard event data */
SDL_TextEditingEvent edit; /**< Text editing event data */
SDL_TextInputEvent text; /**< Text input event data */
SDL_MouseMotionEvent motion; /**< Mouse motion event data */
SDL_MouseButtonEvent button; /**< Mouse button event data */
SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */
SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */
SDL_JoyBallEvent jball; /**< Joystick ball event data */
SDL_JoyHatEvent jhat; /**< Joystick hat event data */
SDL_JoyButtonEvent jbutton; /**< Joystick button event data */
SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */
SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */
SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */
SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */
SDL_QuitEvent quit; /**< Quit request event data */
SDL_UserEvent user; /**< Custom event data */
SDL_SysWMEvent syswm; /**< System dependent window event data */
SDL_TouchFingerEvent tfinger; /**< Touch finger event data */
SDL_MultiGestureEvent mgesture; /**< Gesture event data */
SDL_DollarGestureEvent dgesture; /**< Gesture event data */
SDL_DropEvent drop; /**< Drag and drop event data */
/* This is necessary for ABI compatibility between Visual C++ and GCC
Visual C++ will respect the push pack pragma and use 52 bytes for
this structure, and GCC will use the alignment of the largest datatype
within the union, which is 8 bytes.
So... we'll add padding to force the size to be 56 bytes for both.
*/
Uint8 padding[56];
} SDL_Event;
Every aggregate ( struct
s probably) member SDL_CommonEvent common;
, SDL_WindowEvent window;
, SDL_KeyboardEvent key;
etc... of the union SDL_Event
is starting with some Uint32
field giving the type
and that common type
field has the same address and size in every union member.
So while indeed a union carries only one field at once in memory (in other words, all union members have the same address), each of them starts with a type
and the event.type
makes sense; it fetches that type
.
Such an idiom is a common way in C to implement tagged unions .
Every member of the SDL_Event
union starts with the same two members, Uint32 type
and Uint32 timestamp
. The C standard specifically says that if a union is currently holding a value of one struct type, but read as another struct type whose first members match the other struct type, it's okay to read those matching members.
All other SDL_X
types all begin with a type of 32 bits. In fact, they all seem to include the fields in SDL_CommonEvent
at the beginning. This is to facilitate accesing common elements to all sub-structures. Then, by event.common.x
you can access all the common elements without having to differentiate the exact type of event.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.