Complete.Org:
Mailing Lists:
Archives:
freeciv-dev:
February 2003: [Freeciv-Dev] Re: (PR#3391) SDL client polls the network |
[Freeciv-Dev] Re: (PR#3391) SDL client polls the network[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
> Currently the SDL client monitors the network connection by polling > every 100 milliseconds for data. This leads to a lot of lag in updates. > > The correct thing to do is to get an interrupt or callback that is > activated when network data is available. This is what the other > clients do (although it is possible that the underlying libraries just > do polling, we would hope not). However, in my brief research I don't > see how to do this with SDL. Is it possible that this functionality is > not portable? How could anyone ever program on a system that didn't > provide this? Rafal asked me yesterday the question. I searched a bit and found nothing. The canonical solution looks like this: Thread 1: 1) select on network input 2) push an event in the SDL event queue 3) goto 1) Thread 2: 1) wait for SDL event queue 2) act according to the event (mouse, network) 3) goto 1) The other is polling (see our current code). I completely agree that this is a big design error in SDL.Lets take a look (http://www.libsdl.org/cgi/cvsweb.cgi/SDL12/src/events/SDL_events.c?rev=1.9&content-type=text/x-cvsweb-markup):/* Run the system dependent event loops */ void SDL_PumpEvents(void) { if (!SDL_EventThread) { SDL_VideoDevice *video = current_video; SDL_VideoDevice *this = current_video; /* Get events from the video subsystem */ if (video) { video->PumpEvents(this); } /* Queue pending key-repeat events */ SDL_CheckKeyRepeat(); #ifndef DISABLE_JOYSTICK /* Check for joystick state change */ if (SDL_numjoysticks && (SDL_eventstate & SDL_JOYEVENTMASK)) { SDL_JoystickUpdate(); } #endif } } int SDL_WaitEvent(SDL_Event * event) { while (1) { SDL_PumpEvents(); switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) { case -1: return 0; case 1: return 1; case 0: SDL_Delay(10); } } } So this is even worse. It has a built in polling every 10ms. HiAs I say before SDL is Simple DirectMedia Layer that was design to work on many enviroment. Event code was create also for work on no-threaded system ( Windows ???? ) and with single thread program. In this role work great but it doesn't mean its good solution :( Some time before Bob Pendelton fight with this problem and he creatae thread based event code (see: http://gameprogrammer.com/game.html ) we can use his code ( is small see attach ) and write somthing like : /* Secoudary thread */ static int socket_thread(void *socket) { struct timeval tv; fd_set civfdset; SDL_Event ev; ev.type = SDL_USEREVENT; ev.user.code = 0; ev.user.data1 = 0; ev.user.data2 = 0; while (net_socket >= 0) { FD_ZERO(&civfdset); FD_SET(net_socket, &civfdset); tv.tv_sec = 0; tv.tv_usec = 0; if (select(FD_SETSIZE, &civfdset, NULL, NULL, &tv)) { if (FD_ISSET(net_socket, &civfdset)) { FE_PushEvent(&ev); } } } /* while */ return 0; } /* Primary Thread */ void add_net_input(int sock) { freelog(LOG_DEBUG, "Connection UP (%d)", sock); net_socket = sock; pThread = SDL_CreateThread(socket_thread, NULL); } void remove_net_input(void) { net_socket = (-1); freelog(LOG_DEBUG, "Connection DOWN... "); SDL_WaitThread(pThread, NULL);} and in main event loop : FE_WaitEvent(&Main.event); switch (Main.event.type) { case SDL_QUIT: return; case SDL_USEREVENT: input_from_server(net_socket); break; ... But when I use it I can't make debug with gdb :( Rafal ---------------------------------------------------------------------- KOBIETA > Uroda >>> http://link.interia.pl/f16cd
fastevents.h
fastevents.c
|