Fixed bug 2414 - Execute event watchers in the order they were added
authorSam Lantinga
Sat, 22 Feb 2014 15:27:11 -0800
changeset 823480c193c7c8c8
parent 8233 ffece8ab18a6
child 8235 cc1d377f014a
Fixed bug 2414 - Execute event watchers in the order they were added

Leonardo

Event watchers are being executed on the inverse order they are added because they are added to the head of the SDL_event_watchers list.

Since watchers are allowed to change events before they are reported (they shouldn't, imo), this breaks code that rely on watcher execution order (such as distributed event handling).

An easy scenario to see this behaving weird to the user is if you add an event watcher to check mouse coordinates and check them again in your event loop. If you add the watcher after renderer's one (which always happens after you have initialized renderer), you get the same event but different coordinates.

The proposed patch adds the event watcher in the tail of the list, not in the beginning, and correctly fixes this problem.
src/events/SDL_events.c
     1.1 --- a/src/events/SDL_events.c	Sat Feb 22 15:23:09 2014 -0800
     1.2 +++ b/src/events/SDL_events.c	Sat Feb 22 15:27:11 2014 -0800
     1.3 @@ -503,17 +503,28 @@
     1.4  void
     1.5  SDL_AddEventWatch(SDL_EventFilter filter, void *userdata)
     1.6  {
     1.7 -    SDL_EventWatcher *watcher;
     1.8 +    SDL_EventWatcher *watcher, *tail;
     1.9  
    1.10      watcher = (SDL_EventWatcher *)SDL_malloc(sizeof(*watcher));
    1.11      if (!watcher) {
    1.12          /* Uh oh... */
    1.13          return;
    1.14      }
    1.15 +
    1.16 +    /* create the watcher */
    1.17      watcher->callback = filter;
    1.18      watcher->userdata = userdata;
    1.19 -    watcher->next = SDL_event_watchers;
    1.20 -    SDL_event_watchers = watcher;
    1.21 +    watcher->next = NULL;
    1.22 +
    1.23 +    /* add the watcher to the end of the list */
    1.24 +    if (SDL_event_watchers) {
    1.25 +        for (tail = SDL_event_watchers; tail->next; tail = tail->next) {
    1.26 +            continue;
    1.27 +        }
    1.28 +        tail->next = watcher;
    1.29 +    } else {
    1.30 +        SDL_event_watchers = watcher;
    1.31 +    }
    1.32  }
    1.33  
    1.34  /* FIXME: This is not thread-safe yet */