Timer optimizations.
authorChristopher John Purnell <cjp@lost.org.uk>
Fri, 28 Nov 2003 19:19:59 +0000 (19:19 +0000)
committerChristopher John Purnell <cjp@lost.org.uk>
Fri, 28 Nov 2003 19:19:59 +0000 (19:19 +0000)
Made the list of pendinig timers ordered.
Added a free list of used timer structures.

git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@372 7f0cb862-5218-0410-a997-914c9d46530a

src/freeglut_init.c
src/freeglut_internal.h
src/freeglut_main.c
src/freeglut_structure.c

index b23e152..0289ddd 100644 (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;
index e7f1100..03b08bf 100644 (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       */
 
index 8350e32..55e033a 100644 (file)
@@ -277,38 +277,20 @@ static void fghCheckJoystickPolls( void )
 static void fghCheckTimers( void )
 {
     long checkTime = fgElapsedTime( );
-    SFG_Timer *timer, *next;
-    SFG_List timedOut;
-
-    fgListInit(&timedOut);
+    SFG_Timer *timer;
 
-    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;
@@ -436,27 +418,15 @@ static int fgHavePendingRedisplays (void)
     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( );
 
index 292ce7b..583f744 100644 (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 ***/