package org.ovirt.engine.ui.uicommonweb.models;
import org.ovirt.engine.ui.uicommonweb.Configurator;
import org.ovirt.engine.ui.uicommonweb.TypeResolver;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.user.client.Timer;
public abstract class GridTimer extends Timer implements HasValueChangeHandlers<String> {
private enum RATE {
FAST {
@Override
int getInterval() {
return 2000;
}
@Override
int getRepetitions() {
return 3;
}
@Override
public String toString() {
return "Fast";
}
},
MEDIUM {
@Override
int getInterval() {
return 4000;
}
@Override
int getRepetitions() {
return 30;
}
@Override
public String toString() {
return "Medium";
}
},
NORMAL {
@Override
int getInterval() {
return -1;
}
@Override
int getRepetitions() {
// this interval is set dynamically
return -1;
}
@Override
public String toString() {
return "Normal";
}
},
SLOW {
@Override
int getInterval() {
return 8000;
}
@Override
int getRepetitions() {
return 3;
}
@Override
public String toString() {
return "Slow";
}
};
abstract int getInterval();
abstract int getRepetitions();
}
public static final int DEFAULT_NORMAL_RATE = ((Configurator) TypeResolver.getInstance()
.Resolve(Configurator.class)).getPollingTimerInterval();
private int currentRate = 0;
private SimpleEventBus eventBus;
private final String name;
private boolean active;
private boolean paused;
private int normalInterval = DEFAULT_NORMAL_RATE;
private RATE[] rateCycle = { RATE.NORMAL, RATE.FAST, RATE.MEDIUM, RATE.SLOW };
private int repetitions;
public GridTimer(String name) {
this.name = name;
eventBus = new SimpleEventBus();
}
@Override
public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) {
return eventBus.addHandler(ValueChangeEvent.getType(), handler);
}
/**
* This method will be called when a timer fires. Override it to implement the timer's logic.
*/
public abstract void execute();
/**
* Speed Up the search interval for a limited number of repetitions.
*/
public void fastForward() {
GWT.log("GridTimer[" + name + "].fastForward()");
if (isFastForwarding()) {
// there is already a fast forward running - reset to normal and start over
reset();
}
cycleRate();
}
@Override
public void fireEvent(GwtEvent<?> event) {
eventBus.fireEvent(event);
}
/**
* get the refresh rate in seconds
*/
public int getRefreshRate() {
RATE rate = rateCycle[currentRate];
return rate == RATE.NORMAL ? normalInterval : rate.getInterval();
}
public boolean isFastForwarding() {
return rateCycle[currentRate] != RATE.NORMAL;
}
@Override
public final void run() {
GWT.log("GridTimer[" + name + "].run() called");
if (repetitions > 0) {
repetitions--;
} else if (repetitions == 0) {
cycleRate();
}
GWT.log("GridTimer[" + name + "] Executing! Current Rate: " + rateCycle[currentRate] + ":" + getRefreshRate()
+ " Reps: "
+ repetitions);
execute();
}
/**
* Set the refresh rate. Stops a fast-forward
*
* @param interval
* in seconds
*/
public void setRefreshRate(int interval) {
if (getRefreshRate() == interval) {
return;
}
reset();
GWT.log("GridTimer[" + name + "]: Refresh Rate set to: " + interval);
// set the NORMAL interval
normalInterval = interval;
start();
}
public void start() {
GWT.log("GridTimer[" + name + "].start()");
active = true;
scheduleRepeating(getRefreshRate());
ValueChangeEvent.fire(this, getValue());
}
public void stop() {
GWT.log("GridTimer[" + name + "].stop()");
active = false;
doStop();
}
public void pause() {
GWT.log("GridTimer[" + name + "].pause()");
if (active) {
paused = true;
doStop();
}
}
public void resume() {
GWT.log("GridTimer[" + name + "].resume()");
if (active) {
paused = false;
start();
}
}
public boolean isPaused() {
return paused;
}
public boolean isActive() {
return active;
}
private String getValue() {
return (isActive() ? "Refresh Status: Active(" : "Inactive(") + (isPaused() ? "paused)" : "running)") + ":"
+ " Rate: " + rateCycle[currentRate] + "(" + getRefreshRate() / 1000 + " sec)";
}
private void doStop() {
reset();
cancel();
ValueChangeEvent.fire(this, getValue());
}
private void cycleRate() {
currentRate = (currentRate + 1) % rateCycle.length;
RATE rate = rateCycle[currentRate];
repetitions = rate.getRepetitions();
GWT.log("GridTimer[" + name + "] Rate Cycled: Current Rate: " + rate + " Reps: " + repetitions + " Interval: "
+ rate.getInterval());
start();
}
private void reset() {
// reset rate to NORMAL
currentRate = 0;
repetitions = RATE.NORMAL.getRepetitions();
}
}