View Javadoc

1   /*
2    * Entreri, an entity-component framework in Java
3    *
4    * Copyright (c) 2013, Michael Ludwig
5    * All rights reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without modification,
8    * are permitted provided that the following conditions are met:
9    *
10   *     Redistributions of source code must retain the above copyright notice,
11   *         this list of conditions and the following disclaimer.
12   *     Redistributions in binary form must reproduce the above copyright notice,
13   *         this list of conditions and the following disclaimer in the
14   *         documentation and/or other materials provided with the distribution.
15   *
16   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
20   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23   * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   */
27  package com.lhkbob.entreri.task;
28  
29  import com.lhkbob.entreri.Component;
30  import com.lhkbob.entreri.EntitySystem;
31  
32  import java.util.Collections;
33  import java.util.Set;
34  
35  /**
36   * Timers is a utility class that provides factory methods for creating Tasks that report
37   * {@link ElapsedTimeResult} for use with other tasks that might have time-dependent
38   * behavior.
39   *
40   * @author Michael Ludwig
41   */
42  public final class Timers {
43      private Timers() {
44      }
45  
46      /**
47       * <p/>
48       * Create a new Task that reports an {@link ElapsedTimeResult} with the provided fixed
49       * time delta. It is generally recommended for this task to be one of the first to
50       * execute within a job.
51       * <p/>
52       * The created task always reports the fixed time delta, regardless of true elapsed
53       * time between invocations, and performs no other action.
54       *
55       * @param dt The fixed time delta to always report
56       *
57       * @return Return a task that measures and reports a fixed delta
58       *
59       * @throws IllegalArgumentException if dt is less than or equal to zero
60       */
61      public static Task fixedDelta(double dt) {
62          if (dt <= 0) {
63              throw new IllegalArgumentException("Fixed delta must be positive: " + dt);
64          }
65          return new FixedDeltaTask(dt);
66      }
67  
68      /**
69       * <p/>
70       * Create a new Task that reports an {@link ElapsedTimeResult} with the elapsed time
71       * since the start of the task's last invocation. It is generally recommended for this
72       * task to be one of the first to execute within a job.
73       * <p/>
74       * The created task always reports the measured elapsed time and performs no other
75       * action.
76       *
77       * @return Return a task that measures and reports delta time
78       */
79      public static Task measuredDelta() {
80          return new MeasuredDeltaTask();
81      }
82  
83      /*
84       * Task that reports the same delta each invocation, even if it does equal
85       * the elapsed wall time
86       */
87      private static class FixedDeltaTask implements Task, ParallelAware {
88          private final ElapsedTimeResult delta;
89  
90          public FixedDeltaTask(double dt) {
91              delta = new ElapsedTimeResult(dt);
92          }
93  
94          @Override
95          public Task process(EntitySystem system, Job job) {
96              job.report(delta);
97              return null;
98          }
99  
100         @Override
101         public void reset(EntitySystem system) {
102             // do nothing
103         }
104 
105         @Override
106         public Set<Class<? extends Component>> getAccessedComponents() {
107             return Collections.emptySet();
108         }
109 
110         @Override
111         public boolean isEntitySetModified() {
112             return false;
113         }
114     }
115 
116     /*
117      * Task that measures the time delta from its last invocation
118      */
119     private static class MeasuredDeltaTask implements Task, ParallelAware {
120         private long lastStart = -1L;
121 
122         @Override
123         public Task process(EntitySystem system, Job job) {
124             long now = System.nanoTime();
125             if (lastStart <= 0) {
126                 job.report(new ElapsedTimeResult(0));
127             } else {
128                 job.report(new ElapsedTimeResult((now - lastStart) / 1e9));
129             }
130             lastStart = now;
131 
132             return null;
133         }
134 
135         @Override
136         public void reset(EntitySystem system) {
137             // do nothing
138         }
139 
140         @Override
141         public Set<Class<? extends Component>> getAccessedComponents() {
142             return Collections.emptySet();
143         }
144 
145         @Override
146         public boolean isEntitySetModified() {
147             return false;
148         }
149     }
150 }