package edu.hawaii.ics.yucheng;
import java.util.ArrayList;
/**
* An abstract class that solves graphs.
*/
abstract class GraphSolver {
/**
* Sleeps for a number of milliseconds.
*
* @param milliseconds The number of milliseconds to sleep.
*/
private static void sleep(final long milliseconds) {
try {
Thread.sleep(milliseconds);
} catch (final Exception e) {
// Swallow exceptions here.
System.err.println(e);
}
}
private long myBroadcast = Long.MIN_VALUE;
private final ArrayList<GraphListener> myListeners = new ArrayList<GraphListener>();
private long mySleepTime = 0;
private long myTimeout = 0;
/**
* Adds a listener for progress messages.
*
* @param listener The listener.
*/
public void addGraphListener(final GraphListener listener) {
if (listener == null)
throw new NullPointerException("listener");
myListeners.add(listener);
}
/**
* Returns true if the solver is animating.
*
* @return True indicates the solver is animating and false otherwise.
*/
public boolean isAnimating() {
return myTimeout > 0;
}
/**
* Publishes progress to all added listeners.
*
* @param solution The solution.
*/
protected void publish(final GraphSolution solution) {
if (!isAnimating())
return;
// Don't send too many messages.
final long now = System.currentTimeMillis();
if (now < myBroadcast + myTimeout)
return;
myBroadcast = now;
// Send messages to each listener.
for (final GraphListener listener : myListeners)
listener.progress(solution);
// Sleep if animating.
sleep(mySleepTime);
}
/**
* Removes a progress listener.
*
* @param listener The listener.
*/
public void removeGraphListener(final GraphListener listener) {
if (listener == null)
throw new NullPointerException("listener");
if (myListeners.contains(listener))
myListeners.remove(listener);
}
/**
* Solves a graph or returns null if there is no solution.
*
* @param g The graph.
*
* @return The solution.
*/
public abstract GraphSolution solve(Graph g);
/**
* Starts animation.
*
* @param timeout The amount of time to delay before transmitting progress.
*/
public void startAnimation(final long timeout) {
startAnimation(timeout, timeout);
}
/**
* Starts animation.
*
* @param timeout The amount of time to delay before transmitting progress.
*
* @param sleepTime The amount of time to sleep after transmitting progress.
*/
public void startAnimation(final long timeout, final long sleepTime) {
if (timeout < 0)
throw new IllegalArgumentException("timeout");
if (sleepTime < 0)
throw new IllegalArgumentException("sleepTime");
myTimeout = timeout;
mySleepTime = sleepTime;
}
/**
* Stops animation.
*/
public void stopAnimation() {
myTimeout = 0;
mySleepTime = 0;
}
}