Commits

Michael Ludwig committed 8b67e5f

Update ControllerManager to use real delta time for default process() method.

  • Participants
  • Parent commits 456418a

Comments (0)

Files changed (4)

src/main/java/com/lhkbob/entreri/Controller.java

      * 
      * @param dt The elapsed time since the last processing
      */
-    public void preProcess(float dt);
+    public void preProcess(double dt);
 
     /**
      * Invoke controller specific operations to process the EntitySystem. All
      * 
      * @param dt The elapsed time since the last processing
      */
-    public void process(float dt);
+    public void process(double dt);
 
     /**
      * Invoked at the end of a processing phase after all controllers in a
      * 
      * @param dt The elapsed time since the last processing
      */
-    public void postProcess(float dt);
+    public void postProcess(double dt);
 
     /**
      * Invoked when a Controller is added to an EntitySystem. This method

src/main/java/com/lhkbob/entreri/ControllerManager.java

         ALL
     }
 
-    private float fixedDelta;
     private final List<Controller> controllers;
-    
     private final Map<Controller, ProfileData> profile;
     
     // This is a concurrent map so that parallel controllers can access it efficiently
     private final ConcurrentHashMap<Key<?>, Object> controllerData;
 
     private final EntitySystem system;
+    
+    private long lastProcessTime;
 
     /**
      * Create a new ControllerManager that will store controllers and controller
         controllers = new ArrayList<Controller>();
         
         profile = new HashMap<Controller, ProfileData>();
-        
-        fixedDelta = 1 / 60f; // 60fps
-    }
-
-    /**
-     * Set a new fixed time frame delta. This can take any value and represents
-     * the number of seconds between each frame, so negative values may produce
-     * undefined results with some controllers. This value is only used if
-     * {@link #process()} is invoked, the other varieties take a delta value
-     * that overrides this one.
-     * 
-     * @param dt The new time frame delta
-     */
-    public void setFixedDelta(float dt) {
-        fixedDelta = dt;
-    }
-
-    /**
-     * @return The current fixed time frame delta that is used if
-     *         {@link #process()} is invoked
-     */
-    public float getFixedDelta() {
-        return fixedDelta;
+        lastProcessTime = -1L;
     }
 
     /**
     }
     
     /**
-     * Run all phases of the manager using the current fixed frame time delta.
+     * Run all phases of the manager using the time delta from the last time the
+     * post-process phase was executed. This means that the time delta is
+     * reasonably defined even if {@link #process(double)} and
+     * {@link #process(Phase, double)} are used in addition to this process()
+     * call.
      */
     public void process() {
-        process(fixedDelta);
+        if (lastProcessTime < 0)
+            process(0);
+        else
+            process((System.nanoTime() - lastProcessTime) / 1e9);
     }
 
     /**
      * @param dt The time delta for the frame, or the amount of time since the
      *            start of the last frame and this one
      */
-    public void process(float dt) {
+    public void process(double dt) {
         process(Phase.ALL, dt);
     }
 
      *            start of the last frame and this one
      * @throws NullPointerException if phase is null
      */
-    public void process(Phase phase, float dt) {
+    public void process(Phase phase, double dt) {
         if (phase == null)
             throw new NullPointerException("Phase cannot be null");
         
             controllers.get(i).onComponentRemove(c);
     }
     
-    private void firePreProcess(float dt) {
+    private void firePreProcess(double dt) {
         for (int i = 0; i < controllers.size(); i++) {
             long start = System.nanoTime();
             controllers.get(i).preProcess(dt);
         }
     }
     
-    private void fireProcess(float dt) {
+    private void fireProcess(double dt) {
         for (int i = 0; i < controllers.size(); i++) {
             long start = System.nanoTime();
             controllers.get(i).process(dt);
         }
     }
     
-    private void firePostProcess(float dt) {
+    private void firePostProcess(double dt) {
         for (int i = 0; i < controllers.size(); i++) {
             long start = System.nanoTime();
             controllers.get(i).postProcess(dt);
             profile.get(controllers.get(i)).postprocessTime = System.nanoTime() - start;
         }
+        
+        lastProcessTime = System.nanoTime();
     }
     
     private static class ProfileData {

src/main/java/com/lhkbob/entreri/SimpleController.java

     private EntitySystem system;
     
     @Override
-    public void preProcess(float dt) {
+    public void preProcess(double dt) {
         // do nothing in base class
     }
 
     @Override
-    public void process(float dt) {
+    public void process(double dt) {
         // do nothing in base class
     }
 
     @Override
-    public void postProcess(float dt) {
+    public void postProcess(double dt) {
         // do nothing in base class
     }
 

src/test/java/com/lhkbob/entreri/ControllerManagerTest.java

         EntitySystem system = new EntitySystem();
         system.getControllerManager().addController(controller);
         
-        system.getControllerManager().process(Phase.PREPROCESS, 0f);
+        system.getControllerManager().process(Phase.PREPROCESS, 0);
         
         Assert.assertTrue(controller.preprocessed);
         Assert.assertFalse(controller.processed);
         EntitySystem system = new EntitySystem();
         system.getControllerManager().addController(controller);
         
-        system.getControllerManager().process(Phase.PROCESS, 0f);
+        system.getControllerManager().process(Phase.PROCESS, 0);
         
         Assert.assertFalse(controller.preprocessed);
         Assert.assertTrue(controller.processed);
         EntitySystem system = new EntitySystem();
         system.getControllerManager().addController(controller);
         
-        system.getControllerManager().process(Phase.POSTPROCESS, 0f);
+        system.getControllerManager().process(Phase.POSTPROCESS, 0);
         
         Assert.assertFalse(controller.preprocessed);
         Assert.assertFalse(controller.processed);
         EntitySystem system = new EntitySystem();
         system.getControllerManager().addController(controller);
         
-        system.getControllerManager().process(Phase.ALL, 0f);
+        system.getControllerManager().process(Phase.ALL, 0);
         
         Assert.assertTrue(controller.preprocessed);
         Assert.assertTrue(controller.processed);
     }
     
     @Test
-    public void testFixedDelta() {
+    public void testComputedDelta() throws Exception {
         ControllerImpl controller = new ControllerImpl();
         EntitySystem system = new EntitySystem();
         system.getControllerManager().addController(controller);
         
-        system.getControllerManager().setFixedDelta(1f);
+        system.getControllerManager().process();
+        // 1st process() uses a dt of 0
+        Assert.assertEquals(0.0, controller.dt, .0001);
+        
+        Thread.sleep(10);
         
         system.getControllerManager().process();
-        
         Assert.assertTrue(controller.preprocessed);
         Assert.assertTrue(controller.processed);
         Assert.assertTrue(controller.postprocessed);
-        Assert.assertEquals(1f, controller.dt, .0001f);
+        // must be at least 10 ms, within 2 ms error either direction
+        Assert.assertTrue(controller.dt > .008);
+        Assert.assertTrue(controller.dt < .012);
     }
     
     @Test
         EntitySystem system = new EntitySystem();
         system.getControllerManager().addController(controller);
         
-        system.getControllerManager().setFixedDelta(-1f);
-        
         system.getControllerManager().process(1f);
         
         Assert.assertTrue(controller.preprocessed);
         Assert.assertTrue(controller.processed);
         Assert.assertTrue(controller.postprocessed);
-        Assert.assertEquals(1f, controller.dt, .0001f);
+        Assert.assertEquals(1f, controller.dt, .0001);
     }
     
     @Test
         private boolean processed;
         private boolean postprocessed;
         
-        private float dt;
+        private double dt;
         
         private boolean added;
         private boolean removed;
         }
         
         @Override
-        public void preProcess(float dt) {
+        public void preProcess(double dt) {
             preprocessed = true;
             this.dt = dt;
         }
 
         @Override
-        public void process(float dt) {
+        public void process(double dt) {
             processed = true;
             this.dt = dt;
         }
 
         @Override
-        public void postProcess(float dt) {
+        public void postProcess(double dt) {
             postprocessed = true;
             this.dt = dt;
         }