SDL_timer.c
资源名称:NETVIDEO.rar [点击查看]
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:7k
源码类别:
流媒体/Mpeg4/MP4
开发平台:
Visual C++
- /*
- SDL - Simple DirectMedia Layer
- Copyright (C) 1997, 1998 Sam Lantinga
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Sam Lantinga
- 5635-34 Springhouse Dr.
- Pleasanton, CA 94588 (USA)
- slouken@libsdl.org
- */
- #ifdef SAVE_RCSID
- static char rcsid =
- "@(#) $Id: SDL_timer.c,v 1.4 2002/04/22 21:38:03 wmay Exp $";
- #endif
- #include <stdlib.h>
- #include <stdio.h> /* For the definition of NULL */
- #include "SDL_error.h"
- #include "SDL_timer.h"
- #include "SDL_timer_c.h"
- #include "SDL_mutex.h"
- #include "SDL_systimer.h"
- /* #define DEBUG_TIMERS */
- int SDL_timer_started = 0;
- int SDL_timer_running = 0;
- /* Data to handle a single periodic alarm */
- Uint32 SDL_alarm_interval = 0;
- SDL_TimerCallback SDL_alarm_callback;
- static SDL_bool list_changed = SDL_FALSE;
- /* Data used for a thread-based timer */
- static int SDL_timer_threaded = 0;
- struct _SDL_TimerID {
- Uint32 interval;
- SDL_NewTimerCallback cb;
- void *param;
- Uint32 last_alarm;
- struct _SDL_TimerID *next;
- };
- static SDL_TimerID SDL_timers = NULL;
- static Uint32 num_timers = 0;
- static SDL_mutex *SDL_timer_mutex;
- /* Set whether or not the timer should use a thread.
- This should not be called while the timer subsystem is running.
- */
- int SDL_SetTimerThreaded(int value)
- {
- int retval;
- if ( SDL_timer_started ) {
- SDL_SetError("Timer already initialized");
- retval = -1;
- } else {
- retval = 0;
- SDL_timer_threaded = value;
- }
- return retval;
- }
- int SDL_TimerInit(void)
- {
- int retval;
- SDL_timer_running = 0;
- SDL_SetTimer(0, NULL);
- retval = 0;
- if ( ! SDL_timer_threaded ) {
- retval = SDL_SYS_TimerInit();
- }
- if ( SDL_timer_threaded ) {
- SDL_timer_mutex = SDL_CreateMutex();
- }
- SDL_timer_started = 1;
- return(retval);
- }
- void SDL_TimerQuit(void)
- {
- SDL_SetTimer(0, NULL);
- if ( SDL_timer_threaded < 2 ) {
- SDL_SYS_TimerQuit();
- }
- if ( SDL_timer_threaded ) {
- SDL_DestroyMutex(SDL_timer_mutex);
- }
- SDL_timer_started = 0;
- SDL_timer_threaded = 0;
- }
- void SDL_ThreadedTimerCheck(void)
- {
- Uint32 now, ms;
- SDL_TimerID t, prev, next;
- int removed;
- now = SDL_GetTicks();
- SDL_mutexP(SDL_timer_mutex);
- for ( prev = NULL, t = SDL_timers; t; t = next ) {
- removed = 0;
- ms = t->interval - SDL_TIMESLICE;
- next = t->next;
- if ( (t->last_alarm < now) && ((now - t->last_alarm) > ms) ) {
- if ( (now - t->last_alarm) < t->interval ) {
- t->last_alarm += t->interval;
- } else {
- t->last_alarm = now;
- }
- list_changed = SDL_FALSE;
- #ifdef DEBUG_TIMERS
- printf("Executing timer %p (thread = %d)n",
- t, SDL_ThreadID());
- #endif
- SDL_mutexV(SDL_timer_mutex);
- ms = t->cb(t->interval, t->param);
- SDL_mutexP(SDL_timer_mutex);
- if ( list_changed ) {
- /* Abort, list of timers has been modified */
- break;
- }
- if ( ms != t->interval ) {
- if ( ms ) {
- t->interval = ROUND_RESOLUTION(ms);
- } else { /* Remove the timer from the linked list */
- #ifdef DEBUG_TIMERS
- printf("SDL: Removing timer %pn", t);
- #endif
- if ( prev ) {
- prev->next = next;
- } else {
- SDL_timers = next;
- }
- free(t);
- -- num_timers;
- removed = 1;
- }
- }
- }
- /* Don't update prev if the timer has disappeared */
- if ( ! removed ) {
- prev = t;
- }
- }
- SDL_mutexV(SDL_timer_mutex);
- }
- SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_NewTimerCallback callback, void *param)
- {
- SDL_TimerID t;
- if ( ! SDL_timer_mutex ) {
- if ( SDL_timer_started ) {
- SDL_SetError("This platform doesn't support multiple timers");
- } else {
- SDL_SetError("You must call SDL_Init(SDL_INIT_TIMER) first");
- }
- return NULL;
- }
- if ( ! SDL_timer_threaded ) {
- SDL_SetError("Multiple timers require threaded events!");
- return NULL;
- }
- SDL_mutexP(SDL_timer_mutex);
- t = (SDL_TimerID) malloc(sizeof(struct _SDL_TimerID));
- if ( t ) {
- t->interval = ROUND_RESOLUTION(interval);
- t->cb = callback;
- t->param = param;
- t->last_alarm = SDL_GetTicks();
- t->next = SDL_timers;
- SDL_timers = t;
- ++ num_timers;
- list_changed = SDL_TRUE;
- SDL_timer_running = 1;
- }
- #ifdef DEBUG_TIMERS
- printf("SDL_AddTimer(%d) = %08x num_timers = %dn", interval, (Uint32)t, num_timers);
- #endif
- SDL_mutexV(SDL_timer_mutex);
- return t;
- }
- SDL_bool SDL_RemoveTimer(SDL_TimerID id)
- {
- SDL_TimerID t, prev = NULL;
- SDL_bool removed;
- removed = SDL_FALSE;
- SDL_mutexP(SDL_timer_mutex);
- /* Look for id in the linked list of timers */
- for (t = SDL_timers; t; prev=t, t = t->next ) {
- if ( t == id ) {
- if(prev) {
- prev->next = t->next;
- } else {
- SDL_timers = t->next;
- }
- free(t);
- -- num_timers;
- removed = SDL_TRUE;
- list_changed = SDL_TRUE;
- break;
- }
- }
- #ifdef DEBUG_TIMERS
- printf("SDL_RemoveTimer(%08x) = %d num_timers = %d thread = %dn", (Uint32)id, removed, num_timers, SDL_ThreadID());
- #endif
- SDL_mutexV(SDL_timer_mutex);
- return removed;
- }
- static void SDL_RemoveAllTimers(SDL_TimerID t)
- {
- SDL_TimerID freeme;
- /* Changed to non-recursive implementation.
- The recursive implementation is elegant, but subject to
- stack overflow if there are lots and lots of timers.
- */
- while ( t ) {
- freeme = t;
- t = t->next;
- free(freeme);
- }
- }
- /* Old style callback functions are wrapped through this */
- static Uint32 callback_wrapper(Uint32 ms, void *param)
- {
- SDL_TimerCallback func = (SDL_TimerCallback) param;
- return (*func)(ms);
- }
- int SDL_SetTimer(Uint32 ms, SDL_TimerCallback callback)
- {
- int retval;
- #ifdef DEBUG_TIMERS
- printf("SDL_SetTimer(%d)n", ms);
- #endif
- retval = 0;
- if ( SDL_timer_running ) { /* Stop any currently running timer */
- SDL_timer_running = 0;
- if ( SDL_timer_threaded ) {
- SDL_mutexP(SDL_timer_mutex);
- SDL_RemoveAllTimers(SDL_timers);
- SDL_timers = NULL;
- SDL_mutexV(SDL_timer_mutex);
- } else {
- SDL_SYS_StopTimer();
- }
- }
- if ( ms ) {
- if ( SDL_timer_threaded ) {
- retval = (SDL_AddTimer(ms, callback_wrapper,
- (void *)callback) != NULL);
- } else {
- SDL_timer_running = 1;
- SDL_alarm_interval = ms;
- SDL_alarm_callback = callback;
- retval = SDL_SYS_StartTimer();
- }
- }
- return retval;
- }