Reworked event queue stuff to work effienciently with SDL_GETEVENT.
authorRyan C. Gordon <icculus@icculus.org>
Wed, 10 Apr 2013 15:44:31 -0400
changeset 20c4f19f562177
parent 19 bb548168a73b
child 21 acd0dd6933f3
Reworked event queue stuff to work effienciently with SDL_GETEVENT.
src/SDL12_compat.c
     1.1 --- a/src/SDL12_compat.c	Sun Mar 31 22:20:07 2013 -0400
     1.2 +++ b/src/SDL12_compat.c	Wed Apr 10 15:44:31 2013 -0400
     1.3 @@ -336,9 +336,16 @@
     1.4  
     1.5  // !!! FIXME: need a mutex for the event queue.
     1.6  #define SDL12_MAXEVENTS 128
     1.7 -static SDL12_Event EventQueue[SDL12_MAXEVENTS];
     1.8 -static int EventQueueRead = 0;
     1.9 -static int EventQueueWrite = 0;
    1.10 +typedef struct EventQueueType
    1.11 +{
    1.12 +    SDL12_Event event12;
    1.13 +    struct EventQueueType *next;
    1.14 +} EventQueueType;
    1.15 +
    1.16 +static EventQueueType EventQueuePool[SDL12_MAXEVENTS];
    1.17 +static EventQueueType *EventQueueHead = NULL;
    1.18 +static EventQueueType *EventQueueTail = NULL;
    1.19 +static EventQueueType *EventQueueAvailable = NULL;
    1.20  
    1.21  /* Obviously we can't use SDL_LoadObject() to load SDL2.  :)  */
    1.22  #if defined(_WINDOWS)
    1.23 @@ -450,8 +457,13 @@
    1.24      rc = justsubs ? SDL20_InitSubSystem(sdl20flags) : SDL20_Init(sdl20flags);
    1.25      if ((rc == 0) && (sdl20flags & SDL_INIT_VIDEO))
    1.26      {
    1.27 -        EventQueueRead = EventQueueWrite = 0;
    1.28 -        SDL_zero(EventQueue);
    1.29 +        int i;
    1.30 +        for (i = 0; i < SDL12_MAXEVENTS-1; i++)
    1.31 +            EventQueuePool[i].next = &EventQueuePool[i+1];
    1.32 +        EventQueuePool[SDL12_MAXEVENTS-1].next = NULL;
    1.33 +        EventQueueHead = EventQueueTail = NULL;
    1.34 +        EventQueueAvailable = EventQueuePool;
    1.35 +
    1.36          SDL20_SetEventFilter(EventFilter20to12, NULL);
    1.37          VideoDisplayIndex = GetVideoDisplay();
    1.38      }
    1.39 @@ -515,8 +527,7 @@
    1.40      // !!! FIXME: reset a bunch of other global variables too.
    1.41      if (sdl12flags & SDL12_INIT_VIDEO) {
    1.42          EventFilter12 = NULL;
    1.43 -        EventQueueRead = EventQueueWrite = 0;
    1.44 -        SDL_zero(EventQueue);
    1.45 +        EventQueueAvailable = EventQueueHead = EventQueueTail = NULL;
    1.46          SDL20_FreeFormat(VideoInfo.vfmt);
    1.47          SDL_zero(VideoInfo);
    1.48      }
    1.49 @@ -532,8 +543,7 @@
    1.50  {
    1.51      // !!! FIXME: reset a bunch of other global variables too.
    1.52      EventFilter12 = NULL;
    1.53 -    EventQueueRead = EventQueueWrite = 0;
    1.54 -    SDL_zero(EventQueue);
    1.55 +    EventQueueAvailable = EventQueueHead = EventQueueTail = NULL;
    1.56      SDL20_FreeFormat(VideoInfo.vfmt);
    1.57      SDL_zero(VideoInfo);
    1.58      CDRomInit = 0;
    1.59 @@ -783,24 +793,36 @@
    1.60  int
    1.61  SDL_PollEvent(SDL12_Event *event12)
    1.62  {
    1.63 +    EventQueueType *next;
    1.64 +
    1.65      SDL20_PumpEvents();  /* this will run our filter and build our 1.2 queue. */
    1.66  
    1.67 -    if (EventQueueRead >= EventQueueWrite)
    1.68 +    if (EventQueueHead == NULL)
    1.69          return 0;  /* no events at the moment. */
    1.70  
    1.71 -    SDL_memcpy(event12, &EventQueue[EventQueueRead % SDL12_MAXEVENTS], sizeof (SDL12_Event));
    1.72 -    EventQueueRead++;
    1.73 +    SDL_memcpy(event12, &EventQueueHead->event12, sizeof (SDL12_Event));
    1.74 +    next = EventQueueHead->next;
    1.75 +    EventQueueHead->next = EventQueueAvailable;
    1.76 +    EventQueueAvailable = EventQueueHead;
    1.77 +    EventQueueHead = next;
    1.78      return 1;
    1.79  }
    1.80  
    1.81  int
    1.82  SDL_PushEvent(SDL12_Event *event12)
    1.83  {
    1.84 -    if ((EventQueueWrite - EventQueueRead) >= SDL12_MAXEVENTS)
    1.85 +    EventQueueType *item = EventQueueAvailable;
    1.86 +    if (item == NULL)
    1.87          return -1;  /* no space available at the moment. */
    1.88  
    1.89 -    SDL_memcpy(&EventQueue[EventQueueWrite % SDL12_MAXEVENTS], event12, sizeof (SDL12_Event));
    1.90 -    EventQueueWrite++;
    1.91 +    EventQueueAvailable = item->next;
    1.92 +    if (EventQueueTail)
    1.93 +        EventQueueTail->next = item;
    1.94 +    else
    1.95 +        EventQueueHead = EventQueueTail = item;
    1.96 +    item->next = NULL;
    1.97 +
    1.98 +    SDL_memcpy(&item->event12, event12, sizeof (SDL12_Event));
    1.99      return 0;
   1.100  }
   1.101  
   1.102 @@ -813,42 +835,48 @@
   1.103      {
   1.104          for (i = 0; i < numevents; i++)
   1.105          {
   1.106 -            if ((EventQueueWrite - EventQueueRead) >= SDL12_MAXEVENTS)
   1.107 +            if (SDL_PushEvent(&events12[i]) == -1)
   1.108                  break;  /* out of space for more events. */
   1.109 -            SDL_memcpy(&EventQueue[EventQueueWrite % SDL12_MAXEVENTS], &events12[i], sizeof (SDL12_Event));
   1.110 -            EventQueueWrite++;
   1.111          }
   1.112          return i;
   1.113      }
   1.114      else if ((action == SDL_PEEKEVENT) || (action == SDL_GETEVENT))
   1.115      {
   1.116 -        const SDL_bool isGet = (action == SDL_GETEVENT);
   1.117 -        int seen = 0;
   1.118 +        const int isGet = (action == SDL_GETEVENT);
   1.119 +        EventQueueType *prev = NULL;
   1.120 +        EventQueueType *item = EventQueueHead;
   1.121 +        EventQueueType *next = NULL;
   1.122          int chosen = 0;
   1.123          while (chosen < numevents)
   1.124          {
   1.125 -            const SDL12_Event *event12;
   1.126 -
   1.127 -            if ((EventQueueRead + seen) >= EventQueueWrite)
   1.128 +            EventQueueType *nextPrev = item;
   1.129 +            if (!item)
   1.130                  break;  /* no more events at the moment. */
   1.131  
   1.132 -            event12 = &EventQueue[(EventQueueRead+seen) % SDL12_MAXEVENTS];
   1.133 -            seen++;
   1.134 +            next = item->next;  /* copy, since we might overwrite item->next */
   1.135  
   1.136              if (mask & (1<<event12->type))
   1.137              {
   1.138 -                SDL_memcpy(&events12[chosen++], event12, sizeof (SDL12_Event));
   1.139 -                if (isGet) {
   1.140 -                    event12->type = 0xFF;  /* mark it used. */
   1.141 +                SDL_memcpy(&events12[chosen++], &item->event12, sizeof (SDL12_Event));
   1.142 +                if (isGet)  /* remove from list? */
   1.143 +                {
   1.144 +                    if (prev != NULL)
   1.145 +                        prev->next = next;
   1.146 +                    if (item == EventQueueHead)
   1.147 +                        EventQueueHead = next;
   1.148 +                    if (item == EventQueueTail)
   1.149 +                        EventQueueTail = prev;
   1.150 +
   1.151 +                    /* put it back in the free pool. */
   1.152 +                    item->next = EventQueueAvailable;
   1.153 +                    EventQueueAvailable = item;
   1.154 +                    nextPrev = prev;  /* previous item doesn't change. */
   1.155                  }
   1.156              }
   1.157 +
   1.158 +            item = next;
   1.159 +            prev = nextPrev;
   1.160          }
   1.161 -
   1.162 -        if (isGet)
   1.163 -        {
   1.164 -            // !!! FIXME: remove events we ate.
   1.165 -        }
   1.166 -
   1.167          return chosen;
   1.168      }
   1.169