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 },
#endif
{ NULL, NULL }, /* Timers */
{ NULL, NULL }, /* FreeTimers */
NULL, /* IdleCallback */
0, /* ActiveMenus */
NULL, /* MenuStateCallback */
@ -235,9 +236,15 @@ void fgDeinitialize( void )
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 );
}
@ -274,7 +281,9 @@ void fgDeinitialize( void )
fgState.Time.Set = GL_FALSE;
fgState.Timers.First = fgState.Timers.Last = NULL;
fgListInit( &fgState.Timers );
fgListInit( &fgState.FreeTimers );
fgState.IdleCallback = NULL;
fgState.MenuStateCallback = ( FGCBMenuState )NULL;
fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;

View File

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

View File

@ -277,38 +277,20 @@ static void fghCheckJoystickPolls( void )
static void fghCheckTimers( void )
{
long checkTime = fgElapsedTime( );
SFG_Timer *timer, *next;
SFG_List timedOut;
SFG_Timer *timer;
fgListInit(&timedOut);
for( timer = (SFG_Timer *)fgState.Timers.First;
timer;
timer = (SFG_Timer *)next )
while( timer = fgState.Timers.First )
{
next = (SFG_Timer *)timer->Node.Next;
if( timer->TriggerTime > checkTime )
break;
if( timer->TriggerTime <= checkTime )
{
fgListRemove( &fgState.Timers, &timer->Node );
fgListAppend( &timedOut, &timer->Node );
}
}
fgListRemove( &fgState.Timers, &timer->Node );
fgListAppend( &fgState.FreeTimers, &timer->Node );
/*
* 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 );
timer->Callback( timer->ID );
}
}
/*
* Elapsed Time
*/
@ -319,12 +301,12 @@ long fgElapsedTime( void )
#if TARGET_HOST_UNIX_X11
struct timeval now;
long elapsed;
gettimeofday( &now, NULL );
elapsed = (now.tv_usec - fgState.Time.Value.tv_usec) / 1000;
elapsed += (now.tv_sec - fgState.Time.Value.tv_sec) * 1000;
return elapsed;
#elif TARGET_HOST_WIN32
return timeGetTime() - fgState.Time.Value;
@ -435,28 +417,16 @@ static int fgHavePendingRedisplays (void)
fgEnumWindows( fgHavePendingRedisplaysCallback, &enumerator );
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.
*/
static long fgNextTimer( void )
{
long now = fgElapsedTime();
long ret = INT_MAX;
SFG_Timer *timer;
for( timer = (SFG_Timer *)fgState.Timers.First;
timer;
timer = (SFG_Timer *)timer->Node.Next )
ret = MIN( ret, MAX( 0, timer->TriggerTime - now ) );
if( (timer = fgState.Timers.First) )
ret = timer->TriggerTime - fgElapsedTime();
return ret;
}
@ -1011,7 +981,8 @@ void FGAPIENTRY glutMainLoopEvent( void )
}
#endif
fghCheckTimers( );
if( fgState.Timers.First )
fghCheckTimers( );
fghCheckJoystickPolls( );
fghDisplayAll( );

View File

@ -643,4 +643,26 @@ int fgListLength(SFG_List *list)
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 ***/