java.lang.Object javax.realtime.AsyncEvent javax.realtime.Timer
A timer is a timed event that measures time according to a given
Clock
.
This class defines basic functionality available to all timers.
Applications will generally use either PeriodicTimer
to create
an event that is fired repeatedly at regular intervals,
or OneShotTimer
for an
event that just fires once at a specific time.
A timer is always associated with at least one Clock
, which provides the basic
facilities of something that ticks along following some time line
(real-time, CPU-time, user-time, simulation-time, etc.).
All timers are created disabled and do nothing until
start()
is called.
NOTE: The pseudo-code does not take into account any issue of
synchronization, it just shows the functionality, and the intended behavior
is obtained with groups of and'ed statements interpreted as atomic.
This is relevant, for example, in cases where the firing of an
AsyncEventHandler
is part of the statements preceding a state
transition. While the firing causes the release of the handler
before the state transition, the execution of the handler does not
take place until after the state transition has completed.
The pseudo-code is a model, it should be interpreted as running continuously, with instructions that take no time.
absolute construction state is {not-active, disabled, absolute} with nextTargetTime = absoluteTime last_rescheduled_with_AbsoluteTime = TRUE [(if PeriodicTimer) period = interval]
relative construction state is {not-active, disabled, relative} with nextDurationTime = relativeTime last_rescheduled_with_AbsoluteTime = FALSE [(if PeriodicTimer) period = interval]
{not-active, disabled, absolute} [(if PeriodicTimer) set fired_or_skipped_in_current_activation = FALSE] enable -> no state change, do nothing disable -> no state change, do nothing stop -> no state change, return FALSE start -> [if last_rescheduled_with_AbsoluteTime then [set targetTime = nextTargetTime [if targetTime < currentTime then set targetTime = currentTime] then go to state {active, enabled, absolute}] else [set countingTime = 0 and set durationTime = nextDurationTime then go to state {active, enabled, relative}]] isRunning -> return FALSE reschedule -> [if using an instance of AbsoluteTime then [reset the nextTargetTime to absoluteTime arg and set last_rescheduled_with_AbsoluteTime = TRUE and no state change] else [reset the nextDurationTime to relativeTime arg and set last_rescheduled_with_AbsoluteTime = FALSE and go to state {not-active, disabled, relative}]] getFireTime -> throws IllegalStateException destroy -> go to state {destroyed} startDisabled -> [if last_rescheduled_with_AbsoluteTime then [set targetTime = nextTargetTime [if targetTime < currentTime then set targetTime = currentTime] then go to state {active, disabled, absolute}] else [set countingTime = 0 and set durationTime = nextDurationTime then go to state {active, disabled, relative}]]
{not-active, disabled, relative} [(if PeriodicTimer) set fired_or_skipped_in_current_activation = FALSE] enable -> no state change, do nothing disable -> no state change, do nothing stop -> no state change, return FALSE start -> [if last_rescheduled_with_AbsoluteTime then [set targetTime = nextTargetTime [if targetTime < currentTime then set targetTime = currentTime] then go to state {active, enabled, absolute}] else [set countingTime = 0 and set durationTime = nextDurationTime then go to state {active, enabled, relative}]] isRunning -> return FALSE reschedule -> [if using an instance of AbsoluteTime then [reset the nextTargetTime to absoluteTime arg and set last_rescheduled_with_AbsoluteTime = TRUE and go to state {not-active, disabled, absolute}] else [reset the nextDurationTime to relativeTime arg and set last_rescheduled_with_AbsoluteTime = FALSE and no state change]] getFireTime -> throws IllegalStateException destroy -> go to state {destroyed} startDisabled -> [if last_rescheduled_with_AbsoluteTime then [set targetTime = nextTargetTime [if targetTime < currentTime then set targetTime = currentTime] then go to state {active, disabled, absolute}] else [set countingTime = 0 and set durationTime = nextDurationTime then go to state {active, disabled, relative}]]
{active, enabled, absolute} [if currentTime >= targetTime then [if PeriodicTimer then [if period > 0 then [fire and set fired_or_skipped_in_current_activation = TRUE and self reschedule via targetTime = (targetTime + period) and re-enter current state] else [fire and go to state {not-active, disabled, absolute}]] else [it is a OneShotTimer so fire and go to state {not-active, disabled, absolute}]]] enable -> no state change, do nothing disable -> go to state {active, disabled, absolute} stop -> [go to state {not-active, disabled, absolute} and return TRUE] start -> throws IllegalStateException isRunning -> return TRUE reschedule -> [if NOT fired_or_skipped_in_current_activation then [if using an instance of AbsoluteTime then [reset the targetTime to absoluteTime arg and re-enter current state] else [reset the durationTime to relativeTime arg and set countingTime = 0 and go to state {active, enabled, relative}]] else [if using an instance of AbsoluteTime then [reset the nextTargetTime to absoluteTime arg and set last_rescheduled_with_AbsoluteTime = TRUE and no state change] else [reset the nextDurationTime to relativeTime arg and set last_rescheduled_with_AbsoluteTime = FALSE and no state change]]] getFireTime -> return targetTime destroy -> go to state {destroyed} startDisabled -> throws IllegalStateException
{active, enabled, relative} [if countingTime >= durationTime then [if PeriodicTimer then [if period > 0 then [fire and set fired_or_skipped_in_current_activation = TRUE and self reschedule via durationTime = (durationTime + period) and re-enter current state] else [fire and go to state {not-active, disabled, relative}]] else [it is a OneShotTimer so fire and go to state {not-active, disabled, relative}]]] enable -> no state change, do nothing disable -> go to state {active, disabled, relative} stop -> [go to state {not-active, disabled, relative} and return TRUE] start -> throws IllegalStateException isRunning -> return TRUE reschedule -> [if NOT fired_or_skipped_in_current_activation then [if using an instance of AbsoluteTime then [reset the targetTime to absoluteTime arg and go to state {active, enabled, absolute}] else [reset the durationTime to relativeTime arg and set countingTime = 0 and re-enter current state]] else [if using an instance of AbsoluteTime then [reset the nextTargetTime to absoluteTime arg and set last_rescheduled_with_AbsoluteTime = TRUE and no state change] else [reset the nextDurationTime to relativeTime arg and set last_rescheduled_with_AbsoluteTime = FALSE and no state change]]] getFireTime -> return (currentTime + durationTime - countingTime) destroy -> go to state {destroyed} startDisabled -> throws IllegalStateException
{active, disabled, absolute} [if currentTime >= targetTime then [if PeriodicTimer then [if period > 0 then [skip and set fired_or_skipped_in_current_activation = TRUE and self reschedule via targetTime = (targetTime + period) and re-enter current state] else [skip and go to state {not-active, disabled, absolute}]] else [it is a OneShotTimer so skip and go to state {not-active, disabled, absolute}]]] enable -> go to state {active, enabled, absolute} disable -> no state change, do nothing stop -> [go to state {not-active, disabled, absolute} and return TRUE] start -> throws IllegalStateException isRunning -> return FALSE reschedule -> [if NOT fired_or_skipped_in_current_activation then [if using an instance of AbsoluteTime then [reset the targetTime to absoluteTime arg and re-enter current state] else [reset the durationTime to relativeTime arg and set countingTime = 0 and go to state {active, disabled, relative}]] else [if using an instance of AbsoluteTime then [reset the nextTargetTime to absoluteTime arg and set last_rescheduled_with_AbsoluteTime = TRUE and no state change] else [reset the nextDurationTime to relativeTime arg and set last_rescheduled_with_AbsoluteTime = FALSE and no state change]]] getFireTime -> return targetTime destroy -> go to state {destroyed} startDisabled -> throws IllegalStateException
{active, disabled, relative} [if countingTime >= durationTime then [if PeriodicTimer then [if period > 0 then [skip and set fired_or_skipped_in_current_activation = TRUE and self reschedule via durationTime = (durationTime + period) and re-enter current state] else [skip and go to state {not-active, disabled, relative}]] else [it is a OneShotTimer so skip and go to state {not-active, disabled, relative}]]] enable -> go to state {active, enabled, relative} disable -> no state change, do nothing stop -> [go to state {not-active, disabled, relative} and return TRUE] start -> throws IllegalStateException isRunning -> return FALSE reschedule -> [if NOT fired_or_skipped_in_current_activation then [if using an instance of AbsoluteTime then [reset the targetTime to absoluteTime arg and go to state {active, disabled, absolute}] else [reset the durationTime to relativeTime arg and set countingTime = 0 and re-enter current state]] else [if using an instance of AbsoluteTime then [reset the nextTargetTime to absoluteTime arg and set last_rescheduled_with_AbsoluteTime = TRUE and no state change] else [reset the nextDurationTime to relativeTime arg and set last_rescheduled_with_AbsoluteTime = FALSE and no state change]]] getFireTime -> return (currentTime + durationTime - countingTime) destroy -> go to state {destroyed} startDisabled -> throws IllegalStateException
{destroyed} enable | disable | stop | start | isRunning | reschedule | getFireTime | destroy | startDisabled -> throws IllegalStateException
The following two methods, without loss of generality and to avoid clutter, have been omitted from the above Pseudo-code.
Every state but {destroyed} has: [(if PeriodicTimer) setInterval -> reset period = interval] [(if PeriodicTimer) getInterval -> return period]
The state {destroyed} has: [(if PeriodicTimer) setInterval -> throws IllegalStateException] [(if PeriodicTimer) getInterval -> throws IllegalStateException]
Constructor Summary | |
protected |
Timer(HighResolutionTime time,
Clock clock,
AsyncEventHandler handler)
Create a timer that fires according to the given time ,
based on the Clock clock and is
handled by the specified AsyncEventHandler handler . |
Method Summary | |
void |
addHandler(AsyncEventHandler handler)
Add a handler to the set of handlers associated with this event. |
void |
bindTo(java.lang.String happening)
Should not be called. |
ReleaseParameters |
createReleaseParameters()
Create a ReleaseParameters object appropriate to the
timing characteristics of this event.
|
void |
destroy()
Stop this from counting or comparing
if active, remove from it all the
associated handlers if any, and release as many of its
resources as possible back to the system.
|
void |
disable()
Disable this timer, preventing it from firing. |
void |
enable()
Re-enable this timer after it has been disabled. |
void |
fire()
Should not be called. |
Clock |
getClock()
Return the instance of Clock on which this timer is based. |
AbsoluteTime |
getFireTime()
Get the time at which this Timer is expected to fire.
|
AbsoluteTime |
getFireTime(AbsoluteTime fireTime)
Get the time at which this Timer is expected to fire.
|
boolean |
handledBy(AsyncEventHandler handler)
Test to see if the handler given as the parameter is associated with this . |
boolean |
isRunning()
Tests this to determine if this is active and is
enabled such that when the given time occurs it will
fire the event. |
void |
removeHandler(AsyncEventHandler handler)
Remove a handler from the set associated with this event. |
void |
reschedule(HighResolutionTime time)
Change the scheduled time for this event. |
void |
setHandler(AsyncEventHandler handler)
Associate a new handler with this event and remove all existing handlers. |
void |
start()
Start this timer. |
void |
start(boolean disabled)
Start this timer. |
boolean |
stop()
Stops a timer if it is active and changes its state to not-active and disabled. |
Methods inherited from class javax.realtime.AsyncEvent |
unbindTo |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Constructor Detail |
protected Timer(HighResolutionTime time, Clock clock, AsyncEventHandler handler)
time
,
based on the Clock
clock
and is
handled by the specified AsyncEventHandler
handler
.
time
- The time used to determine when to fire the event.
A time
value of null
is equivalent to a
RelativeTime
of 0, and in this case
the Timer
fires
immediately upon a call to start()
.clock
- The clock on which to base this timer, overriding
the clock associated with the parameter time
.
If null
, the system Realtime clock
is used.
The clock associated with the parameter time
is always
ignored.handler
- The default handler
to use for this event.
If null
, no handler
is associated with the
timer and nothing will happen when this event fires unless a
handler
is subsequently associated with the timer
using the addHandler()
or setHandler()
method.
java.lang.IllegalArgumentException
- Thrown if time
is a
negative RelativeTime
value.
java.lang.UnsupportedOperationException
- Thrown if the timer
functionality cannot be supported using
the given clock
.Method Detail |
public ReleaseParameters createReleaseParameters()
ReleaseParameters
object appropriate to the
timing characteristics of this event.
The default is the most pessimistic: AperiodicParameters
.
This is typically called by code that is setting up a
handler
for
this event that will fill in the parts of the release parameters
for which it has values, e.g. cost.
createReleaseParameters
in class AsyncEvent
ReleaseParameters
object.
java.lang.IllegalStateException
- Thrown if this Timer
has been
destroyed.public void disable()
RelativeTime
for its time parameter continues
to count while it is disabled, and no changes take place in
a disabled timer created using an instance of
AbsoluteTime
, in both cases the potential firing is
simply masked, or skipped.
If the timer is subsequently re-enabled
before its fire time and it is
enabled when its fire time occurs, then it will fire.
It is important to note that this method does not delay
the time before a possible firing.
For example, if the timer is set to fire at time
42 and the disable()
is called at time 30 and
enable()
is called at time 40 the firing will occur
at time 42 (not time 52). These semantics imply
also that firings are not queued. Using the above example,
if enable was called at time 43 no firing will occur,
since at time 42 this
was disabled.
If the Timer
is already disabled,
whether it is active or not-active,
this method does nothing.
java.lang.IllegalStateException
- Thrown if this Timer
has been destroyed.public void enable()
disable()
.)
If the Timer
is already enabled,
this method does nothing.
If the Timer
is not-active,
this method does nothing.
java.lang.IllegalStateException
- Thrown if this Timer
has been destroyed.public void destroy()
this
from counting or comparing
if active, remove from it all the
associated handlers if any, and release as many of its
resources as possible back to the system.
Every method invoked on a Timer
that has been destroyed
will throw IllegalStateException
.
java.lang.IllegalStateException
- Thrown if this Timer
has been
destroyed.public Clock getClock()
Clock
on which this timer is based.
Clock
associated with this
Timer
.
java.lang.IllegalStateException
- Thrown if this Timer
has been destroyed.public AbsoluteTime getFireTime()
Timer
is expected to fire.
If the Timer
is disabled, the returned
time is that of the skipping of the firing.
If the Timer
is not-active it throws
IllegalStateException
.
this
is expected to
fire or to skip, in a newly allocated AbsoluteTime
object.
If the timer has been created or re-scheduled
(see reschedule(HighResolutionTime time)
)
using an instance of
RelativeTime
for its time parameter then it will return
the sum of the current time and the RelativeTime
remaining time before the timer is expected to fire/skip.
The clock association of the returned time is the clock
on which this
timer is based.
java.lang.ArithmeticException
- Thrown if the result does not fit
in the normalized format.
java.lang.IllegalStateException
- Thrown if this Timer
has been destroyed, or if it is not-active.public AbsoluteTime getFireTime(AbsoluteTime fireTime)
Timer
is expected to fire.
If the Timer
is disabled, the returned
time is that of the skipping of the firing.
If the Timer
is not-active it throws
IllegalStateException
.
fireTime
- The instance of AbsoluteTime
which will be updated in place and returned.
The clock association of the fireTime
parameter
is ignored.
When fireTime
is null
a new object
is allocated for the result.
AbsoluteTime
passed as parameter, with time values representing
the absolute time at which this
is expected to
fire or to skip.
If the fireTime
parameter is null
the result is returned in a newly allocated object.
If the timer has been created or re-scheduled
(see reschedule(HighResolutionTime time)
)
using an instance of
RelativeTime
for its time parameter then it will return
the sum of the current time and the RelativeTime
remaining time before the timer is expected to fire/skip.
The clock association of the returned time is the clock
on which this
timer is based.
java.lang.ArithmeticException
- Thrown if the result does not fit
in the normalized format.
java.lang.IllegalStateException
- Thrown if this Timer
has been destroyed, or if it is not-active.public boolean isRunning()
this
is active and is
enabled such that when the given time occurs it will
fire the event. Given the Timer
current state it answer
the question "Is firing expected?".
true
if the timer is active and
enabled;
false
, if the timer has either not been started,
it has been started but it is disabled,
or it has been started and is now stopped.
java.lang.IllegalStateException
- Thrown if this Timer
has been destroyed.public void reschedule(HighResolutionTime time)
AbsoluteTime
or a RelativeTime
for its argument, and the
Timer
will behave as if created using that type
for its time
parameter.
The rescheduling will take place between the invocation and
the return of the method.
NOTE: While the scheduled time is changed as described above,
the rescheduling itself is applied only on the first firing
(or on the first skipping if disabled) of a timer's
activation. If reschedule
is invoked after the
current activation timer's firing, then the rescheduled
time
will be effective only upon the next
start
or startDisabled
command
(which may need to be preceded by a stop
command).
If reschedule
is invoked with a
RelativeTime
time
on an
active timer before its first firing/skipping, then
the rescheduled firing/skipping time
is
relative to the time of invocation.
time
- The time to reschedule for this event firing.
If time
is null
, the previous
time is still the time used for the Timer
firing.
The clock associated with the parameter time
is always
ignored.
java.lang.IllegalArgumentException
- Thrown if time
is a
negative RelativeTime
value.
java.lang.IllegalStateException
- Thrown if this Timer
has been
destroyed.public void start()
java.lang.IllegalStateException
- Thrown if this Timer
has been destroyed,
or if this timer is already active.public void start(boolean disabled)
disabled
is true
start the
timer making it active in a disabled state.
If disabled
is false
this method behaves
like the start()
method.
disabled
- If true
, the timer will be
active but disabled after it is started.
If false
this method behaves
like the start()
method.
java.lang.IllegalStateException
- Thrown if this Timer
has been destroyed,
or if this timer is already active.public boolean stop()
true
if this
was
active and false
otherwise.
java.lang.IllegalStateException
- Thrown if this Timer
has been destroyed.public void fire()
fire
in class AsyncEvent
java.lang.UnsupportedOperationException
- Thrown if fire
is called from outside the Timer
implementation.UnsupportedOperationException
instead of doing unspecified damage.public void bindTo(java.lang.String happening)
bindTo
in class AsyncEvent
happening
- An implementation dependent value that binds
this instance of AsyncEvent
to a happening.
java.lang.UnsupportedOperationException
- Thrown if bindTo
is called on a Timer
.public void addHandler(AsyncEventHandler handler)
AsyncEvent
AsyncEvent
may have more than one associated handler. However, adding a handler
to an event has no effect if the handler is already attached to the event.
The execution of this method is atomic with respect
to the execution of the fire()
method.
Since this affects the constraints expressed in the release parameters of an existing schedulable object, this may change the feasibility of the current system. This method does not change feasibility set of any scheduler, and no feasibility test is performed.
Note, there is an implicit reference to the handler stored in this
.
The assignment must be valid under any applicable memory assignment rules.
addHandler
in class AsyncEvent
handler
- The new handler to add to the list of handlers already
associated with this.
If the handler
is already associated with
the event, the call has no effect.
java.lang.IllegalStateException
- Thrown if this Timer
has been
destroyed.public boolean handledBy(AsyncEventHandler handler)
AsyncEvent
this
.
handledBy
in class AsyncEvent
handler
- The handler to be tested to determine if it is
associated with this
.
this
.
False if handler
is null or the parameters is not associated with this
.
java.lang.IllegalStateException
- Thrown if this Timer
has been
destroyed.public void removeHandler(AsyncEventHandler handler)
AsyncEvent
fire()
method.
A removed handler continues to execute until its fireCount becomes zero and it completes.
Since this affects the constraints expressed in the release parameters of an existing schedulable object, this may change the feasibility of the current system. This method does not change the feasibility set of any scheduler, and no feasibility test is performed.
removeHandler
in class AsyncEvent
handler
- The handler to be disassociated from this
.
If null nothing happens. If the handler
is not already
associated with this
then nothing happens.
java.lang.IllegalStateException
- Thrown if this Timer
has been
destroyed.public void setHandler(AsyncEventHandler handler)
AsyncEvent
fire()
method.
Since this affects the constraints expressed in the release parameters of the existing schedulable objects, this may change the feasibility of the current system. This method does not change the feasibility set of any scheduler, and no feasibility test is performed.
setHandler
in class AsyncEvent
handler
- The new instance of AsyncEventHandler
to be associated with this
.
If handler
is null then no handler will be associated with this
(i.e., remove all handlers).
java.lang.IllegalStateException
- Thrown if this Timer
has been
destroyed.