package org.yakindu.scr;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Default timer service implementation.
*
*/
public class TimerService implements ITimer {
private final Timer timer = new Timer();
private final List<TimeEventTask> timerTaskList = new ArrayList<TimeEventTask>();
private final Lock lock = new ReentrantLock();
/**
* Timer task that reflects a time event. It's internally used by
* {@link TimerService}.
*
*/
private class TimeEventTask extends TimerTask {
private ITimerCallback callback;
int eventID;
/**
* Constructor for a time event.
*
* @param callback
* : Object that implements ITimerCallback, is called
* when the timer expires.
*
* @param eventID
* : Index position within the state machine's timeEvent
* array.
*/
public TimeEventTask(ITimerCallback callback, int eventID) {
this.callback = callback;
this.eventID = eventID;
}
public void run() {
callback.timeElapsed(eventID);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof TimeEventTask) {
return ((TimeEventTask) obj).callback.equals(callback)
&& ((TimeEventTask) obj).eventID == eventID;
}
return super.equals(obj);
}
@Override
public int hashCode() {
int prime = 37;
int result = 1;
int c = (int) this.eventID;
result = prime * result + c;
c = this.callback.hashCode();
result = prime * result + c;
return result;
}
}
public void setTimer(final ITimerCallback callback, final int eventID,
long time, boolean isPeriodic) {
// Create a new TimerTask for given event and store it.
TimeEventTask timerTask = new TimeEventTask(callback, eventID);
lock.lock();
timerTaskList.add(timerTask);
// start scheduling the timer
if (isPeriodic) {
timer.scheduleAtFixedRate(timerTask, time, time);
} else {
timer.schedule(timerTask, time);
}
lock.unlock();
}
public void unsetTimer(ITimerCallback callback, int eventID) {
lock.lock();
int index = timerTaskList.indexOf(new TimeEventTask(callback, eventID));
if (index != -1) {
timerTaskList.get(index).cancel();
timer.purge();
timerTaskList.remove(index);
}
lock.unlock();
}
/**
* Cancel timer service. Use this to end possible timing threads and free
* memory resources.
*/
public void cancel() {
lock.lock();
timer.cancel();
timer.purge();
lock.unlock();
}
}