001 package javax.realtime; 002 003 /** A <code>Timer</code> is a timed event that measures time 004 * relative to a given <code>Clock</code>. This class defines 005 * basic functionality available to all timers. Applications 006 * will generally use either <code>PeriodicTimer</code> to 007 * create an event that is fired repeatedly at regular intervals, 008 * of <code>OneShotTimer</code>, which provides the basic 009 * facilities of something that ticks along following some 010 * time line (real-time, cpu-time, user-time, simulation-time, 011 * etc.). All timers are created disabled and do nothing 012 * until <code>start()</code> is called. 013 */ 014 public abstract class Timer extends AsyncEvent { 015 016 protected boolean enabled = true; 017 protected boolean started = false; 018 protected Clock defaultClock; 019 protected RelativeTime fireAfter; 020 protected AsyncEventHandler handler; 021 protected RelativeTime timePassed = new RelativeTime(0, 0); 022 protected AbsoluteTime lastUpdated = new AbsoluteTime(); 023 024 /** Create a timer that fires at the given time based on the given 025 * instance of <code>Clock</code> and is handled by the specified 026 * handler. 027 * 028 * @param t The time to fire the event. Will be converted to 029 * absolute time. 030 * @param clock The clock on which to base this time. If null, the 031 * system realtime clock is used. 032 * @param handler The default handler to use for this event. If null, no 033 * handler is associated with it and nothing will happen 034 * when this event fires until a handler is provided. 035 */ 036 protected Timer(HighResolutionTime t, Clock c, 037 AsyncEventHandler handler) { 038 if (t instanceof AbsoluteTime) 039 fireAfter = new RelativeTime(((RelativeTime)t).getMilliseconds() - 040 c.getTime().getMilliseconds(), 041 ((RelativeTime)t).getNanoseconds() - 042 c.getTime().getNanoseconds()); 043 else fireAfter = (RelativeTime)t; 044 045 defaultClock = c; 046 this.handler = handler; 047 enabled = false; 048 } 049 050 /** Create a <code>ReleaseParameters</code> block appropriate to the 051 * timing characteristics of this event. The default is the most 052 * pessimistic: <code>AperiodicParameters</code>. This is typically 053 * called by code that is setting up a handler for this event that 054 * will fill in the parts of the release parameters for which it has 055 * values, e.g, cost. 056 * 057 * @return A new <code>ReleaseParameters</code> object. 058 */ 059 public ReleaseParameters createReleaseParameters() { 060 return new AperiodicParameters(null, fireAfter, handler, null); 061 } 062 063 /** Destroy the timer and return all possible resources to the system. */ 064 public void destroy() { 065 defaultClock = null; 066 fireAfter = null; 067 handler = null; 068 enabled = false; 069 } 070 071 /** Disable this timer, preventing it from firing. It may subsequently 072 * be re-enabled. If the timer is disabled when its fire time occurs 073 * then it will not fire. However, a disabled timer continues to 074 * count while it is disabled and if it is subsequently reabled 075 * before its fire time occures and is enabled when its fire time 076 * occurs, it will fire. 077 */ 078 public void disable() { 079 enabled = false; 080 } 081 082 /** Re-enable this timer after it has been disabled. */ 083 public void enable() { 084 enabled = true; 085 } 086 087 /** Gets the instance of <code>Clock</code> that this timer is based on. 088 * 089 * @return The instance of <code>Clock</code>. 090 */ 091 public Clock getClock() { 092 return defaultClock; 093 } 094 095 /** Get the time at which this event will fire. 096 * 097 * @return An instance of <code>AbsoluteTime</code> object representing 098 * the absolute time at which this will fire. 099 */ 100 public AbsoluteTime getFireTime() { 101 return new AbsoluteTime(fireAfter.getMilliseconds() - 102 defaultClock.getTime().getMilliseconds() + 103 Clock.getRealtimeClock().getTime().getMilliseconds(), 104 fireAfter.getNanoseconds() - 105 defaultClock.getTime().getNanoseconds() + 106 Clock.getRealtimeClock().getTime().getNanoseconds()); 107 } 108 109 /** Tests this to determine if this has been started and is in a 110 * state (enabled) such that when the given time occurs it will 111 * fire the event. 112 * 113 * @return True if the timer has been started and is in the enabled 114 * state. False, if the timer has either not been started, 115 * started and is in the disabled state, or started and stopped. 116 */ 117 public boolean isRunning() { 118 return (started && enabled); 119 } 120 121 /** Change the schedule time for this event; can take either absolute 122 * or relative times. 123 * 124 * @param time The time to reschedule for this event firing. If null, the 125 * previous fire time is still the time at which this will fire. 126 */ 127 public void reschedule(HighResolutionTime time) { 128 if (time instanceof AbsoluteTime) 129 fireAfter.set(time.getMilliseconds() - defaultClock.getTime().getMilliseconds(), 130 time.getNanoseconds() - defaultClock.getTime().getNanoseconds()); 131 else fireAfter = (RelativeTime)time; 132 } 133 134 /** Starts this time. A <code>Timer</code> starts measuring time from 135 * when it is started. 136 */ 137 public void start() { 138 started = true; 139 Clock.getRealtimeClock().getTime(lastUpdated); 140 while (started) { 141 AbsoluteTime temp = new AbsoluteTime(); 142 Clock.getRealtimeClock().getTime(temp); 143 RelativeTime difference = temp.subtract(lastUpdated); 144 timePassed = timePassed.add(difference); 145 lastUpdated = temp; 146 } 147 } 148 149 /** Stops a timer that is running and changes its state to 150 * <i>not started</i>. 151 * 152 * @return True, if this was <b>started and enabled</b> and stops this. 153 * False, if this was not <b>started or disabled</b>. 154 */ 155 public boolean stop() { 156 boolean wasStarted = started && enabled; 157 started = false; 158 return wasStarted; 159 } 160 }