Timer optimizations.

Made the list of pendinig timers ordered.
Added a free list of used timer structures.


git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@372 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
cjp 2003-11-28 19:19:59 +00:00
parent e6de6c2e6f
commit e7a19a5546
4 changed files with 49 additions and 46 deletions

View File

@ -76,6 +76,7 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */
{ { 0, 0 }, GL_FALSE }, { { 0, 0 }, GL_FALSE },
#endif #endif
{ NULL, NULL }, /* Timers */ { NULL, NULL }, /* Timers */
{ NULL, NULL }, /* FreeTimers */
NULL, /* IdleCallback */ NULL, /* IdleCallback */
0, /* ActiveMenus */ 0, /* ActiveMenus */
NULL, /* MenuStateCallback */ NULL, /* MenuStateCallback */
@ -235,9 +236,15 @@ void fgDeinitialize( void )
fgDestroyStructure( ); fgDestroyStructure( );
while( timer = ( SFG_Timer * )fgState.Timers.First ) while( (timer = fgState.Timers.First) )
{ {
fgListRemove ( &fgState.Timers, &timer->Node ); fgListRemove( &fgState.Timers, &timer->Node );
free( timer );
}
while( (timer = fgState.FreeTimers.First) )
{
fgListRemove( &fgState.FreeTimers, &timer->Node );
free( timer ); free( timer );
} }
@ -274,7 +281,9 @@ void fgDeinitialize( void )
fgState.Time.Set = GL_FALSE; fgState.Time.Set = GL_FALSE;
fgState.Timers.First = fgState.Timers.Last = NULL; fgListInit( &fgState.Timers );
fgListInit( &fgState.FreeTimers );
fgState.IdleCallback = NULL; fgState.IdleCallback = NULL;
fgState.MenuStateCallback = ( FGCBMenuState )NULL; fgState.MenuStateCallback = ( FGCBMenuState )NULL;
fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL; fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;

View File

@ -239,6 +239,7 @@ struct tagSFG_State
SFG_Time Time; /* Time that glutInit was called */ SFG_Time Time; /* Time that glutInit was called */
SFG_List Timers; /* The freeglut timer hooks */ SFG_List Timers; /* The freeglut timer hooks */
SFG_List FreeTimers; /* The unused timer hooks */
FGCBIdle IdleCallback; /* The global idle callback */ FGCBIdle IdleCallback; /* The global idle callback */

View File

@ -277,38 +277,20 @@ static void fghCheckJoystickPolls( void )
static void fghCheckTimers( void ) static void fghCheckTimers( void )
{ {
long checkTime = fgElapsedTime( ); long checkTime = fgElapsedTime( );
SFG_Timer *timer, *next; SFG_Timer *timer;
SFG_List timedOut;
fgListInit(&timedOut); while( timer = fgState.Timers.First )
for( timer = (SFG_Timer *)fgState.Timers.First;
timer;
timer = (SFG_Timer *)next )
{ {
next = (SFG_Timer *)timer->Node.Next; if( timer->TriggerTime > checkTime )
break;
if( timer->TriggerTime <= checkTime ) fgListRemove( &fgState.Timers, &timer->Node );
{ fgListAppend( &fgState.FreeTimers, &timer->Node );
fgListRemove( &fgState.Timers, &timer->Node );
fgListAppend( &timedOut, &timer->Node );
}
}
/* timer->Callback( timer->ID );
* Now feel free to execute all the hooked and timed out timer callbacks
* And delete the timed out timers...
*/
while ( (timer = (SFG_Timer *)timedOut.First) )
{
if( timer->Callback != NULL )
timer->Callback( timer->ID );
fgListRemove( &timedOut, &timer->Node );
free( timer );
} }
} }
/* /*
* Elapsed Time * Elapsed Time
*/ */
@ -319,12 +301,12 @@ long fgElapsedTime( void )
#if TARGET_HOST_UNIX_X11 #if TARGET_HOST_UNIX_X11
struct timeval now; struct timeval now;
long elapsed; long elapsed;
gettimeofday( &now, NULL ); gettimeofday( &now, NULL );
elapsed = (now.tv_usec - fgState.Time.Value.tv_usec) / 1000; elapsed = (now.tv_usec - fgState.Time.Value.tv_usec) / 1000;
elapsed += (now.tv_sec - fgState.Time.Value.tv_sec) * 1000; elapsed += (now.tv_sec - fgState.Time.Value.tv_sec) * 1000;
return elapsed; return elapsed;
#elif TARGET_HOST_WIN32 #elif TARGET_HOST_WIN32
return timeGetTime() - fgState.Time.Value; return timeGetTime() - fgState.Time.Value;
@ -435,28 +417,16 @@ static int fgHavePendingRedisplays (void)
fgEnumWindows( fgHavePendingRedisplaysCallback, &enumerator ); fgEnumWindows( fgHavePendingRedisplaysCallback, &enumerator );
return !!enumerator.data; return !!enumerator.data;
} }
/*
* Indicates whether there are any outstanding timers.
*/
#if 0 /* Not used */
static int fgHaveTimers( void )
{
return !!fgState.Timers.First;
}
#endif
/* /*
* Returns the number of GLUT ticks (milliseconds) till the next timer event. * Returns the number of GLUT ticks (milliseconds) till the next timer event.
*/ */
static long fgNextTimer( void ) static long fgNextTimer( void )
{ {
long now = fgElapsedTime();
long ret = INT_MAX; long ret = INT_MAX;
SFG_Timer *timer; SFG_Timer *timer;
for( timer = (SFG_Timer *)fgState.Timers.First; if( (timer = fgState.Timers.First) )
timer; ret = timer->TriggerTime - fgElapsedTime();
timer = (SFG_Timer *)timer->Node.Next )
ret = MIN( ret, MAX( 0, timer->TriggerTime - now ) );
return ret; return ret;
} }
@ -1011,7 +981,8 @@ void FGAPIENTRY glutMainLoopEvent( void )
} }
#endif #endif
fghCheckTimers( ); if( fgState.Timers.First )
fghCheckTimers( );
fghCheckJoystickPolls( ); fghCheckJoystickPolls( );
fghDisplayAll( ); fghDisplayAll( );

View File

@ -643,4 +643,26 @@ int fgListLength(SFG_List *list)
return length; return length;
} }
void fgListInsert(SFG_List *list, SFG_Node *next, SFG_Node *node)
{
SFG_Node *prev;
if( (node->Next = next) )
{
prev = next->Prev;
next->Prev = node;
}
else
{
prev = list->Last;
list->Last = node;
}
if( (node->Prev = prev) )
prev->Next = node;
else
list->First = node;
}
/*** END OF FILE ***/ /*** END OF FILE ***/