hmi.util
Class SystemClock

java.lang.Object
  extended by hmi.util.SystemClock

public class SystemClock
extends Object

How to use in practice:

  1. Allocate a SystemClock object, say "clock "
  2. Add one or more ClockListeners by means of the addClockListener() method. Each ClockListener must implement the ClockListener interface, which means that it must have a method of type public void time(double currentTime).
  3. When desired, the clock can send a first time() call to all listeners, without starting the clock running, by means of the initMediaTime() method.
  4. Start the clock running by calling clock.start() The clock will start a new Thread, that continuously determines the current system time in seconds, and then calls the time(currentTime) method of each registered ClockListener.
  5. The clock can be paused and (re)started by means of the pause and start methods. When restarting a paused clock, the media time, send to the ClockListeners, will resume at the time when the clock was paused.
  6. When the clock is paused, it is possible to perform manual clock steps, where the media time is increased with user specified amounts. The time() calls broadcasted to the clock listeners are executed from the clock Thread.
  7. Before (re)starting, or even while the clock is running, the media time can be set to some desired value, by calling methods like setMediaSeconds(double mediatime). When no value is set, the media time starts off at 0 when the clock is started for the first time.
  8. Usually, the media time progresses at the rate as the system time. The setRate() method can be used to set a rate factor different from 1.0, in order to speed up, slow down, or, in the case of negative value, reverse media time.
  9. The tick size, in milliseconds, specifies the desired delay between two clock ticks. Due to hardware dependencies and OS problems, the actual delay might be much larger, and might be erratic, especially for tick sizes below 16 ms.
  10. When the clock is started with tick size 0, or without specifying the tick size, then the clock runs at "full speed", and the delay between clock ticks will be determined by the workload caused by the ClockListeners.
  11. It is possible to show a "frame rate" counter in the title bar of some Java Frame or JFrame, by calling the setFramerateCounterFrame(frame) method.

Author:
Job Zwiers

Field Summary
private  int clockState
           
private  Thread clockThread
           
private  long currentTimeBaseTime
           
private static int DELAY1
           
private static int DELAY2
           
private static int DELAY3
           
private static int DELAY4
           
private  int framerateCounter
           
private  Frame frameRatecounterFrame
           
private  String framerateCounterText
           
private static int INIT
           
private  ArrayList<ClockListener> listeners
           
private  boolean listenersModified
           
private  long mediaTime
           
private static double MICROSPERSECOND
           
private static double MILLISPERSECOND
           
private static double NANOSPERSECOND
           
private static long NANOSPERSMILLISECOND
           
private  long nanoTickSize
           
private  ArrayList<ClockListener> newListeners
           
private static int PAUSED
           
private  long prevFramerateTime
           
private  double rate
           
private  double refreshDelay
           
static double REFRESHDELAY
           
private static int RUNNING
           
private  Semaphore runSem
           
private static int TERMINATED
           
private static int TESTTICKSIZE
           
 
Constructor Summary
SystemClock()
           
SystemClock(long tickSize)
          Creates a new SystemClock, not yet "ticking", and in the STOPPED state, with mediaTime set to 0.
 
Method Summary
 void addClockListener(ClockListener listener)
          adds "listener" to the list of ClockListeners that receive time(currentTime) callbacks.
 long getMediaNanoseconds()
          Gets this Clock's current media time in nanoseconds.
 double getMediaSeconds()
          Gets this Clock's current media time in seconds.
 double getRate()
          Gets the current temporal scale factor.
 void init()
          Initializes the media time, broadcasts this media time to all clock listeners and puts the clock in the paused state, ready to start
private  void initTime()
           
static void main(String[] arg)
           
 void pause()
          Put the clock in the paused state.
private  void resetFrameRate()
           
 void setFramerateCounterFrame(Frame frame)
          Associate a Frame ( which migh be a JFrame), that will be used to show a framerate counter in the title bar.
 void setFramerateCounterPrefixText(String prefixText)
          sets the framerate counter text, in front of the actual frame rate number.
 void setMediaSeconds(double mt)
          Sets the Clock's media time, specified in second.
 void setRate(double rate)
          Sets the temporal scale factor.
private  void showFrameRate()
           
 void start()
          Start ticking, with the current media time set to the specified time.
private  void startClockThread()
          Creates and starts a Thread that delivers clock ticks, by calling tick() on a regular base.
 void terminate()
          Will stop the clock and will terminate the clock Thread.
private  void time()
           
private  void updateListeners()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

REFRESHDELAY

public static final double REFRESHDELAY
See Also:
Constant Field Values

clockThread

private Thread clockThread

nanoTickSize

private long nanoTickSize

currentTimeBaseTime

private long currentTimeBaseTime

mediaTime

private volatile long mediaTime

rate

private volatile double rate

prevFramerateTime

private long prevFramerateTime

framerateCounter

private int framerateCounter

refreshDelay

private double refreshDelay

framerateCounterText

private String framerateCounterText

frameRatecounterFrame

private Frame frameRatecounterFrame

listenersModified

private volatile boolean listenersModified

listeners

private ArrayList<ClockListener> listeners

newListeners

private ArrayList<ClockListener> newListeners

INIT

private static final int INIT
See Also:
Constant Field Values

RUNNING

private static final int RUNNING
See Also:
Constant Field Values

PAUSED

private static final int PAUSED
See Also:
Constant Field Values

TERMINATED

private static final int TERMINATED
See Also:
Constant Field Values

clockState

private volatile int clockState

runSem

private Semaphore runSem

NANOSPERSMILLISECOND

private static final long NANOSPERSMILLISECOND
See Also:
Constant Field Values

NANOSPERSECOND

private static final double NANOSPERSECOND
See Also:
Constant Field Values

MICROSPERSECOND

private static final double MICROSPERSECOND
See Also:
Constant Field Values

MILLISPERSECOND

private static final double MILLISPERSECOND
See Also:
Constant Field Values

TESTTICKSIZE

private static final int TESTTICKSIZE
See Also:
Constant Field Values

DELAY1

private static final int DELAY1
See Also:
Constant Field Values

DELAY2

private static final int DELAY2
See Also:
Constant Field Values

DELAY3

private static final int DELAY3
See Also:
Constant Field Values

DELAY4

private static final int DELAY4
See Also:
Constant Field Values
Constructor Detail

SystemClock

public SystemClock()

SystemClock

public SystemClock(long tickSize)
Creates a new SystemClock, not yet "ticking", and in the STOPPED state, with mediaTime set to 0.

Method Detail

addClockListener

public void addClockListener(ClockListener listener)
adds "listener" to the list of ClockListeners that receive time(currentTime) callbacks.


getMediaSeconds

public double getMediaSeconds()
Gets this Clock's current media time in seconds. The result is a double, obtained by casting the internal long nanosecond representation.


setMediaSeconds

public void setMediaSeconds(double mt)
Sets the Clock's media time, specified in second. Note that the time is specified as a double; this is converted to a long, representing the time in nanoseconds. When the clock is already RUNNING, the effect is that the clock skips instantly to the new time.


getMediaNanoseconds

public long getMediaNanoseconds()
Gets this Clock's current media time in nanoseconds.


start

public void start()
Start ticking, with the current media time set to the specified time.


pause

public void pause()
Put the clock in the paused state. In this state, the clock Thread is waiting, but not terminated. The clock can resume ticking again by calling the normal start() method. It is allowed to call pause when the clock is not yet running; in that case the clock Thread is already created, but starts waiting.


terminate

public void terminate()
Will stop the clock and will terminate the clock Thread.


init

public void init()
Initializes the media time, broadcasts this media time to all clock listeners and puts the clock in the paused state, ready to start


setRate

public void setRate(double rate)
Sets the temporal scale factor. The clock rate determines how fast the media time changes relative to the underlying time base time. The default clock rate is 1.0. A negative rate is allowed, and results in mediaTime runing "backwards" A zero rate is allowed but, although media time will no longer increase, the clock remains in the RUNNING state. It is allowed to (re)set the clock rate while it is RUNNING already.


getRate

public double getRate()
Gets the current temporal scale factor.


updateListeners

private void updateListeners()

initTime

private void initTime()

time

private void time()

startClockThread

private void startClockThread()
Creates and starts a Thread that delivers clock ticks, by calling tick() on a regular base.


setFramerateCounterFrame

public void setFramerateCounterFrame(Frame frame)
Associate a Frame ( which migh be a JFrame), that will be used to show a framerate counter in the title bar.


setFramerateCounterPrefixText

public void setFramerateCounterPrefixText(String prefixText)
sets the framerate counter text, in front of the actual frame rate number. (By default this is the text "FPS: ")


showFrameRate

private void showFrameRate()

resetFrameRate

private void resetFrameRate()

main

public static void main(String[] arg)