[skycastle-commits] SF.net SVN: skycastle: [217] trunk/skycastle/modules/utils/src/main/java/ org/skycastle/util/fpscounter/FpsCounter.java

  • From: zzorn@xxxxxxxxxxxxxxxxxxxxx
  • To: skycastle-commits@xxxxxxxxxxxxx
  • Date: Thu, 04 Oct 2007 16:27:33 -0700

Revision: 217
          http://skycastle.svn.sourceforge.net/skycastle/?rev=217&view=rev
Author:   zzorn
Date:     2007-10-04 16:27:33 -0700 (Thu, 04 Oct 2007)

Log Message:
-----------
Some improvements to the FPS counter code

Modified Paths:
--------------
    
trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/fpscounter/FpsCounter.java

Modified: 
trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/fpscounter/FpsCounter.java
===================================================================
--- 
trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/fpscounter/FpsCounter.java
   2007-10-04 23:26:45 UTC (rev 216)
+++ 
trunk/skycastle/modules/utils/src/main/java/org/skycastle/util/fpscounter/FpsCounter.java
   2007-10-04 23:27:33 UTC (rev 217)
@@ -1,35 +1,27 @@
-/**
- * Copyright Hans H\xE4ggstr\xF6m 2004
- * hans.haggstrom at iki dot fi
- */
-
 package org.skycastle.util.fpscounter;
 
 /**
- * A class used to count frames per second.
+ * An utlity class for counting number of frames per second.
  * <p/>
  * Usage: Create an instance, then every frame call onFrame().
  * The frames per second value can be read at any time using getFps().
  * <p/>
- * IDEA: The implementation could use a longer time sampling span than a 
single frame to get
- * around the imprecision of the standard Java timer.
- * <p/>
- * IDEA: Smoothness feature, averaging the FPS value a bit with the previous 
value - this produces smoother changes,
- * IDEA  which is better looking for some kinds of FPS gauges.
- * <p/>
- * IDEA: Make NUMBER_OF_FPS_SAMPLE_FRAMES a caller adjustable property?
+ * Thread safe, as long as onFrame is only called from a single thread.
  *
  * @author Hans H\xE4ggstr\xF6m
  */
-public class FpsCounter
+public final class FpsCounter
 {
 
     //======================================================================
     // Private Fields
 
-    private double myFramesPerSecond = 0;
+    private final Object mySyncLock = new Object();
+
+    // IDEA: Also calculate average over a number of frames, if a smoother 
value is needed, or if trend information is needed.
+    private double myFramesPerSecond = -1;
+    private double mySecondsBetweenFrames = -1;
     private long myFrameStartTime_ns = -1;
-    private double mySecondsSinceLastFrame = 0;
     private boolean myHasPreviousSample = false;
 
     //======================================================================
@@ -45,7 +37,7 @@
 
     /**
      * Creates a new FpsCounter.
-     * Initially the frames per second property will be 0, until onFrame() is 
called.
+     * Initially the frames per second property will be a negative value, 
until onFrame() is called (twice).
      */
     public FpsCounter()
     {
@@ -55,68 +47,85 @@
     // Other Public Methods
 
     /**
-     * @return the number of frames rendered per second, or 0 if the counter 
has not yet been started or has been stopped.
+     * @return the number of frames rendered per second, or a negative value 
if the counter has not yet been started or has been stopped.
      */
     public double getFramesPerSecond()
     {
-        return myFramesPerSecond;
+        synchronized ( mySyncLock )
+        {
+            return myFramesPerSecond;
+        }
     }
 
 
     /**
-     * @return number of seconds since the last frame, or a negative value if 
there were no earlier frames.
+     * @return number of seconds between the most recent frame and the frame 
before that,
+     *         or a negative value if there were no earlier frames.
      *         Uses the averaged frames per second instead of the latest 
measurement.
      */
-    public double getSecondsSinceLastFrame()
+    public double getSecondsBetweenFrames()
     {
-        return mySecondsSinceLastFrame;
+        synchronized ( mySyncLock )
+        {
+            return mySecondsBetweenFrames;
+        }
     }
 
 
     /**
      * Call this method once each frame, to allow the counter to compute the 
frames per second property.
+     * <p/>
+     * NOTE: Should be called from a single thread, or wrapped in a 
syncronized object.  If called from two different
+     * threads, there could be frames with negative fps or 
secondsBetweenFrames.
      */
     public void onFrame()
     {
         // Get start time of current frame
-        long now_ns = System.nanoTime();
+        final long now_ns = System.nanoTime();
 
-        // Only update the fps property if we have two values already, so the 
duration is valid.
-        if ( myHasPreviousSample )
+        synchronized ( mySyncLock )
         {
-            // Calculate the duration since the last frame
-            long duration_ns = now_ns - myFrameStartTime_ns;
+            // Only update the fps property if we have two values already, so 
the duration is valid.
+            if ( myHasPreviousSample )
+            {
+                // Calculate the duration since the last frame
+                long duration_ns = now_ns - myFrameStartTime_ns;
 
-            // Avoid division by zero if the frame rate is very high
-            if ( duration_ns == 0 )
+                // Avoid division by zero if the frame rate is very high
+                if ( duration_ns == 0 )
+                {
+                    duration_ns = 1;
+                }
+
+                // Update the frames per second and time since last frame 
property
+                mySecondsBetweenFrames = ( 1.0 * duration_ns ) / 
TICKS_PER_SECOND;
+                myFramesPerSecond = TICKS_PER_SECOND / duration_ns;
+            }
+            else
             {
-                duration_ns = 1;
+                // Now we have one sample already, so next time we can update 
the property
+                myHasPreviousSample = true;
             }
 
-            // Update the frames per second and time since last frame property
-            mySecondsSinceLastFrame = ( 1.0 * duration_ns ) / TICKS_PER_SECOND;
-            myFramesPerSecond = TICKS_PER_SECOND / duration_ns;
+            // Remember current frame start time
+            myFrameStartTime_ns = now_ns;
         }
-        else
-        {
-            // Now we have one sample already, so next time we can update the 
property
-            myHasPreviousSample = true;
-        }
-
-        // Remember current frame start time
-        myFrameStartTime_ns = now_ns;
     }
 
 
     /**
-     * Sets the frames per second value to 0, until onFrame() is called again.
+     * Sets the frames per second and seconds since last frame value to 
negative values, until onFrame() is called again.
      */
     public void stopCounting()
     {
-        myFramesPerSecond = 0;
-        myHasPreviousSample = false;
+        synchronized ( mySyncLock )
+        {
+            myFramesPerSecond = -1;
+            mySecondsBetweenFrames = -1;
+            myHasPreviousSample = false;
+        }
     }
 
-
 }
 
+


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

Other related posts:

  • » [skycastle-commits] SF.net SVN: skycastle: [217] trunk/skycastle/modules/utils/src/main/java/ org/skycastle/util/fpscounter/FpsCounter.java