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; } }